最近在做WinCE平台的应用程序的开发,采用SDK编程,对窗口中有滚动条的时候处理上有一些问题,主要是刷新、重绘页面的问题,特别向大虾们请教:1. 当启动程序运行时,窗口中还没有任何的内容,我希望窗口上不出现滚动条。这是问题一。2. 触发某一个事件以后(比如按下某个按键等等),窗口页面中就会出现相关的内容,这些内容包含了自定义的Text控件(文本控件),Button控件(按钮控件),Input控件(输入控件)等等(这些控件都是自己定义和实现的,和MFC上的那些不太一样)。当窗口页面上的内容很多,当前窗口显示不下的时候,就出现滚动条。(这个需要计算页面中所有控件,比较他们的坐标,从而得到最大的宽度和高度以后,设置滚动条,虽然可以,但是页面上控件比较多,有些麻烦。)这个是问题二。3. 就是拖动水平或者是垂直滚动条时,刷新重绘的问题。这个是问题三。
对于问题1,预先定义一个大的高度,初始运行显示滚动条,但是灰色的,没有滚动块的。
对于问题2,开始觉得可以再创建一个子控件窗口,将子控件窗口嵌入到主窗口中,将控件的绘制全部放在子窗口中进行,这样对于问题3,就比较简单了,就是先计算出滚动的距离,然后重新在主窗口中绘制子窗口。对于这个还有一个想法,就是类似MFC中的那个改变窗口源点的坐标SetWindowOrg,SetWindowOrgEx,SetViewportOrg等等之类的函数,这样在刷新的时候就不用一个个的改变页面中所有控件的坐标了,这个最简单,但是SDK中不知道如何实现的。对于问题3,取决于问题2的方法。
各位高手,你们有什么好的方法,或者是比较很容易实现的方法或者是例子,请指点一下,谢谢!!!
对于问题1,预先定义一个大的高度,初始运行显示滚动条,但是灰色的,没有滚动块的。
对于问题2,开始觉得可以再创建一个子控件窗口,将子控件窗口嵌入到主窗口中,将控件的绘制全部放在子窗口中进行,这样对于问题3,就比较简单了,就是先计算出滚动的距离,然后重新在主窗口中绘制子窗口。对于这个还有一个想法,就是类似MFC中的那个改变窗口源点的坐标SetWindowOrg,SetWindowOrgEx,SetViewportOrg等等之类的函数,这样在刷新的时候就不用一个个的改变页面中所有控件的坐标了,这个最简单,但是SDK中不知道如何实现的。对于问题3,取决于问题2的方法。
各位高手,你们有什么好的方法,或者是比较很容易实现的方法或者是例子,请指点一下,谢谢!!!
解决方案 »
- 请问如何unsigned char *转化为char []形式?
- 在对话框中显示50多张图片,如何解决?
- 怎么把WORD格式改成TIF格式?
- 是不是ACE5.4.1有BUG?
- 庆祝再次升5个角,向星努力!
- 大哥们,我是菜鸟!问个问题
- 请问能够控制多线程的执行顺序吗?
- 一个关于系统异常的问题(关注有分)
- 关于在VC中用EXCEL,SAVEAS的参数FILEFORMAT的问题
- 用VB做前台,VC做后台服务进程时,怎么传递消息?
- HOOK ZwCreateProcessEx,当内部返回值为什么时,能够避免“*.exe 句柄无效”对话框的弹出?
- 对彩色图形进行纹理和边缘提取操作是否需要先转化成灰度图?
::ShowScrollBar(GetHandle(), SB_HORZ, TRUE);
2.如果需要显示SCROLLBAR,在ShowScrollBar之后,需要设置SCROLLBAR的滚动参数SetScrollInfo si.nMin = 0;
si.nMax = (nViewWidth - rcClient.right) / m_nScrollLineDP + m_nScrollPageDP;
si.nPos = 0;
si.nPage = m_nScrollPageDP;
::SetScrollInfo(GetHandle(), SB_HORZ, &si, TRUE);3.现在SCROLLBAR有了,并且也能滚动了.然后在滚动消息中,更新画面:
因为我封装的时候,考虑到了画面的缩放.所以在SCROLLBAR的滚动消息中,
A.重新计算视角偏移参数 GetViewInfo 这个函数主要计算出SetWindowOrgEx中的坐标
B.调用UpdateWindow更新背景,我在WM_ERASEBKGND消息中,设置DC的逻辑坐标与设备坐标,并且设置WindowOrg.
MESSAGE_HANDLER(WM_HSCROLL, OnHScroll)LRESULT CKScrollWnd::OnHScroll(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
//HDC hdc;
int nPos;
SCROLLINFO si; // Get all the vertial scroll bar information
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
// Save the position for comparison later on
::GetScrollInfo(GetHandle(), SB_HORZ, &si);
nPos = si.nPos;
switch (LOWORD(wParam))
{
// user clicked left arrow
case SB_LINELEFT:
si.nPos -= si.nPage;
break;
// user clicked right arrow
case SB_LINERIGHT:
si.nPos += m_bScrollLinePage ? si.nPage : 1;
break;
// user clicked the scroll bar shaft left of the scroll box
case SB_PAGELEFT:
si.nPos -= m_bScrollLinePage ? si.nPage : 1;
break;
// user clicked the scroll bar shaft right of the scroll box
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;
// user dragged the scroll box
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
default:
break;
}
// Set the position and then retrieve it. Due to adjustments
// by Windows it may not be the same as the value set.
si.fMask = SIF_POS;
if (si.nPos >= si.nMax - (INT)si.nPage)
{
si.nPos = si.nMax;
}
::SetScrollInfo(GetHandle(), SB_HORZ, &si, TRUE);
::GetScrollInfo(GetHandle(), SB_HORZ, &si); // If the position has changed, scroll the window
if (si.nPos != nPos)
{
//::ScrollWindow(GetHandle(), m_nScrollDP * (nPos - si.nPos), 0, NULL, NULL);
GetViewInfo(&m_sizeDP, &m_sizeLP, &m_ptWindowOrg);
::InvalidateRect(GetHandle(), NULL, TRUE);
::UpdateWindow(GetHandle());
}
return 0;
}
4.现在SCROLLBAR滚动了,并且通知窗口刷新.这时候就可以设置DC的WindowOrg,并且重新绘制.BOOL CKScrollWnd::OnErasebkgnd(HDC hdc)
{
.
.
.
SetScrollDCMapSize(hTargetDC); return TRUE;
}BOOL CKScrollWnd::OnPaint(HDC hdc)
{
.
.Draw
. return TRUE;
}
void CKScrollWnd::SetScrollDCMapSize(HDC hdc)
{
if (!hdc)
{
return;
}
::SetMapMode(hdc, MM_ANISOTROPIC);
::SetWindowExtEx(hdc, m_sizeLP.cx, m_sizeLP.cy, NULL);
::SetViewportExtEx(hdc, m_sizeDP.cx, m_sizeDP.cy, NULL);
::SetWindowOrgEx(hdc,
m_ptWindowOrg.x,
m_ptWindowOrg.y, NULL);
}
因为通过SetWindowOrg实现,其他地方使用逻辑坐标绘图,所以不需要做其他处理.该怎么画还怎么画.