使用滚动条进行窗口滚动的一个例子(Windows Mobile MFC)
本文只适合窗口背景与前景一同滚动的情况,不适合背景固定不动的情况。
首先为窗口添加风格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 }