新手问:WM_PAINT和WM_SIZE的先后顺序问题?

wxen0772 2007-05-07 11:39:49
我想知道在下面的代码中WM_PAINT和WM_SIZE的顺序。
/*--------------------------------------------------
CLOVER.C -- Clover Drawing Program Using Regions
(c) Charles Petzold, 1998
--------------------------------------------------*/

#include <windows.h>
#include <math.h>

#define TWO_PI (2.0 * 3.14159)

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

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Clover") ;
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 ("This program requires Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}

hwnd = CreateWindow (szAppName, TEXT ("Draw a Clover"),
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 ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
static HRGN hRgnClip ;
static int cxClient, cyClient ;
double fAngle, fRadius ;
HCURSOR hCursor ;
HDC hdc ;
HRGN hRgnTemp[6] ;
int i ;
PAINTSTRUCT ps ;

switch (iMsg)
{
case WM_SIZE:
cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
MessageBox ( hwnd,TEXT("this is in WM_SIZE before !!") ,TEXT(" in size before "),NULL );

hCursor = SetCursor (LoadCursor (NULL, IDC_WAIT)) ;
ShowCursor (TRUE) ;
// MessageBox ( hwnd,TEXT("this is in WM_SIZE !!") ,TEXT(" in size"),NULL );
if (hRgnClip)
DeleteObject (hRgnClip) ;

// MessageBox ( hwnd,TEXT("this is in WM_SIZE brfore !!") ,TEXT(" in size "),NULL );

hRgnTemp[0] = CreateEllipticRgn (0, cyClient / 3,
cxClient / 2, 2 * cyClient / 3) ;
hRgnTemp[1] = CreateEllipticRgn (cxClient / 2, cyClient / 3,
cxClient, 2 * cyClient / 3) ;
hRgnTemp[2] = CreateEllipticRgn (cxClient / 3, 0,
2 * cxClient / 3, cyClient / 2) ;
hRgnTemp[3] = CreateEllipticRgn (cxClient / 3, cyClient / 2,
2 * cxClient / 3, cyClient) ;
hRgnTemp[4] = CreateRectRgn (0, 0, 1, 1) ;
hRgnTemp[5] = CreateRectRgn (0, 0, 1, 1) ;
hRgnClip = CreateRectRgn (0, 0, 1, 1) ;

CombineRgn (hRgnTemp[4], hRgnTemp[0], hRgnTemp[1], RGN_OR) ;
CombineRgn (hRgnTemp[5], hRgnTemp[2], hRgnTemp[3], RGN_OR) ;
CombineRgn (hRgnClip, hRgnTemp[4], hRgnTemp[5], RGN_XOR) ;

//MessageBox ( hwnd,TEXT("this is in WM_SIZE after!!") ,TEXT(" in size after "),NULL );

for (i = 0 ; i < 6 ; i++)
DeleteObject (hRgnTemp[i]) ;

SetCursor (hCursor) ;
ShowCursor (FALSE) ;
return 0 ;

case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;

MessageBox ( hwnd,TEXT("this is in WM_PAINT before !!") ,TEXT(" in paint before "),NULL );

SetViewportOrgEx (hdc, cxClient / 2, cyClient / 2, NULL) ;
SelectClipRgn (hdc, hRgnClip) ;

fRadius = _hypot (cxClient / 2.0, cyClient / 2.0) ;

for (fAngle = 0.0 ; fAngle < TWO_PI ; fAngle += TWO_PI / 360)
{
MoveToEx (hdc, 0, 0, NULL) ;
LineTo (hdc, (int) ( fRadius * cos (fAngle) + 0.5),
(int) (-fRadius * sin (fAngle) + 0.5)) ;
}

// MessageBox ( hwnd,TEXT("this is in WM_PAINT after!!") ,TEXT(" in paint after "),NULL );

EndPaint (hwnd, &ps) ;
return 0 ;

case WM_DESTROY:
DeleteObject (hRgnClip) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
}
我通过加MessageBox得到WM_PAINT然后WM_SIZE但是在CSDN以前的贴子中说的刚好相反,贴子为:http://topic.csdn.net/t/20030223/12/1456618.html#
高人能给个解释吗?尤其是在windows 是消息这一部分。。
...全文
704 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
maqiang13522399103 2007-05-15
  • 打赏
  • 举报
回复
当窗口从无到有的时候,整个客户区都是无效的,这是会产生WM_PAINT消息;
当调用ShowWindow函数时,此函数会发送WM_SIZE消息;
以后如果窗口的客户区在产生无效区域,那么就会发送WM_PAINT消息,
如果窗口大小发生变化,会发送WM_SIZE消息
wxen0772 2007-05-09
  • 打赏
  • 举报
回复
顶起。
wxen0772 2007-05-09
  • 打赏
  • 举报
回复
谢谢,怎么给分呢??
fflush 2007-05-09
  • 打赏
  • 举报
回复
窗口在初次显示的时候是先有WM_SIZE,然后才是WM_PAINT。另外,一般不要在WM_PAINT中调用MessageBox,这可能会导致窗口不断的重绘,你可以使用OutputDebugString,或者其它不会影响UI的方法
eggqq007 2007-05-09
  • 打赏
  • 举报
回复
这样说吧,比如你改变窗体大小,那么就是WM_SIZE
当窗体最小化又还原的时候就是WM_PAINT。
但是我怎么知道楼主你是先改变它大小还是先吧它最小化。我又不是你。
wxen0772 2007-05-09
  • 打赏
  • 举报
回复
顶起,有知道的高人吗?指点下啊
eggqq007 2007-05-08
  • 打赏
  • 举报
回复
程序一开始运行肯定先是WM_PAINT,但是以后就不确定了。
蒋晟 2007-05-08
  • 打赏
  • 举报
回复
无固定先后次序
wxen0772 2007-05-08
  • 打赏
  • 举报
回复
先谢谢上面各位,还是不怎么清楚.
无固定先后次序??那在一些情况下,比如变量的定义和使用上不是会出现问题吗?在怎么事件触发种不能是随机的把?
yingyys 2007-05-08
  • 打赏
  • 举报
回复
没有一定的先后顺序的,windows是事件触发的呵

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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