今天折腾了一天就学了个滚动条,没有想到挺麻烦的........虽然老师说以后用控件,现在做真够费劲的!
为窗口添加滚动条
为窗口添加滚动条非常的简单,只需在创建窗口时指定窗口的样式中加上WS_VSCROLL或WS_HSCROLL或是两者皆有即可。
设置选项
通过SetScrollInfo函数来设置滚动条
使滚动条大小适应窗口变化变化
在WM_ONSIZE消息处理中动态改变滚动条大小
滚动
在ON_VSCROLL消息处理函数中使滚动条进行滚动,并激活窗口重绘
贴个自己写的程序,以后忘了再回来看看...
编写程序,在窗口中显示部分的鼠标与键盘消息列表,一行显示一个消息...
messageshow.h 文件
class CMessageShowApp:public CWinApp
{
public:
virtual BOOL InitInstance();
};
class CMessageShowWindow:public CFrameWnd
{
public:
CMessageShowWindow();
protected:
afx_msg void OnPaint();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnChar(UINT nChar,UINT nRepCnt,UINT nFlags);
afx_msg void OnSize(UINT nType,int cx,int cy);
afx_msg void OnVScroll(UINT nSBCode,UINT nPosl,CScrollBar *pScorllBar);
afx_msg void OnLButtonDown(UINT nFlags,CPoint point);
afx_msg void OnLButtonUp(UINT nFlags,CPoint point);
afx_msg void OnLButtonDblClk(UINT nFlg,CPoint point);
afx_msg BOOL OnMouseWheel(UINT nFlags,short zDelta,CPoint pt);
DECLARE_MESSAGE_MAP()
};
messaeshow.cpp 文件
#include<afxwin.h>
#include"messageshow.h"
#include<afxcoll.h>
CMessageShowApp theApp;
SCROLLINFO si;
UINT g_nLines;
UINT g_nLineHeight;
CStringList g_csList;
BOOL CMessageShowApp::InitInstance()
{
m_pMainWnd = new CMessageShowWindow;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();
return TRUE;
}
CMessageShowWindow::CMessageShowWindow()
{
Create(NULL,_T("Message show"),WS_OVERLAPPEDWINDOW|WS_VSCROLL);
}
BEGIN_MESSAGE_MAP(CMessageShowWindow,CFrameWnd)
ON_WM_PAINT()
ON_WM_CREATE()
ON_WM_CHAR()
ON_WM_SIZE()
ON_WM_VSCROLL()
ON_WM_LBUTTONDOWN()
ON_WM_LBUTTONUP()
ON_WM_LBUTTONDBLCLK()
ON_WM_MOUSEWHEEL()
END_MESSAGE_MAP()
int CMessageShowWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
TEXTMETRIC tm;
GetTextMetrics(GetDC()->m_hDC,&tm); // 获得文本信息
g_nLineHeight = tm.tmHeight + tm.tmExternalLeading; // 文本高度
GetScrollInfo(SB_VERT,&si);
si.cbSize = sizeof(SCROLLINFO);
si.nMin = 1;
si.nMax = 100;
si.nPage = -1; //我把它赋值为 -1 ,开始没有那么多内容不显示 滚动条
SetScrollInfo(SB_VERT,&si);
return 0;
}
void CMessageShowWindow::OnPaint()
{
CPaintDC dc(this);
// 链表不能随机取数 ,只好用个迭代器
POSITION pos = g_csList.GetHeadPosition();
int count = g_csList.GetCount();
if(count<=g_nLines)
{
for(int i = 0;i<count;i++)
{
dc.DrawText(g_csList.GetNext(pos),-1,
&CRect(30,i*g_nLineHeight,500,(i+1)*g_nLineHeight),DT_LEFT|DT_VCENTER);
}
} else {
int npos = si.nPos;
while(npos>1) { g_csList.GetNext(pos);npos--;} //npos 必须大于 1
for(int i = 0;i<si.nPage;i++)
{
dc.DrawText(g_csList.GetNext(pos),-1,
&CRect(30,i*g_nLineHeight,500,(i+1)*g_nLineHeight),DT_LEFT|DT_VCENTER);
}
}
}
void CMessageShowWindow::OnChar(UINT nChar,UINT nRepCnt,UINT nFlags)
{
CString str;
str.Format(" WM_CHAR %c : %u",TCHAR(nChar),nChar);
g_csList.AddTail(str);
if(g_csList.GetCount()>g_nLines)
{
// 把滚动条的位置同时向下移动 一个 单位
si.nPos = g_csList.GetCount() - g_nLines+1;
si.nPage = g_nLines;
si.nMax = g_csList.GetCount();
SetScrollInfo(SB_VERT,&si);
}
Invalidate();
}
void CMessageShowWindow::OnSize(UINT nType,int cx,int cy)
{
CRect rect;
GetClientRect(&rect);
//客户区所能显示的文本行数
g_nLines = rect.Height()/g_nLineHeight;
// 如果 g_csList 消息行数 > 客户区能够显示的 消息行数 ,那么 nPage 设置行数,同时设置 nMax 为 消息总数
si.nPage = g_csList.GetCount()>g_nLines?g_nLines:-1;
si.nMax = g_csList.GetCount()>g_nLines?g_csList.GetCount():100;
// 在客户区 纵向 变大的时候 ,有可能 在 nPos 后面 的消息 总数 少于 刚刚设置的
// nPage ,这是个错误,检查并纠正................
if(si.nPage>g_csList.GetCount() - si.nPos)
si.nPos = si.nPage - (g_csList.GetCount() - si.nPos);
SetScrollInfo(SB_VERT,&si);
}
void CMessageShowWindow::OnVScroll(UINT nSBCode,UINT nPos,CScrollBar *pScrollBar)
{
switch(nSBCode)
{
case SB_LINEDOWN:
si.nPos++;
break;
case SB_LINEUP:
si.nPos--;
break;
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
case SB_PAGEUP:
si.nPos += si.nPage;
break;
case SB_THUMBTRACK:
si.nPos = nPos;
break;
case SB_THUMBPOSITION:
si.nPos = nPos;
break;
}
SetScrollInfo(SB_VERT,&si);
Invalidate();
}
void CMessageShowWindow::OnLButtonDown(UINT nFalgs,CPoint point)
{
CString str;
str.Format(" WM_LBUTTONDOWN %ld : %ld",point.x,point.y);
g_csList.AddTail(str);
if(g_csList.GetCount()>g_nLines)
{
si.nPos = g_csList.GetCount() - g_nLines+1;
si.nPage = g_nLines;
si.nMax = g_csList.GetCount();
SetScrollInfo(SB_VERT,&si);
}
Invalidate();
}
void CMessageShowWindow::OnLButtonUp(UINT nFlags,CPoint point)
{
CString str;
str.Format(" WM_LBUTTONUP %ld : %ld",point.x,point.y);
g_csList.AddTail(str);
if(g_csList.GetCount()>g_nLines)
{
si.nPos = g_csList.GetCount() - g_nLines+1;
si.nPage = g_nLines;
si.nMax = g_csList.GetCount();
SetScrollInfo(SB_VERT,&si);
}
Invalidate();
}
void CMessageShowWindow::OnLButtonDblClk(UINT nFlag,CPoint point)
{
CString str;
str.Format(" WM_LBUTTONDBLCLK %ld : %ld",point.x,point.y);
g_csList.AddTail(str);
if(g_csList.GetCount()>g_nLines)
{
si.nPos = g_csList.GetCount() - g_nLines+1;
si.nPage = g_nLines;
si.nMax = g_csList.GetCount();
SetScrollInfo(SB_VERT,&si);
}
Invalidate();
}
BOOL CMessageShowWindow::OnMouseWheel(UINT nFlags,short zDelta,CPoint pt)
{
CString str;
str.Format(" WM_MOUSEWHEEL %ld : %ld %d",pt.x,pt.y,zDelta);
g_csList.AddTail(str);
if(g_csList.GetCount()>g_nLines)
{
si.nPos = g_csList.GetCount() - g_nLines+1;
si.nPage = g_nLines;
si.nMax = g_csList.GetCount();
SetScrollInfo(SB_VERT,&si);
}
Invalidate();
return TRUE;
}