关于 InvalidateRect (hwnd, NULL, TRUE)函数

zhangbinnpu 2007-03-15 05:15:37
这是《windows程序设计》中的例题,在case WM_PAINT:分支中用了InvalidateRect (hwnd, NULL, TRUE)函数,但是我去掉这个函数以后程序也可以正常运行,请那位达人给解释一下用法和原因!
#include <windows.h>

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,

PSTR szCmdLine, int iCmdShow)

{

static TCHAR szAppName[] = TEXT ("Bezier") ;

HWND hwnd ;

MSG msg ;

WNDCLASS wndclass ;


wndclass.style = CS_HREDRAW | CS_VREDRAW ;

wndclass.lpfnWndProc= WndProc ;

wndclass.cbClsExtra = 0 ;

wndclass.cbWndExtra = 0 ;

wndclass.hInstance = hInstance ;

wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;

wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;

wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;

wndclass.lpszMenuName= NULL ;

wndclass.lpszClassName= szAppName ;



if (!RegisterClass (&wndclass))

{

MessageBox (NULL, TEXT ("Program requires Windows NT!"),

szAppName, MB_ICONERROR) ;

return 0 ;

}



hwnd = CreateWindow (szAppName, TEXT ("Bezier Splines"),

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, CW_USEDEFAULT,

CW_USEDEFAULT, CW_USEDEFAULT,

NULL, NULL, hInstance, NULL) ;



ShowWindow (hwnd, iCmdShow) ;

UpdateWindow (hwnd) ;



while (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg) ;

DispatchMessage (&msg) ;

}

return msg.wParam ;

}


void DrawBezier (HDC hdc, POINT apt[])

{

PolyBezier (hdc, apt, 4) ;

MoveToEx (hdc, apt[0].x, apt[0].y, NULL) ;

LineTo (hdc, apt[1].x, apt[1].y) ;



MoveToEx (hdc, apt[2].x, apt[2].y, NULL) ;

LineTo (hdc, apt[3].x, apt[3].y) ;

}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

static POINT apt[4] ;

HDC hdc ;

int cxClient, cyClient ;

PAINTSTRUCT ps ;


switch (message)

{

case WM_SIZE:

cxClient = LOWORD (lParam) ;

cyClient = HIWORD (lParam) ;



apt[0].x = cxClient / 4 ;

apt[0].y = cyClient / 2 ;



apt[1].x = cxClient / 2 ;

apt[1].y = cyClient / 4 ;



apt[2].x = cxClient / 2 ;

apt[2].y = 3 * cyClient / 4 ;



apt[3].x = 3 * cxClient / 4 ;

apt[3].y = cyClient / 2 ;



return 0 ;


case WM_LBUTTONDOWN:

case WM_RBUTTONDOWN:

case WM_MOUSEMOVE:

if (wParam & MK_LBUTTON || wParam & MK_RBUTTON)

{

hdc = GetDC (hwnd) ;

SelectObject (hdc, GetStockObject (WHITE_PEN)) ;

DrawBezier (hdc, apt) ;



if (wParam & MK_LBUTTON)

{

apt[1].x = LOWORD (lParam) ;

apt[1].y = HIWORD (lParam) ;

}



if (wParam & MK_RBUTTON)

{

apt[2].x = LOWORD (lParam) ;

apt[2].y = HIWORD (lParam) ;

}



SelectObject (hdc, GetStockObject (BLACK_PEN)) ;

DrawBezier (hdc, apt) ;

ReleaseDC (hwnd, hdc) ;

}

return 0 ;

case WM_PAINT:

InvalidateRect (hwnd, NULL, TRUE) ;



hdc = BeginPaint (hwnd, &ps) ;



DrawBezier (hdc, apt) ;



EndPaint (hwnd, &ps) ;

return 0 ;



case WM_DESTROY:

PostQuitMessage (0) ;

return 0 ;

}

return DefWindowProc (hwnd, message, wParam, lParam) ;

}
...全文
516 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangbinnpu 2007-03-16
  • 打赏
  • 举报
回复
非常感谢上面众位好心的兄弟了 :)
尘雨 2007-03-16
  • 打赏
  • 举报
回复
我的理解是 InvalidateRect (hwnd, NULL, TRUE) ;
将会引发一个WM_PAINT消息,这样的理解对不?

不会!!这仅仅是把一个矩形标记为一个需要下一次重绘的无效区域,在下一个WM_PAINT消息的时候,会把这个区域加入到需要更新的区域,并计算出需要重绘的最小区域

在程序里调用UpdateWindow();可以强制发出WM_PAINT消息,至于是否重绘,取决于计算出来的需要更新的区域又没有,如果没有,就不需要重绘,否则重绘那些无效区域
菜牛 2007-03-16
  • 打赏
  • 举报
回复
我一直认为这段例程是错的,误导了很多人,在WM_PAINT消息中加InvalidateRect()不知道干什么。
zhangbinnpu 2007-03-16
  • 打赏
  • 举报
回复
我的理解是 InvalidateRect (hwnd, NULL, TRUE) ;
将会引发一个WM_PAINT消息,这样的理解对不?
livedeal 2007-03-16
  • 打赏
  • 举报
回复
你上面的代码本来加不加就一样,怎么看的出来有效果啊~
tracing 2007-03-16
  • 打赏
  • 举报
回复
InvalidateRect()单独用是没效果的,要和UpdateWindow()一起使用才有效果
//立即刷新这块区域
InvalidateRect(rect);
UpdateWindow();
zhangbinnpu 2007-03-15
  • 打赏
  • 举报
回复
我刚才试了一下,加不加那个函数效果都是一样的

不知道是什么原因?
rollor_phoe 2007-03-15
  • 打赏
  • 举报
回复
程序是可以正常运行,但当你改变窗口中的东西以后,程序并不调用InvalidateRect函数使矩形区域变得无效,你画出来的东西就不会立即显示出来,只有当你移动窗口时才会引起窗口重绘,从而将你刚才所画的东西显示出来。
加上了InvalidateRect函数就会在你在窗口中画出东西后立即在窗口中显示你画的东西。
其实就这个样了,要我说得多么清楚我也说不清,你试试就可以了。
先不加此函数,然后做一些操作,然后再加上此函数,再做一些操作,看两次有什么区别,然后函数的作用就出来了。
zhangbinnpu 2007-03-15
  • 打赏
  • 举报
回复
上面的兄弟能不能给详细解释一下,我是刚开始学的-_-!
xyxfly 2007-03-15
  • 打赏
  • 举报
回复
但是我去掉这个函数以后程序也可以正常运行

该不该去掉只是看你需不需要使用

关于该函数的功能楼上已经讲了:)
freecsw 2007-03-15
  • 打赏
  • 举报
回复
InvalidateRect函数使矩形区域变得无效,从而引发重绘

16,465

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧