ck) ; 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) ; }
CHECKER2中的WM_KEYDOWN的处理方式决定游标的位置(用GetCursorPos),把萤幕座标转换为显示区域座标(用ScreenToClient),并用矩形方块的宽度和高度来除这个座标。这会产生指示矩形位置的x和y值(5×5阵列)。当按下一个键时,滑鼠游标可能在或不在显示区域中,所以x和y必须经过min和max巨集处理以保证它们的范围是0到4之间。
对方向键,CHECKER2近似地增加或减少x和y。如果是Enter键或Spacebar键,那么CHECKER2使用SendMessage把WM_LBUTTONDOWN讯息发送给它自身。这种技术类似于在第六章SYSMETS程式中把键盘介面加到视窗卷动列时所使用的方法。WM_KEYDOWN的处理方式是通过计算指向矩形中心的显示区域座标,再用ClientToScreen转换成萤幕座标,然後用SetCursorPos设定游标位置来实作的。
将子视窗用於命中测试
有些程式(例如,Windows的「画图」程式),把显示区域划分为几个小的逻辑区域。「画图」程式在其左边有一个由图示组成的工具功能表区,在底部有颜色功能表区。在这两个区做命中测试的时候,「画图」必须在使用者选中功能表项之前记住功能表的位置。
不过,也可能不需要这么做。实际上,画风经由使用子视窗简化了功能表的绘制和命中测试。子视窗把整个矩形区域划分为几个更小的矩形区,每个子视窗有自己的视窗代号、视窗讯息处理程式和显示区域,每个视窗讯息处理程式接收只适用於它的子视窗的滑鼠讯息。滑鼠讯息中的lP |