• Win32 键盘事件


    注:以下内容为学习笔记,多数是从书本、资料中得来,只为加深印象,及日后参考。然而本人表达能力较差,写的不好。因非翻译、非转载,只好选原创,但多数乃摘抄,实为惭愧。但若能帮助一二访客,幸甚!

    以下内容主要来自《Windows 程序设计》

    1.焦点

    程序用于从消息队列中读取消息的MSG结构中包含一个hwnd字段。此字段指出了接收消息的窗口句柄。消息循环中的DispatchMessage函数传送消息给需要该消息的窗口过程。

    接收到这个键盘事件的窗口称为有输入焦点的窗口。

    有时没有窗口具有输入焦点。这种情况发生在所以程序都最小化时。

    窗口过程通过捕获WM_SETFOCUS和WM_KILLFOCUS消息来确定自己的窗口是否具有输入焦点。

    2.队列和同步

    当用户按下和释放键盘上的一个键时,Windows和键盘设备驱动程序将硬件扫描码转换为格式化后的消息。但是这些消息并不立即被放入应用程序消息队列,而是由Windows把这些消息存储在系统消息队列中。系统消息队列是一个单独的消息队列,它被Windows用来初步存储用户从键盘和鼠标输入的消息。仅当Windows应用程序完成了对当前一个用户输入消息的处理后,Windows才从系统消息队列中取出下一条消息,并把它放入应用程序消息队列。

    3.击键消息

    当用户按下一个键时,Windows将WM_KEYDOWN或WM_SYSKEYDOWN消息放入具有输入焦点的消息队列中。当该键被释放时,Windows把WM_KEYUP或WM_SYSKEYUP消息放入相应的消息队列中。其中SYS代表系统,它表明该击键对Windows比对应用程序更加重要。

    虚拟键代码存储在WM_KEYDOWN等消息的wParam参数中,确定哪个键被按下或被释放。

    当处理击键消息时,可能需要知道是否有转义键(Shift、Ctrl和Alt)或切换键(Caps Lock、Num Lock和Scroll Lock)键被按下。

    可以用如下方式:

    iState = GetKeyState(VK_SHIFT);

    给前面的SYSMETS代码(http://blog.csdn.net/guzhou_diaoke/article/details/8155740   7.滚动条)中添加键盘处理功能:

    简单方法:为窗口过程增加WM_KEYDOWN逻辑

    更好的方法:把每一个WM_KEYDOWN消息转换为等同的WM_VSCROLL或WM_HSCROLL消息。可以使用:

    SendMessage(hwnd, message, wParam, lParam);

    当你调用SendMessage函数时,Windows调用窗口句柄hwnd的窗口过程,同时把四个函数变量传递给他。当窗口过程处理完此消息,Windows把控制权还给紧跟着SendMessage调用的下一条语句。

    [cpp] view plain copy
     
     print?
    1. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
    2. {  
    3.     // cxChar平均字符宽度,cyChar字符的总高度(包括外部间距),cxCaps大写字符的平均宽度  
    4.     // 等宽字体中,cxCaps等于cxChar,变宽字体中,cxCaps等于cxChar的1.5倍  
    5.     static int  cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth, iVscrollPos;   
    6.     HDC         hdc;  
    7.     int         i, x, y, iVertPos, iHorzPos, iPaintBeg, iPaintEnd;  
    8.     PAINTSTRUCT ps;  
    9.     SCROLLINFO  si;  
    10.     TCHAR       szBuffer[10];  
    11.     TEXTMETRIC  tm;   
    12.   
    13.     switch (message)  
    14.     {  
    15.     case WM_CREATE:  
    16.         hdc = GetDC(hwnd);  
    17.           
    18.         GetTextMetrics(hdc, &tm);       // 获取系统默认字体的尺寸  
    19.         cxChar = tm.tmAveCharWidth;  
    20.         // tmPitchAndFamily为1表示变宽字体,为0表示等宽字体  
    21.         cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;  
    22.         cyChar = tm.tmHeight + tm.tmExternalLeading;  
    23.   
    24.         ReleaseDC(hwnd, hdc);  
    25.   
    26.         iMaxWidth = 40*cxChar + 22*cxCaps;  
    27.         return 0;  
    28.   
    29.     case WM_SIZE:  
    30.         cxClient = LOWORD(lParam);  
    31.         cyClient = HIWORD(lParam);  
    32.           
    33.         si.cbSize   = sizeof(si);  
    34.         si.fMask    = SIF_RANGE | SIF_PAGE;  
    35.   
    36.         si.nMin     = 0;  
    37.         si.nMax     = NUMLINES-1;  
    38.         si.nPage    = cyClient / cyChar;  
    39.         SetScrollInfo(hwnd, SB_VERT, &si, TRUE);  
    40.   
    41.         si.cbSize   = sizeof(si);  
    42.         si.fMask    = SIF_RANGE | SIF_PAGE;  
    43.   
    44.         si.nMin     = 0;  
    45.         si.nMax     = 2 + iMaxWidth/cxChar;  
    46.         si.nPage    = cxClient / cxChar;  
    47.         SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);  
    48.   
    49.         return 0;  
    50.           
    51.     case WM_VSCROLL:  
    52.         si.cbSize   = sizeof(si);  
    53.         si.fMask    = SIF_ALL;  
    54.   
    55.         GetScrollInfo(hwnd, SB_VERT, &si);  
    56.         iVertPos = si.nPos;  
    57.   
    58.         switch (LOWORD(wParam))  
    59.         {  
    60.         case SB_TOP:  
    61.             si.nPos = si.nMin;  
    62.             break;  
    63.   
    64.         case SB_BOTTOM:  
    65.             si.nPos = si.nMax;  
    66.             break;  
    67.   
    68.         case SB_LINEUP:  
    69.             si.nPos -= 1;  
    70.             break;  
    71.   
    72.         case SB_LINEDOWN:  
    73.             si.nPos += 1;  
    74.             break;  
    75.   
    76.         case SB_PAGEUP:  
    77.             si.nPos -= si.nPage;  
    78.             break;  
    79.   
    80.         case SB_PAGEDOWN:  
    81.             si.nPos += si.nPage;  
    82.             break;  
    83.   
    84.         case SB_THUMBTRACK:  
    85.             si.nPos = si.nTrackPos;  
    86.             break;  
    87.   
    88.         default:  
    89.             break;  
    90.         }  
    91.   
    92.         si.fMask = SIF_POS;  
    93.         SetScrollInfo(hwnd, SB_VERT, &si, TRUE);  
    94.         GetScrollInfo(hwnd, SB_VERT, &si);  
    95.   
    96.         if (si.nPos != iVertPos)  
    97.         {  
    98.             ScrollWindow(hwnd, 0, cyChar*(iVertPos-si.nPos), NULL, NULL);  
    99.             UpdateWindow(hwnd);  
    100.         }  
    101.         return 0;  
    102.   
    103.     case WM_HSCROLL:  
    104.         si.cbSize   = sizeof(si);  
    105.         si.fMask    = SIF_ALL;  
    106.   
    107.         GetScrollInfo(hwnd, SB_HORZ, &si);  
    108.         iHorzPos = si.nPos;  
    109.   
    110.         switch (LOWORD(wParam))  
    111.         {  
    112.         case SB_LINELEFT:  
    113.             si.nPos -= 1;  
    114.             break;  
    115.   
    116.         case SB_LINERIGHT:  
    117.             si.nPos += 1;  
    118.             break;  
    119.   
    120.         case SB_PAGELEFT:  
    121.             si.nPos -= si.nPage;  
    122.             break;  
    123.   
    124.         case SB_PAGERIGHT:  
    125.             si.nPos += si.nPage;  
    126.             break;  
    127.   
    128.         case SB_THUMBPOSITION:  
    129.             si.nPos = si.nTrackPos;  
    130.             break;  
    131.   
    132.         default:  
    133.             break;  
    134.         }  
    135.   
    136.         si.fMask = SIF_POS;  
    137.         SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);  
    138.         GetScrollInfo(hwnd, SB_HORZ, &si);  
    139.   
    140.         if (si.nPos != iHorzPos)  
    141.         {  
    142.             ScrollWindow(hwnd, cxChar*(iHorzPos-si.nPos), 0, NULL, NULL);  
    143.             UpdateWindow(hwnd);  
    144.         }  
    145.         return 0;  
    146.   
    147.     case WM_KEYDOWN:  
    148.         switch (wParam)  
    149.         {  
    150.         case VK_HOME:  
    151.             SendMessage(hwnd, WM_VSCROLL, SB_TOP, 0);  
    152.             break;  
    153.   
    154.         case VK_END:  
    155.             SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, 0);  
    156.             break;  
    157.   
    158.         case VK_PRIOR:  
    159.             SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, 0);  
    160.             break;  
    161.   
    162.         case VK_NEXT:  
    163.             SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, 0);  
    164.             break;  
    165.   
    166.         case VK_UP:  
    167.             SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0);  
    168.             break;  
    169.   
    170.         case VK_DOWN:  
    171.             SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);  
    172.             break;  
    173.   
    174.         case VK_LEFT:  
    175.             SendMessage(hwnd, WM_HSCROLL, SB_PAGEUP, 0);  
    176.             break;  
    177.   
    178.         case VK_RIGHT:  
    179.             SendMessage(hwnd, WM_HSCROLL, SB_PAGEDOWN, 0);  
    180.             break;  
    181.         }  
    182.         return 0;  
    183.   
    184.     case WM_PAINT:  
    185.         hdc = BeginPaint(hwnd, &ps);  
    186.   
    187.         si.cbSize = sizeof(si);  
    188.         si.fMask = SIF_POS;  
    189.           
    190.         GetScrollInfo(hwnd, SB_VERT, &si);  
    191.         iVertPos = si.nPos;  
    192.   
    193.         GetScrollInfo(hwnd, SB_HORZ, &si);  
    194.         iHorzPos = si.nPos;  
    195.   
    196.         iPaintBeg = max(0, iVertPos + ps.rcPaint.top/cyChar);  
    197.         iPaintEnd = min(NUMLINES-1, iVertPos + ps.rcPaint.bottom/cyChar);  
    198.   
    199.         for (i = iPaintBeg; i <= iPaintEnd; i++)  
    200.         {  
    201.             x = cxChar * (1-iHorzPos);  
    202.             y = cyChar * (i-iVertPos);  
    203.   
    204.             TextOut(hdc, x, y, sysmetrics[i].szLabel, lstrlen(sysmetrics[i].szLabel));  
    205.   
    206.             TextOut(hdc, x + 22*cxCaps, y, sysmetrics[i].szDesc, lstrlen(sysmetrics[i].szDesc));  
    207.   
    208.             SetTextAlign(hdc, TA_RIGHT | TA_TOP);  
    209.   
    210.             TextOut(hdc, x + 22*cxCaps + 40*cxChar, y, szBuffer, wsprintf(szBuffer, TEXT("%5d"),   
    211.                 GetSystemMetrics(sysmetrics[i].iIndex)));  
    212.   
    213.             // 将对齐方式设回正常方式  
    214.             SetTextAlign(hdc, TA_LEFT | TA_TOP);  
    215.         }  
    216.   
    217.         EndPaint(hwnd, &ps);  
    218.         return 0;  
    219.   
    220.     case WM_DESTROY:  
    221.         PostQuitMessage(0);  
    222.         return 0;  
    223.     }  
    224.   
    225.     return DefWindowProc(hwnd, message, wParam, lParam);  
    226. }  

    有键盘了,就差鼠标了~很快会有的。

    4.字符消息

    通过转义状态信息可把击键消息转换为字符消息。

    GetMessage从消息队列中取出下一条消息;

    TranslateMessage负责把击键消息转换为字符消息;

    DispatchMessage调用此消息的窗口过程。

    5.消息排序

    假如Caps Lock没有锁定,按下再释放A,相应窗口过程会接收:

    1)WM_KEYDOWN:’A‘ 的虚拟键代码(0x41)

    2)WM_CHAR:  'a'的字符编码(0x61)

    3)WM_KEYUP: 'A' 的虚拟键代码(0x41)

    按下Shift+A,释放A,再释放Shift:

    1)WM_KEYDOWN:虚拟键代码VK_SHIFT(0x10)

    2)WM_KEYDOWN:’A‘ 的虚拟键代码(0x41)

    3)WM_CHAR:  'A' 的字符编码(0x41)

    4)WM_KEYUP: 'A' 的虚拟键代码(0x41)

    5)WM_UP:虚拟键代码VK_SHIFT(0x10)

    连续按住A:

    1)WM_KEYDOWN:’A‘ 的虚拟键代码(0x41)

    2)WM_CHAR:  'a'的字符编码(0x61)

    3)WM_KEYDOWN:’A‘ 的虚拟键代码(0x41)

    4)WM_CHAR:  'a'的字符编码(0x61)

    ……

    n)WM_KEYUP: 'A' 的虚拟键代码(0x41)


    6.控制字符的处理

    按照以下基本规则来处理击键和字符消息:如果你需要读取输入到窗口中的键盘字符,就处理WM_CHAR消息;如果你需要读取光标键、功能键、Delete键、Insert键、Shift键、Ctrl键和Alt键,则处理WM_KEYDOWN消息。

    [cpp] view plain copy
     
     print?
    1. /*--------------------------------------------------------------------------- 
    2.     keyView.cpp -- Displays keyboard and character messages 
    3. ----------------------------------------------------------------------------*/  
    4.   
    5. /*----------------------------------------------------------------------------------- 
    6.     SysMets4.cpp -- System Metrics Display Program ver4 use keyboard 
    7.  *----------------------------------------------------------------------------------*/  
    8.   
    9. #include <windows.h>  
    10.   
    11. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  
    12.   
    13. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)  
    14. {  
    15.     static TCHAR    szAppName[] = TEXT("KeyView1");  
    16.     HWND            hwnd;  
    17.     MSG             msg;  
    18.     WNDCLASS        wndclass;  
    19.   
    20.     wndclass.style          = CS_HREDRAW | CS_VREDRAW;  
    21.     wndclass.lpfnWndProc    = WndProc;  
    22.     wndclass.cbClsExtra     = 0;  
    23.     wndclass.cbWndExtra     = 0;  
    24.     wndclass.hInstance      = hInstance;  
    25.     wndclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);  
    26.     wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);  
    27.     wndclass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);  
    28.     wndclass.lpszMenuName   = NULL;  
    29.     wndclass.lpszClassName  = szAppName;  
    30.   
    31.     if (!RegisterClass(&wndclass))  
    32.     {  
    33.         MessageBox(NULL, TEXT("This program requires windows NT!"), szAppName, MB_ICONERROR);  
    34.         return 0;  
    35.     }  
    36.   
    37.     hwnd = CreateWindow(szAppName,                                      // window class name  
    38.                         TEXT("Keyboard Message Viewer #1"),             // window caption  
    39.                         WS_OVERLAPPEDWINDOW,                            // window style  
    40.                         CW_USEDEFAULT,                                  // initial x position  
    41.                         CW_USEDEFAULT,                                  // initial y position  
    42.                         CW_USEDEFAULT,                                  // initial x size  
    43.                         CW_USEDEFAULT,                                  // initial y size  
    44.                         NULL,                                           // parent window handle  
    45.                         NULL,                                           // window menu handle  
    46.                         hInstance,                                      // program instance handle  
    47.                         NULL);                                          // creation parameters  
    48.   
    49.     ShowWindow(hwnd, iCmdShow);  
    50.     UpdateWindow(hwnd);  
    51.   
    52.     while (GetMessage(&msg, NULL, 0, 0))  
    53.     {  
    54.         TranslateMessage(&msg);  
    55.         DispatchMessage(&msg);  
    56.     }  
    57.   
    58.     return msg.wParam;  
    59. }  
    60.   
    61. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
    62. {  
    63.     // cxChar平均字符宽度,cyChar字符的总高度(包括外部间距),cxCaps大写字符的平均宽度  
    64.     // 等宽字体中,cxCaps等于cxChar,变宽字体中,cxCaps等于cxChar的1.5倍  
    65.     static int      cxChar, cyChar, cxClient, cyClient, cxClientMax, cyClientMax;  
    66.     static int      cLinesMax, cLines;  
    67.     static PMSG     pmsg;  
    68.     static RECT     rectScroll;  
    69.     static TCHAR szTop[] = TEXT ("Message        Key       Char     ")  
    70.                             TEXT ("Repeat Scan Ext ALT Prev Tran") ;  
    71.      static TCHAR szUnd[] = TEXT ("_______        ___       ____     ")  
    72.                             TEXT ("______ ____ ___ ___ ____ ____") ;  
    73.   
    74.     static TCHAR*   szFormat[2] = {  
    75.         TEXT("%-13s %3d %-15s%c%6u %4d %3s %3s %4s %4s"),  
    76.         TEXT("%-13s            0x%04X%1s%c %6u %4d %3s %3s %4s %4s") };  
    77.     static TCHAR*   szYes   = TEXT("Yes");  
    78.     static TCHAR*   szNo    = TEXT("No");  
    79.     static TCHAR*   szDown  = TEXT("Down");  
    80.     static TCHAR*   szUp    = TEXT("Up");  
    81.   
    82.     static TCHAR*   szMessage[] = {  
    83.         TEXT("WM_KEYDOWN"),     TEXT("WM_KEYUP"),  
    84.         TEXT("WM_CHAR"),        TEXT("WM_DEADCHAR"),  
    85.         TEXT("WM_SYSKEYDOWN"),  TEXT("WM_SYSKEYUP"),  
    86.         TEXT("WM_SYSCHAR"),     TEXT("WM_SYSDEADCHAR") };  
    87.   
    88.     HDC         hdc;  
    89.     int         i, iType;  
    90.     PAINTSTRUCT ps;  
    91.     TCHAR       szBuffer[128], szKeyName[32];  
    92.     TEXTMETRIC  tm;   
    93.   
    94.     switch (message)  
    95.     {  
    96.     case WM_CREATE:  
    97.     case WM_DISPLAYCHANGE:  
    98.         cxClientMax = GetSystemMetrics(SM_CXMAXIMIZED);  
    99.         cyClientMax = GetSystemMetrics(SM_CYMAXIMIZED);  
    100.   
    101.         hdc = GetDC(hwnd);  
    102.           
    103.         SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));  
    104.         GetTextMetrics(hdc, &tm);       // 获取系统默认字体的尺寸  
    105.         cxChar = tm.tmAveCharWidth;  
    106.         cyChar = tm.tmHeight;  
    107.   
    108.         ReleaseDC(hwnd, hdc);  
    109.   
    110.         if (pmsg)  
    111.             free(pmsg);  
    112.   
    113.         cLinesMax = cyClientMax / cyChar;  
    114.         pmsg = (PMSG)malloc(cLinesMax * sizeof(MSG));  
    115.         cLines = 0;  
    116.   
    117.         //return 0;  
    118.   
    119.     case WM_SIZE:  
    120.         if (message == WM_SIZE)  
    121.         {  
    122.             cxClient = LOWORD(lParam);  
    123.             cyClient = HIWORD(lParam);  
    124.         }  
    125.           
    126.         rectScroll.left     = 0;  
    127.         rectScroll.right    = cxClient;  
    128.         rectScroll.top      = cyChar;  
    129.         rectScroll.bottom   = cyChar * (cyClient / cyChar);  
    130.   
    131.         InvalidateRect(hwnd, NULL, TRUE);  
    132.   
    133.         return 0;  
    134.           
    135.     case WM_KEYDOWN:  
    136.     case WM_KEYUP:  
    137.     case WM_CHAR:  
    138.     case WM_DEADCHAR:  
    139.     case WM_SYSKEYDOWN:  
    140.     case WM_SYSKEYUP:  
    141.     case WM_SYSCHAR:  
    142.     case WM_SYSDEADCHAR:  
    143.         for (i = cLinesMax-1; i > 0; i--)  
    144.         {  
    145.             pmsg[i] = pmsg[i-1];  
    146.         }  
    147.   
    148.         pmsg[0].hwnd    = hwnd;  
    149.         pmsg[0].message = message;  
    150.         pmsg[0].wParam  = wParam;  
    151.         pmsg[0].lParam  = lParam;  
    152.   
    153.         cLines = min(cLines + 1, cLinesMax);  
    154.   
    155.         ScrollWindow(hwnd, 0, -cyChar, &rectScroll, &rectScroll);  
    156.         break;  
    157.       
    158.   
    159.     case WM_PAINT:  
    160.         hdc = BeginPaint(hwnd, &ps);  
    161.   
    162.         SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));  
    163.         SetBkMode(hdc, TRANSPARENT);  
    164.         TextOut(hdc, 0, 0, szTop, lstrlen(szTop));  
    165.         TextOut(hdc, 0, 0, szUnd, lstrlen(szUnd));  
    166.   
    167.         for (i = 0; i < min(cLines, cyClient / cyChar - 1); i++)  
    168.         {  
    169.             iType = pmsg[i].message == WM_CHAR ||  
    170.                     pmsg[i].message == WM_SYSCHAR ||  
    171.                     pmsg[i].message == WM_DEADCHAR ||  
    172.                     pmsg[i].message == WM_SYSDEADCHAR;  
    173.   
    174.             GetKeyNameText(pmsg[i].lParam, szKeyName, sizeof(szKeyName) / sizeof(TCHAR));  
    175.   
    176.             TextOut(hdc, 0, (cyClient/cyChar - 1 - i) * cyChar, szBuffer,   
    177.                 wsprintf(szBuffer, szFormat[iType],  
    178.                     szMessage[pmsg[i].message - WM_KEYFIRST],  
    179.                     pmsg[i].wParam,  
    180.                     (PTSTR)(iType ? TEXT(" ") : szKeyName),  
    181.                     (TCHAR)(iType ? pmsg[i].wParam: ' '),  
    182.                     LOWORD(pmsg[i].lParam),  
    183.                     HIWORD(pmsg[i].lParam) & 0xFF,  
    184.                     0x01000000 & pmsg[i].lParam ? szYes : szNo,  
    185.                     0x20000000 & pmsg[i].lParam ? szYes : szNo,  
    186.                     0x40000000 & pmsg[i].lParam ? szDown: szUp,  
    187.                     0x80000000 & pmsg[i].lParam ? szUp  : szDown));  
    188.         }  
    189.   
    190.         EndPaint(hwnd, &ps);  
    191.         return 0;  
    192.   
    193.     case WM_DESTROY:  
    194.         PostQuitMessage(0);  
    195.         return 0;  
    196.     }  
    197.   
    198.     return DefWindowProc(hwnd, message, wParam, lParam);  
    199. }  


    7.插入符号(就是平时说的光标)

    插入符号指明你输入的下一个字符将出现在屏幕上的位置。

    相关函数:

    CreateCaret:创建和窗口关联的插入符号

    SetCaretPos:设置窗口内的插入符号的位置

    ShowCaret:显式插入符号

    HideCaret:隐藏插入符号

    DestroyCaret:销毁插入符号

    GetCaretPos:获取插入符号位置

    GetCaretBlinkTime、SetCaretBlinkTime:获取、设置插入符号闪烁时间

    使用插入符号主要规则:在窗口过程处理WM_SETFOCUS消息时调用CreateCaret,处理WM_KILLFOCUS消息时调用DestroyCaret函数。

    创建的插入符号是隐藏的,必须调用ShowCaret使之可见。

    要在窗口内绘制某些东西时,它必须调用HideCaret隐藏插入符号。结束绘制后,再调用ShowCaret显式插入符号。

    HideCaret效果是叠加的。

    一个简单的文本编辑器雏形:

    [cpp] view plain copy
     
     print?
    1. /*---------------------------------------------------------------------------- 
    2.     typer.cpp -- Typing Program 
    3. ----------------------------------------------------------------------------*/  
    4.   
    5. /*--------------------------------------------------------------------------- 
    6.     keyView.cpp -- Displays keyboard and character messages 
    7. ----------------------------------------------------------------------------*/  
    8.   
    9. /*----------------------------------------------------------------------------------- 
    10.     SysMets4.cpp -- System Metrics Display Program ver4 use keyboard 
    11.  *----------------------------------------------------------------------------------*/  
    12.   
    13. #include <windows.h>  
    14.   
    15. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);  
    16.   
    17. #define BUFFER(x, y)    *(pBuffer + y*cxBuffer + x)  
    18.   
    19. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)  
    20. {  
    21.     static TCHAR    szAppName[] = TEXT("Typer");  
    22.     HWND            hwnd;  
    23.     MSG             msg;  
    24.     WNDCLASS        wndclass;  
    25.   
    26.     wndclass.style          = CS_HREDRAW | CS_VREDRAW;  
    27.     wndclass.lpfnWndProc    = WndProc;  
    28.     wndclass.cbClsExtra     = 0;  
    29.     wndclass.cbWndExtra     = 0;  
    30.     wndclass.hInstance      = hInstance;  
    31.     wndclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);  
    32.     wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);  
    33.     wndclass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);  
    34.     wndclass.lpszMenuName   = NULL;  
    35.     wndclass.lpszClassName  = szAppName;  
    36.   
    37.     if (!RegisterClass(&wndclass))  
    38.     {  
    39.         MessageBox(NULL, TEXT("This program requires windows NT!"), szAppName, MB_ICONERROR);  
    40.         return 0;  
    41.     }  
    42.   
    43.     hwnd = CreateWindow(szAppName,                                      // window class name  
    44.                         TEXT("Typer"),                                  // window caption  
    45.                         WS_OVERLAPPEDWINDOW,                            // window style  
    46.                         CW_USEDEFAULT,                                  // initial x position  
    47.                         CW_USEDEFAULT,                                  // initial y position  
    48.                         CW_USEDEFAULT,                                  // initial x size  
    49.                         CW_USEDEFAULT,                                  // initial y size  
    50.                         NULL,                                           // parent window handle  
    51.                         NULL,                                           // window menu handle  
    52.                         hInstance,                                      // program instance handle  
    53.                         NULL);                                          // creation parameters  
    54.   
    55.     ShowWindow(hwnd, iCmdShow);  
    56.     UpdateWindow(hwnd);  
    57.   
    58.     while (GetMessage(&msg, NULL, 0, 0))  
    59.     {  
    60.         TranslateMessage(&msg);  
    61.         DispatchMessage(&msg);  
    62.     }  
    63.   
    64.     return msg.wParam;  
    65. }  
    66.   
    67. LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
    68. {  
    69.     static DWORD    dwCharSet = DEFAULT_CHARSET;  
    70.     static int      cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer, xCaret, yCaret;  
    71.     static TCHAR*   pBuffer = NULL;  
    72.   
    73.     int             x, y, i;  
    74.     HDC             hdc;  
    75.     PAINTSTRUCT     ps;  
    76.     TEXTMETRIC      tm;   
    77.   
    78.     switch (message)  
    79.     {  
    80.     case WM_INPUTLANGCHANGE:  
    81.         dwCharSet = wParam;  
    82.   
    83.     case WM_CREATE:  
    84.         hdc = GetDC(hwnd);  
    85.           
    86.         SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));  
    87.         GetTextMetrics(hdc, &tm);  
    88.         cxChar = tm.tmAveCharWidth;  
    89.         cyChar = tm.tmHeight;  
    90.           
    91.         DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));  
    92.         ReleaseDC(hwnd, hdc);  
    93.   
    94.     case WM_SIZE:  
    95.         if (message == WM_SIZE)  
    96.         {  
    97.             cxClient = LOWORD(lParam);  
    98.             cyClient = HIWORD(lParam);  
    99.         }  
    100.           
    101.         cxBuffer = max(1, cxClient/cxChar);  
    102.         cyBuffer = max(1, cyClient/cyChar);  
    103.   
    104.         if (pBuffer != NULL)  
    105.             free(pBuffer);  
    106.   
    107.         pBuffer = (TCHAR *)malloc(sizeof(TCHAR) * cxBuffer * cyBuffer);  
    108.   
    109.         for (y = 0; y < cyBuffer; y++)  
    110.             for (x = 0; x < cxBuffer; x++)  
    111.                 BUFFER(x, y) = ' ';  
    112.   
    113.         xCaret = 0;  
    114.         yCaret = 0;  
    115.   
    116.         if (hwnd == GetFocus())  
    117.             SetCaretPos(xCaret * cxChar, yCaret * cyChar);  
    118.   
    119.         InvalidateRect(hwnd, NULL, TRUE);  
    120.         return 0;  
    121.   
    122.     case WM_SETFOCUS:  
    123.         CreateCaret(hwnd, NULL, cxChar, cyChar);  
    124.         SetCaretPos(xCaret*cxChar, yCaret*cyChar);  
    125.         ShowCaret(hwnd);  
    126.         return 0;  
    127.   
    128.     case WM_KILLFOCUS:  
    129.         HideCaret(hwnd);  
    130.         DestroyCaret();  
    131.         return 0;  
    132.           
    133.     case WM_KEYDOWN:  
    134.         switch (wParam)  
    135.         {  
    136.         case VK_HOME:  
    137.             xCaret = 0;  
    138.             break;  
    139.   
    140.         case VK_END:  
    141.             xCaret = cxBuffer - 1;  
    142.             break;  
    143.   
    144.         case VK_PRIOR:  
    145.             yCaret = 0;  
    146.             break;  
    147.   
    148.         case VK_NEXT:  
    149.             yCaret = cyBuffer - 1;  
    150.             break;  
    151.   
    152.         case VK_LEFT:  
    153.             xCaret = max(xCaret-1, 0);  
    154.             break;  
    155.   
    156.         case VK_RIGHT:  
    157.             xCaret = min(xCaret+1, cxBuffer-1);  
    158.             break;  
    159.   
    160.         case VK_UP:  
    161.             yCaret = max(yCaret-1, 0);  
    162.             break;  
    163.   
    164.         case VK_DOWN:  
    165.             yCaret = min(yCaret+1, cyBuffer-1);  
    166.             break;  
    167.   
    168.         case VK_DELETE:  
    169.             for (x = xCaret; x < cxBuffer-1; x++)  
    170.                 BUFFER(x, yCaret) = BUFFER(x+1, yCaret);  
    171.             BUFFER(cxBuffer-1, yCaret) = ' ';  
    172.   
    173.             HideCaret(hwnd);  
    174.   
    175.             hdc = GetDC(hwnd);  
    176.   
    177.             SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));  
    178.   
    179.             TextOut(hdc, xCaret*cxChar, yCaret*cyChar, &BUFFER(xCaret, yCaret), cxBuffer-xCaret);  
    180.   
    181.             DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));  
    182.             ReleaseDC(hwnd, hdc);  
    183.             ShowCaret(hwnd);  
    184.             break;  
    185.         }  
    186.         SetCaretPos(xCaret*cxChar, yCaret*cyChar);  
    187.         return 0;  
    188.   
    189.     case WM_CHAR:  
    190.         for (i = 0; i < (int)LOWORD(lParam); i++)  
    191.         {  
    192.             switch (wParam)  
    193.             {  
    194.             case '':          // backspace  
    195.                 if (xCaret > 0)  
    196.                 {  
    197.                     xCaret--;  
    198.                     SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1);  
    199.                 }  
    200.                 break;  
    201.   
    202.             case ' ':          // tab  
    203.                 do  
    204.                 {  
    205.                     SendMessage(hwnd, WM_CHAR, ' ', 1);  
    206.                 }  
    207.                 while (xCaret % 8 != 0);  
    208.                 break;  
    209.   
    210.             case ' ':          // line feed  
    211.                 if (++yCaret == cyBuffer)  
    212.                     yCaret = 0;  
    213.                 break;  
    214.   
    215.             case ' ':          // carriage return  
    216.                 xCaret = 0;  
    217.                 if (++yCaret == cyBuffer)  
    218.                     yCaret = 0;  
    219.                 break;  
    220.   
    221.             case 'x1B':        // escape  
    222.                 for (y = 0; y < cyBuffer; y++)  
    223.                     for (x = 0; x < cxBuffer; x++)  
    224.                         BUFFER(x, y) = ' ';  
    225.   
    226.                 xCaret = 0;  
    227.                 yCaret = 0;  
    228.   
    229.                 InvalidateRect(hwnd, NULL, FALSE);  
    230.                 break;  
    231.   
    232.             default:            // character codes  
    233.                 BUFFER(xCaret, yCaret) = (TCHAR)wParam;  
    234.   
    235.                 HideCaret(hwnd);  
    236.                 hdc = GetDC(hwnd);  
    237.                 SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));  
    238.   
    239.                 TextOut(hdc, xCaret*cxChar, yCaret*cyChar, &BUFFER(xCaret, yCaret), 1);  
    240.   
    241.                 DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));  
    242.                 ReleaseDC(hwnd, hdc);  
    243.                 ShowCaret(hwnd);  
    244.   
    245.                 if (++xCaret == cxBuffer)  
    246.                 {  
    247.                     xCaret = 0;  
    248.                     if (++yCaret == cyBuffer)  
    249.                         yCaret = 0;  
    250.                 }  
    251.                 break;  
    252.             }  
    253.         }  
    254.   
    255.         SetCaretPos(xCaret*cxChar, yCaret*cyChar);  
    256.         return 0;  
    257.   
    258.     case WM_PAINT:  
    259.         hdc = BeginPaint(hwnd, &ps);  
    260.   
    261.         SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));  
    262.           
    263.         for (y = 0; y < cyBuffer; y++)  
    264.             TextOut(hdc, 0, y*cyChar, &BUFFER(0, y), cxBuffer);  
    265.   
    266.         DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));  
    267.   
    268.         EndPaint(hwnd, &ps);  
    269.         return 0;  
    270.   
    271.     case WM_DESTROY:  
    272.         PostQuitMessage(0);  
    273.         return 0;  
    274.     }  
    275.   
    276.     return DefWindowProc(hwnd, message, wParam, lParam);  
    277. }  


     
    http://blog.csdn.net/guzhou_diaoke/article/details/8170366
  • 相关阅读:
    [USACO 5.5]Hidden Password
    [Codeforces 1016F]Road Projects
    再会,OI
    [TJOI 2018]智力竞赛
    [POI 2009]Lyz
    [NOI 2015]品酒大会
    [NOI 2017]蔬菜
    [NOI 2017]整数
    [NOI 2017]游戏
    [NOI 2017]蚯蚓排队
  • 原文地址:https://www.cnblogs.com/findumars/p/7475433.html
Copyright © 2020-2023  润新知