• 第七章 鼠标(CHECKER1)


    CHECKER1程序将客户区划分成25个矩形,构成一个5*5的数组。如果在其中一个矩形内单击鼠标,就用X形填充该矩形。再次单击,则X形消失。

      1 /*--------------------------------------------
      2 CHECKER1.C -- Mouse Hit-Test Demo Program No.1
      3               (c) Charles Petzold, 1998
      4 --------------------------------------------*/
      5 
      6 #include <Windows.h>
      7 
      8 #define DIVISION 5
      9 
     10 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
     11 
     12 int WINAPI WinMain( __in HINSTANCE hInstance
     13                     , __in_opt HINSTANCE hPrevInstance
     14                     , __in LPSTR lpCmdLine
     15                     , __in int nShowCmd )
     16 {
     17     static TCHAR szAppName[] = TEXT("Checker1");
     18     HWND hwnd;
     19     MSG msg;
     20     WNDCLASS wndclass;
     21 
     22     wndclass.style = CS_HREDRAW | CS_VREDRAW;
     23     wndclass.lpfnWndProc = WndProc;
     24     wndclass.cbClsExtra = 0;
     25     wndclass.cbWndExtra = 0;
     26     wndclass.hInstance = hInstance;
     27     wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
     28     wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
     29     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
     30     wndclass.lpszMenuName = NULL;
     31     wndclass.lpszClassName = szAppName;
     32 
     33     if (!RegisterClass(&wndclass))
     34     {
     35         MessageBox(NULL, TEXT("Program requires Windows NT!")
     36             , szAppName, MB_ICONERROR);
     37         return 0;
     38     }
     39 
     40     hwnd = CreateWindow(szAppName, TEXT("Checker1 Mouse Hit-Test Demo")
     41         , WS_OVERLAPPEDWINDOW
     42         , CW_USEDEFAULT, CW_USEDEFAULT
     43         , CW_USEDEFAULT, CW_USEDEFAULT
     44         , NULL, NULL, hInstance, NULL);
     45 
     46     ShowWindow(hwnd, nShowCmd);
     47     UpdateWindow(hwnd);
     48 
     49     while (GetMessage(&msg, NULL, 0, 0))
     50     {
     51         TranslateMessage(&msg);
     52         DispatchMessage(&msg);
     53     }
     54 
     55     return msg.wParam;
     56 }
     57 
     58 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
     59 {
     60     static BOOL fState[DIVISION][DIVISION];
     61     static int cxBlock, cyBlock;
     62     HDC hdc;
     63     int x, y;
     64     PAINTSTRUCT ps;
     65     RECT rect;
     66 
     67     switch (message)
     68     {
     69     case WM_SIZE:
     70         cxBlock = LOWORD(lParam) / DIVISION;
     71         cyBlock = HIWORD(lParam) / DIVISION;
     72         return 0;
     73 
     74     case WM_LBUTTONDOWN:
     75         x = LOWORD(lParam) / cxBlock;
     76         y = HIWORD(lParam) / cyBlock;
     77 
     78         if (x < DIVISION && y < DIVISION)
     79         {
     80             fState[x][y] ^= 1;
     81 
     82             rect.left = x * cxBlock;
     83             rect.top = y * cyBlock;
     84             rect.right = (x + 1) * cxBlock;
     85             rect.bottom = (y + 1) * cyBlock;
     86 
     87             InvalidateRect(hwnd, &rect, FALSE);
     88         }
     89         else
     90             MessageBeep(0);
     91         return 0;
     92 
     93     case WM_PAINT:
     94         hdc = BeginPaint(hwnd, &ps);
     95 
     96         for (x = 0; x < DIVISION; ++x)
     97             for (y = 0; y < DIVISION; ++y)
     98             {
     99                 Rectangle(hdc, x * cxBlock, y * cyBlock
    100                     , (x + 1) * cxBlock, (y + 1) * cyBlock);
    101 
    102                 if (fState[x][y])
    103                 {
    104                     MoveToEx(hdc, x * cxBlock, y * cyBlock, NULL);
    105                     LineTo(hdc, (x + 1) * cxBlock, (y + 1) * cyBlock);
    106                     MoveToEx(hdc, x * cxBlock, (y + 1) * cyBlock, NULL);
    107                     LineTo(hdc, (x + 1) * cxBlock, y * cyBlock);
    108                 }
    109             }
    110 
    111         EndPaint(hwnd, &ps);
    112         return 0;
    113 
    114     case WM_DESTROY:
    115         PostQuitMessage(0);
    116         return 0;
    117     }
    118 
    119     return DefWindowProc(hwnd, message, wParam, lParam);
    120 }
    CHECKER1.C

    CHECKER1程序显示结果如图所示:

    所有25个矩形具有相同的宽度和高度,这些宽度和高度被保存在cxBlock、cyBlock中。无论何时改变客户区的大小,程序都将重新计算cxBlock、cyBlock。WM_LBUTTONDOWN处理逻辑利用鼠标的坐标来判断哪个矩形被单击,然后在fState数组中使用位运算符(按位异或^)计算那个矩形的新状态,最后强制使该矩形失效,从而产生WM_PAINT消息。

    如果客户区的宽度和高度不能被5整除,客户区的左边或底部就会出现一个小长条区域,不被举行覆盖。在这片区域进行鼠标单击时,CHECKER1程序会调用MessageBeep函数进行响应。

    当CHECKER1程序收到WM_PAINT消息时,它会重新绘制整个客户区,利用GDI中的Rectangle函数画出所有的矩形。若fState值为真,则CHECKER1程序调用函数MoveToEx和函数LineTo函数画出两条直线。

  • 相关阅读:
    每日日报24
    每日日报23
    每日日报22
    链路层:MAC 地址
    应用层:电子邮件
    应用层:HTTP 协议
    应用层:DNS 域名系统
    运输层:TCP 拥塞控制
    运输层:拥塞控制原理
    JAVA学习日记26-0731
  • 原文地址:https://www.cnblogs.com/web1013/p/9011687.html
Copyright © 2020-2023  润新知