主题:请教WM_MOUSEMOVE和Invalidaterect()的奇怪问题
各位朋友大家好!! 我初学windows编程。
发现有些消息的处理和函数的功能和想象中的并不一致,有2个想不明白的问题,就写了段代码和我的
理解,请大家帮我分析一下我写下的代码段,帮我解释一下原因。十分感谢!!!
[...]
static int iCount = 0; // number of calling WM_PAINT
char Buff[50];
switch(message)
{
case WM_LBUTTONDOWN: // left mouse button click
InvalidateRect(hwnd,NULL,TRUE); // (1) ???????????????????????????
hdc = GetDC();
sprintf(Buff,"Clicked Position:%i,%i",Point.x,Point,y);
TextOut(hdc,0,0,Buff,lstrlen(Buff));
ReleaseDC(hwnd,hdc);
return 0;
case WM_MOUSEMOVE: // (2) ???????????????????????
hdc = GetDC();
TextOut(hdc,0,yClient/2,"Moving",lstrlen("Moving"));
ReleaseDC(hwnd,hdc);
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);
sprintf(Buff,"OnPaint: %i times",iCount);
TextOut(hcd,0,yClient-16,Buff,lstrlen(Buff));
iCount++; // increment every time calling WM_PAINT
EndPaint(hwnd,&ps);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
[...]
根据我的理解,运行后,窗口客户区域应该显示 OnPaint: 0 times
是因为WINMAIN中创建窗口时调用的UpdateWindow(),然后静态变量iCount自增一次,为下次
WM_PAINT的调用次数显示做准备。
问题1:
我首先假定代码段中没有标记注释为 // (1) ??????????????? 的这句Invalidaterect。
此时,如果客户区域单击鼠标左键,就会在0,0位置写出 Clicked Position:x,y。我以Point变量
表示当前鼠标的位置,假如写出来的位置是Clicked Position:566,588。但是根据此消息,并没通知
更新客户区域,原来的数值还留会在客户区,所以在为 3,3 的位置单击鼠标,本来应该显示为:
Clicked Position:3,3
但是由于没有更新,实际的显示受到原来残留的值影响:Clicked Position:3,3,588 其中后边的,588
就是原来残留的值, 3,3这3个字符只是覆盖了原来的566。
所以我加上了注释为// (1) ???????????????的这句Invalidaterect,我认为在消息的开头先调用
这个函数通知窗口客户区域擦除原来背景重新画,这样原来残留的值就被擦掉了,然后向下执行代码:
输出文本,也就是写出新的鼠标位置。
可是实际运行的结果却不会写出的文本,无论怎么单击都不会,只显示出WM_PAINT中的OnPaint……
为什么会是这样??
问题2:
关于WM_MOUSEMOVE消息,这次其中的注释为// (2) ???????????????的是一直存在的。
这时,根据我的想法,把鼠标指针在客户区域移动就会导致窗口重画,每次重画OnPaint: X times
的iCount值都会增加。而鼠标停在客户区域中不动,就不会看见OnPaint的值在不断增加.而实际上,即
使把鼠标停在客户区域中,那个iCount值也在不断地增加,应该表示还在不停的调用WM_PAINT,只是我移
动鼠标的时候,它增加得更快而以,只有把鼠标移到客户区以外这个值才停止增加,
WM_MOUSEMOVE消息不是应该只监听鼠标移动吗?怎么不动时也会发送这个消息啊???
求各位的解答,再次感谢!!!!
发现有些消息的处理和函数的功能和想象中的并不一致,有2个想不明白的问题,就写了段代码和我的
理解,请大家帮我分析一下我写下的代码段,帮我解释一下原因。十分感谢!!!
[...]
static int iCount = 0; // number of calling WM_PAINT
char Buff[50];
switch(message)
{
case WM_LBUTTONDOWN: // left mouse button click
InvalidateRect(hwnd,NULL,TRUE); // (1) ???????????????????????????
hdc = GetDC();
sprintf(Buff,"Clicked Position:%i,%i",Point.x,Point,y);
TextOut(hdc,0,0,Buff,lstrlen(Buff));
ReleaseDC(hwnd,hdc);
return 0;
case WM_MOUSEMOVE: // (2) ???????????????????????
hdc = GetDC();
TextOut(hdc,0,yClient/2,"Moving",lstrlen("Moving"));
ReleaseDC(hwnd,hdc);
InvalidateRect(hwnd,NULL,TRUE);
return 0;
case WM_PAINT:
hdc = BeginPaint(hwnd,&ps);
sprintf(Buff,"OnPaint: %i times",iCount);
TextOut(hcd,0,yClient-16,Buff,lstrlen(Buff));
iCount++; // increment every time calling WM_PAINT
EndPaint(hwnd,&ps);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParam);
[...]
根据我的理解,运行后,窗口客户区域应该显示 OnPaint: 0 times
是因为WINMAIN中创建窗口时调用的UpdateWindow(),然后静态变量iCount自增一次,为下次
WM_PAINT的调用次数显示做准备。
问题1:
我首先假定代码段中没有标记注释为 // (1) ??????????????? 的这句Invalidaterect。
此时,如果客户区域单击鼠标左键,就会在0,0位置写出 Clicked Position:x,y。我以Point变量
表示当前鼠标的位置,假如写出来的位置是Clicked Position:566,588。但是根据此消息,并没通知
更新客户区域,原来的数值还留会在客户区,所以在为 3,3 的位置单击鼠标,本来应该显示为:
Clicked Position:3,3
但是由于没有更新,实际的显示受到原来残留的值影响:Clicked Position:3,3,588 其中后边的,588
就是原来残留的值, 3,3这3个字符只是覆盖了原来的566。
所以我加上了注释为// (1) ???????????????的这句Invalidaterect,我认为在消息的开头先调用
这个函数通知窗口客户区域擦除原来背景重新画,这样原来残留的值就被擦掉了,然后向下执行代码:
输出文本,也就是写出新的鼠标位置。
可是实际运行的结果却不会写出的文本,无论怎么单击都不会,只显示出WM_PAINT中的OnPaint……
为什么会是这样??
问题2:
关于WM_MOUSEMOVE消息,这次其中的注释为// (2) ???????????????的是一直存在的。
这时,根据我的想法,把鼠标指针在客户区域移动就会导致窗口重画,每次重画OnPaint: X times
的iCount值都会增加。而鼠标停在客户区域中不动,就不会看见OnPaint的值在不断增加.而实际上,即
使把鼠标停在客户区域中,那个iCount值也在不断地增加,应该表示还在不停的调用WM_PAINT,只是我移
动鼠标的时候,它增加得更快而以,只有把鼠标移到客户区以外这个值才停止增加,
WM_MOUSEMOVE消息不是应该只监听鼠标移动吗?怎么不动时也会发送这个消息啊???
求各位的解答,再次感谢!!!!