奇怪的问题,InvalidateRect最后一个参数在XP下无效

一直用的WIN2K系统,写的一个程序在本机正常,到XP系统的机器运行发现调整窗口大小时界面闪得厉害,程序比较大,而且这种闪烁还不好调试,因为单步调试没有闪烁效果,只能排除法找原因,最后以为找到原因了,就写了一个测试程序,就是用VC6向导自动生成API的Hello World程序,然后修改一下其WM_PAINT代码:

  1. case WM_PAINT:
  2.             hdc = BeginPaint(hWnd, &ps);
  3.             // TODO: Add any drawing code here...
  4.             RECT rt;
  5.             GetClientRect(hWnd, &rt);
  6.             InflateRect(&rt,-20,-20);
  7.             BitBlt(hdc,rt.left,rt.top,rt.right-rt.left,rt.bottom-rt.top,hdc,0,0,BLACKNESS);
  8.             EndPaint(hWnd, &ps);
  9.             break;

效果是在窗口中间显示一个黑框,编译后调整窗口大小时画面闪烁,这是正常的。把窗口类型的CS_HREDRAW | CS_VREDRAW取消掉,即把ATOM MyRegisterClass(HINSTANCE hInstance)函数里改成

wcex.style   = 0;//CS_HREDRAW | CS_VREDRAW;

 

这下不闪了,但是也不画黑框了,因为不刷新了,需要在WM_SIZE消息里面通知刷新一下:

  1. case WM_SIZE:
  2.             InvalidateRect(hWnd,NULL,FALSE);
  3.             return DefWindowProc(hWnd, message, wParam, lParam);

按道理这段代码造成的效果应该是:黑框跟着窗口尺寸变化,但是背景会花,因为InvalidateRect的最后一个参数如果是FALSE,是不刷新背景的。在WIN2000下运行的确是这个效果,而在XP下,不管这最后一个参数是TRUE还是FALSE,效果跟原始代码是一样的,黑框闪烁得厉害,好象这个参数在XP下无效了。

 

解决方案是响应WM_ERASEBKGND,直接返回TRUE,在WIN2000和XP下就表现一致了。但是这个InvalidateRect的最后一个参数无效的问题就不知道怎么回事了,不知道是不是XP的BUG。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以通过以下步骤实现: 1. 在picture control的OnLButtonDown和OnLButtonUp事件中记录鼠标按下和松开的坐标。 2. 在OnMouseMove事件中,判断鼠标是否处于拖动状态,如果是则计算出矩形的左上角和右下角坐标,并根据这些坐标重新绘制矩形。 3. 在OnLButtonUp事件中,根据矩形的左上角和右下角坐标计算出矩形的宽度和高度,并将这些参数记录下来。 4. 在需要使用矩形参数的地方,可以直接调用记录下来的参数进行操作。 下面是一个简单的示例代码: void CPictureCtrlDlg::OnLButtonDown(UINT nFlags, CPoint point) { m_bDragging = TRUE; m_ptStart = point; m_ptEnd = point; CDialogEx::OnLButtonDown(nFlags, point); } void CPictureCtrlDlg::OnLButtonUp(UINT nFlags, CPoint point) { m_bDragging = FALSE; m_ptEnd = point; m_nWidth = abs(m_ptStart.x - m_ptEnd.x); m_nHeight = abs(m_ptStart.y - m_ptEnd.y); CDialogEx::OnLButtonUp(nFlags, point); } void CPictureCtrlDlg::OnMouseMove(UINT nFlags, CPoint point) { if (m_bDragging) { m_ptEnd = point; m_nWidth = abs(m_ptStart.x - m_ptEnd.x); m_nHeight = abs(m_ptStart.y - m_ptEnd.y); m_rcRect.left = min(m_ptStart.x, m_ptEnd.x); m_rcRect.top = min(m_ptStart.y, m_ptEnd.y); m_rcRect.right = max(m_ptStart.x, m_ptEnd.x); m_rcRect.bottom = max(m_ptStart.y, m_ptEnd.y); InvalidateRect(NULL); } CDialogEx::OnMouseMove(nFlags, point); } void CPictureCtrlDlg::OnPaint() { CPaintDC dc(this); CRect rcClient; GetClientRect(&rcClient); CBrush brush(RGB(255, 255, 255)); dc.FillRect(rcClient, &brush); if (m_bDragging) { CPen pen(PS_SOLID, 1, RGB(255, 0, 0)); CPen* pOldPen = dc.SelectObject(&pen); dc.Rectangle(&m_rcRect); dc.SelectObject(pOldPen); } } 在上面的代码中,m_bDragging表示鼠标是否处于拖动状态,m_ptStart和m_ptEnd表示矩形的左上角和右下角坐标,m_nWidth和m_nHeight表示矩形的宽度和高度,m_rcRect表示矩形的参数。在OnPaint事件中,如果鼠标处于拖动状态,则绘制矩形。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值