设为首页 加入收藏

TOP

四、程序中的命中测试—子窗口和键盘
2012-11-05 12:26:51 】 浏览:478
Tags:程序 命中 测试 窗口 键盘

为CHECKER3添加键盘接口就像CHECKER系列构想中的最后一步。但在这样做的时候,可能有更适当的做法。在CHECKER2中,鼠标光标的位置决定按下Spacebar键时哪个区域将获得标记符号。当我们处理子窗口时,我们能从对话框功能中获得提示。在对话框中,带有闪烁的插入符号或点划的矩形的子窗口表示它有输入焦点(当然也可以用键盘进行定位)。

我们不需要把Windows内部已有的对话框处理方式重新写过,我只是要告诉您大致上应该如何在应用程序中仿真对话框。研究过程中,您会发现这样一件事:父窗口和子窗口可能要共享同键盘消息处理。按下Spacebar键和Enter键时,子窗口将锁定复选标记。按下方向键时,父窗口将在子窗口之间移动输入焦点。实际上,当您在子窗口上单击时,情况会有些复杂,这时是父窗口而不是子窗口获得输入焦点。

CHECKER4.C如程序7-5所示。

程序7-5 CHECKER4
        CHECKER4.C        /*---------------------------------------------------------------------------         CHECKER4.C --   Mouse Hit-Test Demo Program No. 4                                                 (c) Charles Petzold, 1998        ---------------------------------------------------------------------------*/        #include <windows.h>        #define DIVISIONS 5        LRESULT CALLBACK WndProc   (HWND, UINT, WPARAM, LPARAM) ;        LRESULT CALLBACK ChildWndProc (HWND, UINT, WPARAM, LPARAM) ;        int   idFocus = 0 ;        TCHAR szChildClass[] = TEXT ("Checker4_Child") ;        int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,                                                                 PSTR szCmdLine, int iCmdShow)        {                  static TCHAR szAppName[] = TEXT ("Checker4") ;                   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 ("Checker4 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 ;                          // On set-focus message, set focus to child window                   case   WM_SETFOCUS:                          SetFocus (GetDlgItem (hwnd, idFocus)) ;                          return 0 ;                    // On key-down message, possibly change the focus window                   case   WM_KEYDOWN:                          x = idFocus & 0xFF ;                          y = idFocus >> 8 ;                          switch (wParam)                          {               case VK_UP:            y-- ;                                                break ;                    case VK_DOWN:                 y++ ;                                            break ;                    case VK_LEFT:                 x-- ;                                    break ;               case VK_RIGHT:                x++ ;                       break ;               case VK_HOME:                     x = y = 0 ;                          break ;               case VK_END:                      x = y = DIVISIONS - 1 ;          break ;                          default:                                     return 0 ;                          }                          x = (x + DIVISIONS) % DIVISIONS ;                          y = (y + DIVISIONS) % DIVISIONS ;                          idFocus = y << 8 | x ;                          SetFocus (GetDlgItem (hwnd, idFocus)) ;                          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_KEYDOWN:                                          // Send most key presses to the parent window                                          if (wParam != VK_RETURN && wParam != VK_SPACE)                          {                                  SendMessage (GetParent (hwnd), message, wParam, lParam) ;                                  return 0 ;                          }                                         // For Return and Space, fall through to toggle the square                                   case   WM_LBUTTONDOWN :                          SetWindowLong (hwnd, 0, 1 ^ GetWindowLong (hwnd, 0)) ;                          SetFocus (hwnd) ;                          InvalidateRect (hwnd, NULL, FALSE) ;                        return 0 ;                          // For focus messages, invalidate the window for repaint                                   case   WM_SETFOCUS:                          idFocus = GetWindowLong (hwnd, GWL_ID) ;                          // Fall through                   case   WM_KILLFOCUS:                          InvalidateRect (hwnd, NULL, TRUE) ;                          return 0 ;                               case      WM_PAINT :                          hdc = BeginPaint (hwnd, &ps) ;                                          GetClientRect (hwnd, &rect) ;                          Rectangle (hdc, 0, 0, rect.right, rect.bottom) ;                                         // Draw the "x" mark                                         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) ;                          }                                          // Draw the "focus" rectangle                                          if (hwnd == GetFocus ())                          {                                          rect.left   += rect.right / 10 ;                                         rect.right  -= rect.left ;                                          rect.top    += rect.bottom / 10 ;                                          rect.bottom -= rect.top ;                                          SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;                                          SelectObject (hdc, CreatePen (PS_DASH, 0, 0)) ;                                          Rectangle (hdc, rect.left, rect.top, rect.right, rect.bottom) ;                                          DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))) ;                          }                          EndPaint (hwnd, &ps) ;                          return 0 ;                   }                   return DefWindowProc (hwnd, message, wParam, lParam) ;        }        
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇五、Windows拦截鼠标 下一篇四、程序中的命中测试—CHECKER中..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目