1.在OnInitDialog中加入初始化垂直和水平滚动条的属性:
SCROLLINFO vinfo;
vinfo.cbSize = sizeof(vinfo);
vinfo.fMask = SIF_ALL;
vinfo.nPage = 50;
vinfo.nMax = 600;
vinfo.nMin = 0;
vinfo.nPos = 0;
SetScrollInfo(SB_HORZ, &vinfo);
SetScrollInfo(SB_VERT, &vinfo);
之后在对话框类的定义中自定义五个变量:
POINT Old;
long lastVscroll;
long curVscroll;
long lastHscroll;
long curHscroll;
2.重载两个消息:WM_HSCROLL和WM_VSCROLL
void CjupiaoDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
int iMin(0), iMax(0), iVisibleCol(0), iVertPos(0);
SCROLLINFO m_hScrollInfo;
GetScrollInfo(SB_HORZ, &m_hScrollInfo, SIF_ALL);
iVertPos = m_hScrollInfo.nPos; //滚动条未滑动前的位置
iMin = m_hScrollInfo.nMin;
iMax = m_hScrollInfo.nMax;
iVisibleCol = m_hScrollInfo.nPage;
lastHscroll = iVertPos;
switch (nSBCode)
{
case SB_THUMBTRACK://当用户直接拖动滑动条时会触发这个
m_hScrollInfo.nPos = nPos;
break;
case SB_LEFT:
m_hScrollInfo.nPos = iMin;
break;
case SB_RIGHT:
m_hScrollInfo.nPos = iMax;
case SB_LINELEFT://这个是点击向左移动的箭头
m_hScrollInfo.nPos -= 40;
break;
case SB_LINERIGHT:
m_hScrollInfo.nPos += 40; //加多少自己确定
break;
case SB_PAGELEFT:
//m_hScrollInfo.nPage -= iVisibleCol;
m_hScrollInfo.nPos -= 40; //减多少自己确定
break;
case SB_PAGERIGHT://这个是点击滑块右边的空白部分
//m_hScrollInfo.nPage += iVisibleCol;
m_hScrollInfo.nPos += 40;
break;
default:
break;
}
m_hScrollInfo.fMask = SIF_ALL;
SetScrollInfo(SB_HORZ, &m_hScrollInfo);
curHscroll = m_hScrollInfo.nPos;
GetScrollInfo(SB_HORZ, &m_hScrollInfo);
if (iVertPos != m_hScrollInfo.nPos)
{
Invalidate();//会发送WM_PAINT消息
//ScrollWindow(m_lCellWith*(iVertPos-m_hScrollInfo.nPos),0);
}
CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}
void CjupiaoDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
int iMin(0), iMax(0), iVisibleCol(0), iVertPos(0);
SCROLLINFO m_vScrollInfo;
GetScrollInfo(SB_VERT, &m_vScrollInfo, SIF_ALL);
iVertPos = m_vScrollInfo.nPos; //滚动条未滑动前的位置
iMin = m_vScrollInfo.nMin;
iMax = m_vScrollInfo.nMax;
iVisibleCol = m_vScrollInfo.nPage;
lastVscroll = iVertPos;
switch (nSBCode)
{
case SB_THUMBTRACK:
m_vScrollInfo.nPos = nPos;
break;
case SB_TOP:
m_vScrollInfo.nPos = iMin;
break;
case SB_BOTTOM:
m_vScrollInfo.nPos = iMax;
case SB_LINEUP:
m_vScrollInfo.nPos -= 40;
break;
case SB_LINEDOWN:
m_vScrollInfo.nPos += 40; //加多少自己确定
break;
case SB_PAGEUP:
m_vScrollInfo.nPage -= iVisibleCol;
m_vScrollInfo.nPos -= 40; //减多少自己确定
break;
case SB_PAGEDOWN:
m_vScrollInfo.nPage += iVisibleCol;
m_vScrollInfo.nPos += 40;
break;
default:
break;
}
m_vScrollInfo.fMask = SIF_ALL;
SetScrollInfo(SB_VERT, &m_vScrollInfo);
curVscroll = m_vScrollInfo.nPos;
GetScrollInfo(SB_VERT, &m_vScrollInfo);
if (iVertPos != m_vScrollInfo.nPos)
{
Invalidate();
//ScrollWindow(m_lCellWith*(iVertPos-m_vScrollInfo.nPos),0);
}
CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);
}
3.自定义一个函数用来对每一个控件改变位置:
void CjupiaoDlg::automove()
{
float fsp[2];
POINT Newp; //获取现在对话框的大小
CRect recta;
long stepH = curHscroll - lastHscroll;
long stepV = curVscroll - lastVscroll;
GetClientRect(&recta); //取客户区大小
Newp.x = recta.right - recta.left;
Newp.y = recta.bottom - recta.top;
fsp[0] = (float)Newp.x / Old.x;
fsp[1] = (float)Newp.y / Old.y;
CRect Rect;
int woc;
CPoint OldTLPoint, TLPoint; //左上角
CPoint OldBRPoint, BRPoint; //右下角
HWND hwndChild = ::GetWindow(m_hWnd, GW_CHILD); //列出所有控件
while (hwndChild)
{
woc = ::GetDlgCtrlID(hwndChild);//取得ID
GetDlgItem(woc)->GetWindowRect(Rect);
ScreenToClient(Rect);
OldTLPoint = Rect.TopLeft();
TLPoint.x = long((OldTLPoint.x - stepH)*fsp[0]);
TLPoint.y = long((OldTLPoint.y - stepV)*fsp[1]);
OldBRPoint = Rect.BottomRight();
BRPoint.x = long((OldBRPoint.x - stepH) *fsp[0]);
BRPoint.y = long((OldBRPoint.y - stepV) *fsp[1]);
Rect.SetRect(TLPoint, BRPoint);
GetDlgItem(woc)->MoveWindow(Rect, TRUE);
hwndChild = ::GetWindow(hwndChild, GW_HWNDNEXT);
}
Old = Newp;
}
4.最后在OnPaint()里面加入:
automove();
大概长成这个样子:
void CjupiaoDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 使图标在工作区矩形中居中
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
automove();
CDialogEx::OnPaint();
}
}
//Over!