In Windows, the getkeystate function can return the status of keys such as the mouse button or shift. When the getkeystate function returns a negative value, it indicates that the mouse button or the corresponding shift or ctrl key has been pressed.
You cannot use the getkeystate function when you do not press the mouse.
During mouse events, you sometimes need to bitwise AND perform operations on the wparam and mk_xx parameters.
If (wparam & mk_shift) {If (wparam & mk_control) {Press SHIFT + ctrl} else {Press Shift key} else {If (wparam & mk_control) {Press the ctrl key} The else {shift and CTRL keys are not pressed }}
Another example:
Case wm_lbuttondown: If (! (Wparam & mk_shift) {here the left button is processed;} return 0;
The following common virtual key code:
VK_LBUTTONVK_RBUTTONVK_MBUTTONVK_SHIFTVK_CONTROLVK_LMENUVK_RMENU
Look at non-customer zone mouse messages
The non-customer area of the window includes the title bar, menu, and window scroll bar.
The message generated by the mouse button is as follows:
| Button |
Press |
Release |
The second time you press the button |
| Left click |
Wm_nclbuttondown |
Wm_nclbuttonup |
Wm_nclbuttondblclk |
| Key |
Wm_ncmbuttondown |
Wm_ncmbuttonup |
Wm_ncmbuttondblclk |
| Right-click |
Wn_ncrbuttondown |
Wm_ncrbuttonup |
Wm_ncrbuttondblclk |
The following two functions can be used to swap the screen coordinates and the client zone coordinates.
ScreenToClient(hwnd,&pt);ClientToScreen(hwnd,&pt);
Hit Test message:
| Htclient |
Customer Zone |
| Htnowhere |
Not in any window |
| Httransparent |
Windows overwritten by another window |
| Ror |
Enable the defwindowproc function to generate an alert |
The following code makes your window abnormal every day, so that it does not work properly.
case WM_NCHITTEST: return (LRESULT)HTNOWHERE;
At this time, no matter where the mouse is in the window, including the system menu icon, adjust the size or close button, the mouse button operation will become invalid.
A simple program that divides the customer division into 25 rectangles to form an array of 5x5. If you click the mouse in one of the rectangles, fill the rectangle with X and click again, then, X disappears;
# Include <windows. h> # include <windowsx. h> # define divisions 5 lresult callback windowproc (hwnd, // handle to window uint umsg, // message identifier wparam, // first message parameter lparam // second message parameter); int winapi winmain (hinstance, // handle to current instance hinstance hprevinstance, // handle to previous instance lpstr lpcmdline, // command line int n Cmdshow // show state) {static tchar szappname [] = text ("leidemingzi"); hwnd; MSG; wndclass. cbclsextra = 0; wndclass. cbwndextra = 0; wndclass. hbrbackground = (hbrush) getstockobject (white_brush); wndclass. hcursor = loadcursor (null, idc_arrow); wndclass. hicon = loadicon (null, idi_error); wndclass. hinstance = hinstance; wndclass. lpfnwndproc = windowproc; wndclass. lpszclassname = szappname; wndclass. lpszme Nuname = NULL; wndclass. Style = cs_hredraw | cs_vredraw; If (! Registerclass (& wndclass) {MessageBox (null, text ("the program require window nt"), szappname, mb_iconerror); Return 0;} hwnd = createwindow (szappname, // registered Class Name text ("this is Title"), // window name ws_overlappedwindow, // window style cw_usedefault, // horizontal position of window cw_usedefault, // vertical position of window cw_usedefault, // window width cw_usedefault, // window height null, // handle to parent or owner window null, // menu handle or child identifier hinstance, // handle to application instance null // window-creation data); showwindow (hwnd, ncmdshow); updatewindow (hwnd); While (getmessage (& MSG, null, 0, 0 )) {translatemessage (& MSG); dispatchmessage (& MSG);} return MSG. wparam;} lresult callback windowproc (hwnd, // handle to window uint umsg, // message identifier wparam, // first message parameter lparam // second message parameter) {HDC; paintstruct pS; static bool fstate [divisions] [divisions]; static int cxblock, cyblock; int X, Y; rect; Switch (umsg) {Case wm_size: cxblock = loword (lparam)/divisions; // all parts are divided into five parts: cyblock = hiword (lparam)/divisions; return 0; Case wm_lbuttondown: x = get_x_lparam (lparam)/cxblock; y = get_y_lparam (lparam)/cyblock; If (x <divisions & Y <divisions) {fstate [x] [Y] ^ = 1; // returns or, if "X" is displayed, then "X" disappears. If "X" is not displayed, "xrect" is displayed. left = x * cxblock; // mark the area of the clicked rectangle, and fix a rect range for "display" and "disappear. top = y * cyblock; rect. right = (x + 1) * cxblock; rect. bottom = (Y + 1) * cyblock; invalidaterect (hwnd, & rect, false);} else {messagebeep (0);} return 0; Case wm_paint: HDC = beginpaint (hwnd, & PS); For (x = 0; x <divisions; ++ X) {for (y = 0; y <divisions; ++ y) {rectangle (HDC, x * cxblock, y * cyblock, (x + 1) * cxblock, (Y + 1) * cyblock); If (fstate [x] [Y]) // draw "X" {movetoex (HDC, x * cxblock, y * cyblock, null); lineto (HDC, (x + 1) * cxblock, (Y + 1) * cyblock); movetoex (HDC, x * cxblock, (Y + 1) * cyblock, null); lineto (HDC, (x + 1) * cxblock, y * cyblock) ;}} endpaint (hwnd, & PS); Return 0; Case wm_destroy: postquitmessage (0); Return 0;} return defwindowproc (hwnd, umsg, wparam, lparam );}
The running result is as follows:
You can use subwindows to perform the same functions:
#include <windows.h>#define DIVISIONS 5LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;LRESULT CALLBACK ChildWndProc (HWND, UINT, WPARAM, LPARAM) ;TCHAR szChildClass[] = TEXT ("Checker3_Child") ;int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ static TCHAR szAppName[] = TEXT ("Checker3") ; 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 ; } wndclass.lpfnWndProc = ChildWndProc ; wndclass.cbWndExtra = sizeof (long) ; wndclass.hIcon = NULL ; wndclass.lpszClassName = szChildClass ; RegisterClass (&wndclass) ; hwnd = CreateWindow (szAppName, TEXT ("Checker3 Mouse Hit-Test Demo"), 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 message, WPARAM wParam, LPARAM lParam){ static HWND hwndChild[DIVISIONS][DIVISIONS] ; int cxBlock, cyBlock, x, y ; switch (message) { case WM_CREATE : for (x = 0 ; x < DIVISIONS ; x++) for (y = 0 ; y < DIVISIONS ; y++) hwndChild[x][y] = CreateWindow (szChildClass, NULL, WS_CHILDWINDOW | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU) (y << 8 | x), (HINSTANCE) GetWindowLong (hwnd, GWL_HINSTANCE), NULL) ; return 0 ; case WM_SIZE : cxBlock = LOWORD (lParam) / DIVISIONS ; cyBlock = HIWORD (lParam) / DIVISIONS ; for (x = 0 ; x < DIVISIONS ; x++) for (y = 0 ; y < DIVISIONS ; y++) MoveWindow (hwndChild[x][y], x * cxBlock, y * cyBlock, cxBlock, cyBlock, TRUE) ; return 0 ; case WM_LBUTTONDOWN : MessageBeep (0) ; return 0 ; case WM_DESTROY : PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}LRESULT CALLBACK ChildWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ HDC hdc ; PAINTSTRUCT ps ; RECT rect ; switch (message) { case WM_CREATE : SetWindowLong (hwnd, 0, 0) ; // on/off flag return 0 ; case WM_LBUTTONDOWN : SetWindowLong (hwnd, 0, 1 ^ GetWindowLong (hwnd, 0)) ; InvalidateRect (hwnd, NULL, FALSE) ; return 0 ; case WM_PAINT : hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; Rectangle (hdc, 0, 0, rect.right, rect.bottom) ; if (GetWindowLong (hwnd, 0)) { MoveToEx (hdc, 0, 0, NULL) ; LineTo (hdc, rect.right, rect.bottom) ; MoveToEx (hdc, 0, rect.bottom, NULL) ; LineTo (hdc, rect.right, 0) ; } EndPaint (hwnd, &ps) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ;}