设为首页 加入收藏

TOP

三、Windows键盘消息和字符集
2012-11-05 12:25:53 】 浏览:451
Tags:Windows 键盘 消息 字符集

本章剩下的范例程序有缺陷。它们不能在所有版本的Windows下都正常执行。这些缺陷不是特意引过程序代码中的;事实上,您也许永远不会遇到这些缺陷。只有在不同的键盘语言和键盘布局间切换,以及在多字节字符集的远东版Windows下执行程序时,这些问题才会出现-所以我不愿将它们称为「错误」。

不过,如果程序使用Unicode编译并在Windows NT下执行,那么程序会执行得更好。我在第二章提到过这个问题,并且展示了Unicode对简化棘手的国际化问题的重要性。

KEYVIEW1程序

了解键盘国际化问题的第一步,就是检查Windows传递给窗口消息处理程序的键盘内容和字符消息。程序6-2所示的KEYVIEW1会对此有所帮助。该程序在显示区域显示Windows向窗口消息处理程序发送的8种不同键盘消息的全部信息。

程序6-2 KEYVIEW1
        KEYVIEW1.C        /*---------------------------------------------------------------------            KEYVIEW1.C --Displays Keyboard and Character Messages                                          (c) Charles Petzold, 1998        ---------------------------------------------------------------------*/        #include <windows.h>        LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;        int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,                                           PSTR szCmdLine, int iCmdShow)        {            static TCHAR szAppName[]      = TEXT ("KeyView1") ;            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 ("This program requires Windows NT!"),                                                  szAppName, MB_ICONERROR) ;                    return 0 ;            }                      hwnd = CreateWindow (szAppName, TEXT ("Keyboard Message Viewer #1"),                                                          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 int   cxClientMax, cyClientMax, cxClient, cyClient, cxChar, cyChar ;            static int   cLinesMax, cLines ;            static PMSG  pmsg ;            static RECT  rectScroll ;            static TCHAR szTop[] = TEXT ("Message Key  Char ")                                                                  TEXT ("Repeat Scan Ext ALT Prev Tran") ;            static TCHAR szUnd[] = TEXT ("_______        ___       ____     ")                                                                  TEXT ("______ ____ ___ ___ ____ ____") ;            static TCHAR * szFormat[2] = {                                   TEXT ("%-13s %3d %-15s%c%6u %4d %3s %3s %4s %4s"),                                   TEXT ("%-13s  0x%04X%1s%c %6u %4d %3s %3s %4s %4s") } ;                    static TCHAR * szYes  = TEXT ("Yes") ;                    static TCHAR * szNo   = TEXT ("No") ;                    static TCHAR * szDown = TEXT ("Down") ;                    static TCHAR * szUp   = TEXT ("Up") ;                    static TCHAR * szMessage [] = {                    TEXT ("WM_KEYDOWN"),  TEXT ("WM_KEYUP"),                    TEXT ("WM_CHAR"),     TEXT ("WM_DEADCHAR"),                    TEXT ("WM_SYSKEYDOWN"),TEXT ("WM_SYSKEYUP"),                    TEXT ("WM_SYSCHAR"),  TEXT ("WM_SYSDEADCHAR") } ;                    HDC                   hdc ;                    int                   i, iType ;                    PAINTSTRUCT           ps ;                    TCHAR                 szBuffer[128], szKeyName [32] ;                    TEXTMETRIC            tm ;                      switch (message)            {            case WM_CREATE:            case WM_DISPLAYCHANGE:                                   // Get maximum size of client area                    cxClientMax = GetSystemMetrics (SM_CXMAXIMIZED) ;                    cyClientMax = GetSystemMetrics (SM_CYMAXIMIZED) ;                                   // Get character size for fixed-pitch font                    hdc = GetDC (hwnd) ;                    SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;                    GetTextMetrics (hdc, &tm) ;                    cxChar = tm.tmAveCharWidth ;                    cyChar = tm.tmHeight ;                    ReleaseDC (hwnd, hdc) ;                                   // Allocate memory for display lines                    if (pmsg)                           free (pmsg) ;                           cLinesMax = cyClientMax / cyChar ;                           pmsg = malloc (cLinesMax * sizeof (MSG)) ;                           cLines = 0 ;                           // fall through            case WM_SIZE:                    if (message == WM_SIZE)                    {                           cxClient = LOWORD (lParam) ;                           cyClient = HIWORD (lParam) ;                    }                                           // Calculate scrolling rectangle                    rectScroll.left       = 0 ;                    rectScroll.right      = cxClient ;                    rectScroll.top        = cyChar ;                    rectScroll.bottom     = cyChar * (cyClient / cyChar) ;                    InvalidateRect (hwnd, NULL, TRUE) ;                    return 0 ;                            case WM_KEYDOWN:            case WM_KEYUP:            case WM_CHAR:            case WM_DEADCHAR:            case WM_SYSKEYDOWN:            case WM_SYSKEYUP:            case WM_SYSCHAR:            case WM_SYSDEADCHAR:                                           // Rearrange storage array                    for (i = cLinesMax - 1 ; i > 0 ; i--)                    {                                   pmsg[i] = pmsg[i - 1] ;                    }                                           // Store new message                    pmsg[0].hwnd = hwnd ;                    pmsg[0].message = message ;                    pmsg[0].wParam = wParam ;                    pmsg[0].lParam = lParam ;                    cLines = min (cLines + 1, cLinesMax) ;                                           // Scroll up the display                    ScrollWindow (hwnd, 0, -cyChar, &rectScroll, &rectScroll) ;                    break ;               // i.e., call DefWindowProc so Sys messages work            case WM_PAINT:                    hdc = BeginPaint (hwnd, &ps) ;                    SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT)) ;                    SetBkMode (hdc, TRANSPARENT) ;                    TextOut (hdc, 0, 0, szTop, lstrlen (szTop)) ;                    TextOut (hdc, 0, 0, szUnd, lstrlen (szUnd)) ;                    for (i = 0 ; i < min (cLines, cyClient / cyChar - 1) ; i++)                    {                           iType =       pmsg[i].message == WM_CHAR ||                                           pmsg[i].message == WM_SYSCHAR ||                                           pmsg[i].message == WM_DEADCHAR ||                                           pmsg[i].message == WM_SYSDEADCHAR ;                           GetKeyNameText (pmsg[i].lParam, szKeyName,                                                  sizeof (szKeyName) / sizeof (TCHAR)) ;                    TextOut (hdc, 0, (cyClient / cyChar - 1 - i) * cyChar, szBuffer,                    wsprintf (szBuffer, szFormat [iType],                    szMessage [pmsg[i].message - WM_KEYFIRST],                    pmsg[i].wParam,                    (PTSTR) (iType   TEXT (" ") : szKeyName),                    (TCHAR) (iType   pmsg[i].wParam : ' '),                    LOWORD (pmsg[i].lParam),                    HIWORD (pmsg[i].lParam) & 0xFF,                                   0x01000000 & pmsg[i].lParam   szYes  : szNo,                                   0x20000000 & pmsg[i].lParam   szYes  : szNo,                                   0x40000000 & pmsg[i].lParam   szDown : szUp,                                   0x80000000 & pmsg[i].lParam   szUp   : szDown)) ;                    }                    EndPaint (hwnd, &ps) ;                    return 0 ;            case   WM_DESTROY:                    PostQuitMessage (0) ;                    return 0 ;            }            return DefWindowProc (hwnd, message, wParam, lParam) ;        }        
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇三、Windows键盘消息和字符集—外.. 下一篇三、Windows字符消息

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目