本文只适合窗口背景与前景一同滚动的情况,不适合背景固定不动的情况。
首先为窗口添加风格WS_VSCROLL(垂直滚动条)。
然后处理OnSize:
void CUserRegisterDlg::OnSize(UINT nType, int cx, int cy)
{
CDialogBase::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
OnVScroll(SB_TOP,0,NULL);
SetScrollRange(SB_VERT, 0, THEME->GetScreenPortraitSize().cy/*屏高*/ - TORP(52)/*标题栏菜单栏*/ - cy);
}
处理OnVScroll:
#define SW_STYLE SW_SCROLLCHILDREN|SW_INVALIDATE|SW_ERASE
void CUserRegisterDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO: Add your message handler code here and/or call default
SCROLLINFO scrollinfo;
GetScrollInfo(SB_VERT,&scrollinfo);
int& nPosFrom = scrollinfo.nPos;
int nPosTo = nPos;
switch (nSBCode)
{
case SB_BOTTOM:
nPosTo = scrollinfo.nMax;
goto label;
case SB_TOP:
nPosTo = scrollinfo.nMin;
goto label;
case SB_LINEUP:
nPosTo = scrollinfo.nPos - TORP(5);
if (scrollinfo.nPos == scrollinfo.nMin)
break;
else if (nPosTo < scrollinfo.nMin)
nPosTo = scrollinfo.nMin;
goto label;
case SB_LINEDOWN:
nPosTo = scrollinfo.nPos + TORP(5);
if (scrollinfo.nPos == scrollinfo.nMax)
break;
else if (nPosTo > scrollinfo.nMax)
nPosTo = scrollinfo.nMax;
goto label;
case SB_PAGEUP:
nPosTo = scrollinfo.nPos - TORP(130);
if (scrollinfo.nPos == scrollinfo.nMin)
break;
else if (nPosTo < scrollinfo.nMin)
nPosTo = scrollinfo.nMin;
goto label;
case SB_PAGEDOWN:
nPosTo = scrollinfo.nPos + TORP(130);
if (scrollinfo.nPos == scrollinfo.nMax)
break;
else if (nPosTo > scrollinfo.nMax)
nPosTo = scrollinfo.nMax;
goto label;
case SB_THUMBPOSITION:
if(scrollinfo.nPos==scrollinfo.nMax && (nPos>scrollinfo.nMax) )
break;
goto label;
case SB_THUMBTRACK:
if(scrollinfo.nPos==scrollinfo.nMax && (nPos>scrollinfo.nMax) )
break;
goto label;
label:
SetScrollPos(SB_VERT, nPosTo);
ScrollWindowEx(0, nPosFrom - nPosTo, NULL, NULL, NULL, NULL, SW_STYLE);
UpdateWindow();
break;
case SB_ENDSCROLL:
break;
}
CDialogBase::OnVScroll(nSBCode, nPos, pScrollBar);
}
运行时发现,在对话框刚打开时输入法为打开状态的情况下,窗口rect并没有根据输入法位置而自动调整,所以滚动条也就没出现。可以用下面代码解决:
#include <Sipapi.h>
BOOL CUserRegisterDlg::OnInitDialog()
{
CDialogBase::OnInitDialog();
// TODO: Add extra initialization here
SIPINFO si = {0};
si.cbSize = sizeof(si);
SHSipInfo(SPI_GETSIPINFO, 0, &si, 0);
BOOL bShow = si.fdwFlags&SIPF_ON;
if (bShow)
{
MoveWindow(&si.rcVisibleDesktop);
}
return FALSE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}