zoukankan      html  css  js  c++  java
  • 09 Windows编程——键盘消息

    焦点窗口:接收到这个键盘事件的窗口称为有输入焦点的窗口。具有输入焦点的窗口要么是活动窗口,要么是活动窗口的子孙窗口。

    活动窗口:活动窗口通常是很好鉴别的。它总是最上层的窗口——也就是说,它的父窗口句柄是NULL。

    系统消息队列 & 应用程序消息队列

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

    应用程序从Windows接收的关于键盘事件的消息可分为击键消息和字符消息两种。对产生可显示字符的击键组合,Windows在发送击键消息的同时还发送字符消息。有些键不产生字符,如Shift键、功能键、光标移动键和特殊字符键(如Insert键和Delete键)。对于这些键,Windows只产生击键消息。

    字符消息

    WM_CHAR,WM_SYSCHAR,WM_DEADCHAR,WM_SYSDEADCHAR

    wParam就是按键字符,TCHAR(wParam)就可以获得这个字符,不要去区分这个字符是ASCII字符或者UNICODE字符,因为TCHAR数据类型已经帮你区分好了!

    一个按键会产生以下4个消息:WM_KEYDOWN,WM_CHAR,WM_KEYUP,WM_DEADCHAR 4个消息。

    击键消息

    通常键按下消息和键释放消息是成对出现的。但是如果你按下一个键不放时,则被认为发生了一次连续按键(自动重复)行为,Windows将发送给窗口过程一连串的WM KEYDOWN(或WMSYSKEYDOWN)消息。当此键最终被释放时,Windows发送给窗口过程一个WMKEYUP(或WMSYSKEYUP)消息。像所有的队列消息一样,击键消息是可被实时追踪的。你能通过调用GetMessageTime函数,得到键被按下或释放的相对时间。

    系统击键

    表明该击键对Windows比对Windows应用程序更加重要。当输入键和Alt键组合时通常产生的是WM SYSKEYDOWN和WMSYSKEYUP消息。应用程序通常忽略WMSYSKEYUP和WMSYSKEYDOWN消息,将它们交付给DefWindowProc函数完成默认处理。因为Windows关注所有的Alt键功能逻辑,应用程序就不必处理这些消息。如果你非要处理这些消息,则在处理完毕后,仍然需要发送这些消息给DefWindowProc函数,以便不影响Windows对它的处理。

    对所有四类击键消息,wParam是虚拟键代码,用于标识哪个键被按下或被释放,而IParam包含属于本次击键的一些其他数据。大多数虚拟键代码命名是以VK_开头的,它定义在WINUSER日头文件中。lParam消息参数包含了帮助理解击键的其他有用信息。32位的lParam消息被分成了6个字段,如图所示。

     1 #include<Windows.h>
     2 #include<WinUser.h>
     3 #include<tchar.h>
     4 #include<stdio.h>
     5 
     6 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
     7 
     8 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow)
     9 {
    10     WNDCLASS WndClass;
    11     TCHAR* ClassName = TEXT("MyClass");
    12     HWND hwnd;
    13     MSG msg;
    14 
    15     WndClass.cbClsExtra = 0;
    16     WndClass.cbWndExtra = 0;
    17     WndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    18     WndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    19     WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    20     WndClass.hInstance = hInst;
    21     WndClass.lpfnWndProc = WindProc;
    22     WndClass.lpszClassName = ClassName;
    23     WndClass.lpszMenuName = NULL;
    24     WndClass.style = CS_VREDRAW | CS_HREDRAW;
    25 
    26     RegisterClass(&WndClass);
    27     hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 300, NULL, NULL, hInst, NULL);
    28     ShowWindow(hwnd, nShow);
    29     UpdateWindow(hwnd);
    30 
    31     while (GetMessage(&msg, NULL, 0, 0))
    32     {
    33         TranslateMessage(&msg);
    34         DispatchMessage(&msg);
    35     }
    36     return 0;
    37 }
    38 
    39 
    40 
    41 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    42 {
    43     HDC hdc;
    44     PAINTSTRUCT pt;
    45     static int cx, cy;
    46     static int cyChar;
    47     static int iLine;
    48     static int iMaxLine;
    49     static TCHAR cBuf[1024] = { "Please Press Key:" };
    50     TEXTMETRIC tm;
    51     RECT rect;
    52     switch (message)
    53     {
    54     case WM_CREATE:
    55         hdc = GetDC(hwnd);
    56         GetTextMetrics(hdc, &tm);
    57         cyChar = tm.tmHeight;
    58         ReleaseDC(hwnd, hdc);
    59         iLine = 0;
    60         iMaxLine = 0;
    61         return 0;
    62     case WM_SIZE:
    63         cx = LOWORD(lParam);
    64         cy = HIWORD(lParam);
    65         iMaxLine = cy / cyChar-1;
    66         iLine = iLine > iMaxLine ? iMaxLine : iLine;
    67         return 0;
    68     case WM_PAINT:
    69         hdc = BeginPaint(hwnd, &pt);
    70         TextOut(hdc, pt.rcPaint.left, pt.rcPaint.top, cBuf, _tcslen(cBuf));
    71         EndPaint(hwnd, &pt);
    72         iLine++;
    73         return 0;
    74     case WM_CHAR:
    75         iLine = iLine > iMaxLine ? iMaxLine : iLine;
    76         _stprintf(cBuf, TEXT("lParam=0x%X   wParam=0x%X  : %c"), lParam, wParam,wParam);
    77         rect.left = 0;
    78         rect.top = iLine * cyChar;
    79         rect.right = cx;
    80         rect.bottom = (iLine + 1)*cyChar;
    81         InvalidateRect(hwnd, &rect, TRUE);
    82         return 0;
    83     case WM_DESTROY:
    84         PostQuitMessage(0);
    85         return 0;
    86     default:
    87         break;
    88     }
    89 
    90     return DefWindowProc(hwnd, message, wParam, lParam);
    91 }
    View Code
  • 相关阅读:
    UVa-272-TEX Quotes
    UVa-10881-蚂蚁
    UVa-1339-古老的密码
    POJ-1328-放置雷达
    POJ-3190-分配畜栏
    Openjudge-2787-算24
    WHYZOJ-#47. 滑行的窗口(单调队列)
    2017年9月16日18:03:54
    WHYZOJ-#93. 暗黑破坏神(垃圾01背包)
    WHYZOJ-#95 大逃亡(二分+BFS)(好题!!!)
  • 原文地址:https://www.cnblogs.com/kelamoyujuzhen/p/9320644.html
Copyright © 2011-2022 走看看