滑鼠(2)

來源:互聯網
上載者:User

Windows的GetKeyState函數能夠返回滑鼠按鍵或Shift等鍵的狀態,當GetKeyState函數返回一個負值時,表示已經按下了滑鼠按鍵或相應的Shift或Ctrl鍵。

在沒有按下滑鼠時,不能使用GetKeyState函數。

在滑鼠事件的時候,有時候,需要對參數wParam和MK_XX進行位與運算

if(wParam & MK_SHIFT){    if(wParam  &  MK_CONTROL)    {        按下Shift+Ctrl    }     else{        按下Shift鍵    }}else{    if(wParam & MK_CONTROL)    {        按下Ctrl鍵    }     else    {       Shift和Ctrl鍵都沒有按下    }}

又如:

case WM_LBUTTONDOWN:     if(!(wParam & MK_SHIFT))     {        這裡處理左鍵;     }      return 0;

下面常用的虛擬按鍵碼:

VK_LBUTTONVK_RBUTTONVK_MBUTTONVK_SHIFTVK_CONTROLVK_LMENUVK_RMENU

看看非客戶區滑鼠訊息

視窗的非客戶區包括標題列,菜單和視窗捲軸。

滑鼠按鍵產生的訊息如下所示:

按鈕 按下 釋放 第二次按下按鈕
左鍵 WM_NCLBUTTONDOWN WM_NCLBUTTONUP WM_NCLBUTTONDBLCLK
中鍵 WM_NCMBUTTONDOWN WM_NCMBUTTONUP WM_NCMBUTTONDBLCLK
右鍵 WN_NCRBUTTONDOWN WM_NCRBUTTONUP WM_NCRBUTTONDBLCLK

 

利用下面兩個函數,可以將螢幕座標和客戶區座標進行互換

ScreenToClient(hwnd,&pt);ClientToScreen(hwnd,&pt);

擊中測試訊息:

HTCLIENT 客戶區
HTNOWHERE 不在任何視窗
HTTRANSPARENT 被另一個視窗覆蓋的視窗
HTERROR 使函數DefWindowProc產生一個警示聲

 

下面這個代碼,可以讓你的視窗叫天天不應,叫地地不靈

case WM_NCHITTEST:         return (LRESULT)HTNOWHERE;

此時,無論滑鼠位於視窗任何位置,包括系統功能表表徵圖,調整大小和關閉按鈕,滑鼠按鍵操作都將失效。

 

一個簡單的程式,該程式將客戶區劃分成25個矩形,構成5X5的數組,如果在其中一個矩形內單擊滑鼠,就用X形填充該矩形,再次單擊,則X形消失;

#include<windows.h>#include<windowsx.h>#define DIVISIONS 5LRESULT CALLBACK WindowProc(  HWND hwnd,      // handle to window  UINT uMsg,      // message identifier  WPARAM wParam,  // first message parameter  LPARAM lParam   // second message parameter);int WINAPI WinMain(  HINSTANCE hInstance,      // handle to current instance  HINSTANCE hPrevInstance,  // handle to previous instance  LPSTR lpCmdLine,          // command line  int nCmdShow              // show state){static TCHAR szAppName[]=TEXT("leidemingzi");HWND hwnd;MSG msg;WNDCLASS wndclass;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.lpszMenuName=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 hwnd,      // handle to window  UINT uMsg,      // message identifier  WPARAM wParam,  // first message parameter  LPARAM lParam   // second message parameter){HDC hdc;PAINTSTRUCT ps;static BOOL fState[DIVISIONS][DIVISIONS];static int cxBlock,cyBlock;int x,y;RECT rect;switch(uMsg){case WM_SIZE:cxBlock=LOWORD(lParam)/DIVISIONS;//橫豎都分成五份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;//異或,如果已經顯示了X,再點擊,則X消失,如果沒有X顯示,則點擊會顯示Xrect.left=x*cxBlock; //標記該被點擊的矩形地區,為後面“顯示”和“消失”固定一個範圍rect.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])//畫“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);}

運行結果如下:

 

 可以用子視窗完成相同的功能:

#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) ;}

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.