【新手求助】关于《windows程序设计》中鼠标击中测试程序的疑问
- C/C++ code
#define DIVISIONS 5LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){ static BOOL fState[DIVISIONS][DIVISIONS] ; static int cxBlock, cyBlock ; HDC hdc ; int x, y ; PAINTSTRUCT ps ; RECT rect ; switch (message) { 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 ; rect.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]) { 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, message, wParam, lParam) ;}switch哪位大神能稍微仔细地分段解释下代码的含义?
fState [x][y] ^= 1 ; 我对这句尤为不懂。。
小弟初学,谢谢大家了!!
[解决办法]
具体一些,
在WM_SIZE消息中,根据窗口的实际大小和预定义的DIVISIONS计算出每个小方格的大小
在WM_LBUTTONDOWN消息中,根据鼠标点击位置的坐标计算出对应的小方格,通过fState变量判断该小方格是否已经画叉,并更新fState的状态,然后计算出小方格的范围,放在矩形结构rect中,再通过InvalidateRect函数要求系统重新绘制小方格所对应的区域
在WM_PAINT消息中,对所有的小方格进行循环遍历,先清空每个小方格所对应的范围,然后检查每个小方格的状态fState,如果需要画叉,则沿对角线画一个叉
具体的消息顺序大致是这样的:在窗口启动或窗口大小发生变化的时候,系统产生一个WM_SIZE消息,在这个消息中对小方格的大小进行初始化;然后用户在窗口中点击鼠标左键,产生WM_LBUTTONDOWN消息,在这个消息中计算相应的小方格并更改小方格状态fState,然后要求系统更新窗口,系统收到更新需求后按一定的规则触发WM_PAINT消息,在这个消息中根据小方格的状态绘制小方格