和处理键盘输入一样,WINDOWS将捕捉鼠标动作并把它们发送到相关窗口。这些活动包括左、右键按下、移动、双击新式鼠标还包括滚轮消息WM_WHEEL等。WINDOWS并不像处理键盘输入那样把所有的鼠标消息都导向有输入焦点的窗口,任何鼠标经过的窗口都将接收到鼠标消息,无论有否输入焦点。另外,窗口还会接收到鼠标在非客户区移动的消息(WM_NCMOVE),但大多数的情况下我们都会将其忽略掉。 对鼠标的每一个按钮都有两个消息:WM_LBUTTONDOWN,WM_RBUTTONDOWN 。对于三键鼠标还会有WM_MBUTTONDOWN和WM_MBUTTONUP消息,当鼠标在某窗口客户区移动时,该窗口将接收到WM_MOUSEMOVE消息。一个窗口若想处理WM_LBUTTONDBCLK或 WM_RBUTTONDBCLK,那么它的窗口类必须有CS_DBLCLKS风格,否则它就会接受到一堆的按键起落(WM_XBUTTONDOWN或WM_XBUTTONUP)的消息。 对于所有的消息,窗口过程函数传入的参数lParam包含了鼠标的位置,其中底位为x坐标,高位为y坐标,这些坐标值都是相对于窗口客户区的左上角的值,wParam中则包含了鼠标按钮的状态。
关键代码
//示例程序演示了如何等待左键按下消息,我们将在按下的位置显示一个字符串。 TCHAR FontName[]=_T("宋体"); TCHAR szCaptionmain[]=_T("My First Window!"); WPARAM keyChar =0x20;//0x20(十六进制)是空格的ascii码,亳州没有按键的时候程序正常显示 BOOL mouseClick=FALSE; POINT hitPoint; LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; HFONT hFont,hOldFont; switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // 分析菜单选择: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: 在此添加任意绘图代码... hFont=CreateFont(24,16,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SCRIPT,FontName); hOldFont =(HFONT)SelectObject(hdc,hFont); SetTextColor(hdc,RGB(200,200,50)); SetBkColor(hdc,RGB(0,0,255)); TextOut(hdc,0,0,(TCHAR*)&keyChar,1); if (mouseClick) { TextOut(hdc,hitPoint.x,hitPoint.y,szCaptionmain,lstrlen(szCaptionmain)); } SelectObject(hdc,hOldFont); EndPaint(hWnd, &ps); break; //case WM_MOUSEMOVE: case WM_LBUTTONDOWN://在左键按下时,获取其坐标,并在此处显示一字符串(WM_PAINT消息) hitPoint.x=LOWORD(lParam); hitPoint.y=HIWORD(lParam); mouseClick=!mouseClick;//两次显示一次 InvalidateRect(hWnd,NULL,TRUE); break; case WM_CHAR: keyChar=wParam; InvalidateRect(hWnd,NULL,TRUE); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }