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

以下内容主要来自《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调用的下一条语句。

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{// cxChar平均字符宽度,cyChar字符的总高度(包括外部间距),cxCaps大写字符的平均宽度// 等宽字体中,cxCaps等于cxChar,变宽字体中,cxCaps等于cxChar的1.5倍static int   cxChar, cxCaps, cyChar, cxClient, cyClient, iMaxWidth, iVscrollPos; HDC         hdc;int         i, x, y, iVertPos, iHorzPos, iPaintBeg, iPaintEnd;PAINTSTRUCT   ps;SCROLLINFO   si;TCHAR        szBuffer[10];TEXTMETRIC tm; switch (message){case WM_CREATE:hdc = GetDC(hwnd);GetTextMetrics(hdc, &tm);        // 获取系统默认字体的尺寸cxChar = tm.tmAveCharWidth;// tmPitchAndFamily为1表示变宽字体,为0表示等宽字体cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;cyChar = tm.tmHeight + tm.tmExternalLeading;ReleaseDC(hwnd, hdc);iMaxWidth = 40*cxChar + 22*cxCaps;return 0;case WM_SIZE:cxClient = LOWORD(lParam);cyClient = HIWORD(lParam);si.cbSize  = sizeof(si);si.fMask  = SIF_RANGE | SIF_PAGE;si.nMin     = 0;si.nMax        = NUMLINES-1;si.nPage  = cyClient / cyChar;SetScrollInfo(hwnd, SB_VERT, &si, TRUE);si.cbSize  = sizeof(si);si.fMask  = SIF_RANGE | SIF_PAGE;si.nMin     = 0;si.nMax        = 2 + iMaxWidth/cxChar;si.nPage   = cxClient / cxChar;SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);return 0;case WM_VSCROLL:si.cbSize = sizeof(si);si.fMask  = SIF_ALL;GetScrollInfo(hwnd, SB_VERT, &si);iVertPos = si.nPos;switch (LOWORD(wParam)){case SB_TOP:si.nPos = si.nMin;break;case SB_BOTTOM:si.nPos = si.nMax;break;case SB_LINEUP:si.nPos -= 1;break;case SB_LINEDOWN:si.nPos += 1;break;case SB_PAGEUP:si.nPos -= si.nPage;break;case SB_PAGEDOWN:si.nPos += si.nPage;break;case SB_THUMBTRACK:si.nPos = si.nTrackPos;break;default:break;}si.fMask = SIF_POS;SetScrollInfo(hwnd, SB_VERT, &si, TRUE);GetScrollInfo(hwnd, SB_VERT, &si);if (si.nPos != iVertPos){ScrollWindow(hwnd, 0, cyChar*(iVertPos-si.nPos), NULL, NULL);UpdateWindow(hwnd);}return 0;case WM_HSCROLL:si.cbSize   = sizeof(si);si.fMask  = SIF_ALL;GetScrollInfo(hwnd, SB_HORZ, &si);iHorzPos = si.nPos;switch (LOWORD(wParam)){case SB_LINELEFT:si.nPos -= 1;break;case SB_LINERIGHT:si.nPos += 1;break;case SB_PAGELEFT:si.nPos -= si.nPage;break;case SB_PAGERIGHT:si.nPos += si.nPage;break;case SB_THUMBPOSITION:si.nPos = si.nTrackPos;break;default:break;}si.fMask = SIF_POS;SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);GetScrollInfo(hwnd, SB_HORZ, &si);if (si.nPos != iHorzPos){ScrollWindow(hwnd, cxChar*(iHorzPos-si.nPos), 0, NULL, NULL);UpdateWindow(hwnd);}return 0;case WM_KEYDOWN:switch (wParam){case VK_HOME:SendMessage(hwnd, WM_VSCROLL, SB_TOP, 0);break;case VK_END:SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, 0);break;case VK_PRIOR:SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, 0);break;case VK_NEXT:SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, 0);break;case VK_UP:SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, 0);break;case VK_DOWN:SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, 0);break;case VK_LEFT:SendMessage(hwnd, WM_HSCROLL, SB_PAGEUP, 0);break;case VK_RIGHT:SendMessage(hwnd, WM_HSCROLL, SB_PAGEDOWN, 0);break;}return 0;case WM_PAINT:hdc = BeginPaint(hwnd, &ps);si.cbSize = sizeof(si);si.fMask = SIF_POS;GetScrollInfo(hwnd, SB_VERT, &si);iVertPos = si.nPos;GetScrollInfo(hwnd, SB_HORZ, &si);iHorzPos = si.nPos;iPaintBeg = max(0, iVertPos + ps.rcPaint.top/cyChar);iPaintEnd = min(NUMLINES-1, iVertPos + ps.rcPaint.bottom/cyChar);for (i = iPaintBeg; i <= iPaintEnd; i++){x = cxChar * (1-iHorzPos);y = cyChar * (i-iVertPos);TextOut(hdc, x, y, sysmetrics[i].szLabel, lstrlen(sysmetrics[i].szLabel));TextOut(hdc, x + 22*cxCaps, y, sysmetrics[i].szDesc, lstrlen(sysmetrics[i].szDesc));SetTextAlign(hdc, TA_RIGHT | TA_TOP);TextOut(hdc, x + 22*cxCaps + 40*cxChar, y, szBuffer, wsprintf(szBuffer, TEXT("%5d"), GetSystemMetrics(sysmetrics[i].iIndex)));// 将对齐方式设回正常方式SetTextAlign(hdc, TA_LEFT | TA_TOP);}EndPaint(hwnd, &ps);return 0;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProc(hwnd, message, wParam, lParam);
}

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

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消息。

/*---------------------------------------------------------------------------keyView.cpp -- Displays keyboard and character messages
----------------------------------------------------------------------------*//*-----------------------------------------------------------------------------------SysMets4.cpp -- System Metrics Display Program ver4 use keyboard*----------------------------------------------------------------------------------*/#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,                                        // window class nameTEXT("Keyboard Message Viewer #1"),               // window captionWS_OVERLAPPEDWINDOW,                           // window styleCW_USEDEFAULT,                                   // initial x positionCW_USEDEFAULT,                                 // initial y positionCW_USEDEFAULT,                                 // initial x sizeCW_USEDEFAULT,                                 // initial y sizeNULL,                                          // parent window handleNULL,                                            // window menu handlehInstance,                                     // program instance handleNULL);                                            // creation parametersShowWindow(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)
{// cxChar平均字符宽度,cyChar字符的总高度(包括外部间距),cxCaps大写字符的平均宽度// 等宽字体中,cxCaps等于cxChar,变宽字体中,cxCaps等于cxChar的1.5倍static int       cxChar, cyChar, cxClient, cyClient, cxClientMax, cyClientMax;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:cxClientMax = GetSystemMetrics(SM_CXMAXIMIZED);cyClientMax = GetSystemMetrics(SM_CYMAXIMIZED);hdc = GetDC(hwnd);SelectObject(hdc, GetStockObject(SYSTEM_FIXED_FONT));GetTextMetrics(hdc, &tm);     // 获取系统默认字体的尺寸cxChar = tm.tmAveCharWidth;cyChar = tm.tmHeight;ReleaseDC(hwnd, hdc);if (pmsg)free(pmsg);cLinesMax = cyClientMax / cyChar;pmsg = (PMSG)malloc(cLinesMax * sizeof(MSG));cLines = 0;//return 0;case WM_SIZE:if (message == WM_SIZE){cxClient = LOWORD(lParam);cyClient = HIWORD(lParam);}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:for (i = cLinesMax-1; i > 0; i--){pmsg[i] = pmsg[i-1];}pmsg[0].hwnd  = hwnd;pmsg[0].message = message;pmsg[0].wParam   = wParam;pmsg[0].lParam    = lParam;cLines = min(cLines + 1, cLinesMax);ScrollWindow(hwnd, 0, -cyChar, &rectScroll, &rectScroll);break;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);
}

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

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

相关函数:

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

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

ShowCaret:显式插入符号

HideCaret:隐藏插入符号

DestroyCaret:销毁插入符号

GetCaretPos:获取插入符号位置

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

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

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

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

HideCaret效果是叠加的。

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

/*----------------------------------------------------------------------------typer.cpp -- Typing Program
----------------------------------------------------------------------------*//*---------------------------------------------------------------------------keyView.cpp -- Displays keyboard and character messages
----------------------------------------------------------------------------*//*-----------------------------------------------------------------------------------SysMets4.cpp -- System Metrics Display Program ver4 use keyboard*----------------------------------------------------------------------------------*/#include <windows.h>LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);#define BUFFER(x, y) *(pBuffer + y*cxBuffer + x)int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{static TCHAR   szAppName[] = TEXT("Typer");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,                                        // window class nameTEXT("Typer"),                                    // window captionWS_OVERLAPPEDWINDOW,                           // window styleCW_USEDEFAULT,                                   // initial x positionCW_USEDEFAULT,                                 // initial y positionCW_USEDEFAULT,                                 // initial x sizeCW_USEDEFAULT,                                 // initial y sizeNULL,                                          // parent window handleNULL,                                            // window menu handlehInstance,                                     // program instance handleNULL);                                            // creation parametersShowWindow(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 DWORD   dwCharSet = DEFAULT_CHARSET;static int     cxChar, cyChar, cxClient, cyClient, cxBuffer, cyBuffer, xCaret, yCaret;static TCHAR*    pBuffer = NULL;int             x, y, i;HDC             hdc;PAINTSTRUCT     ps;TEXTMETRIC       tm; switch (message){case WM_INPUTLANGCHANGE:dwCharSet = wParam;case WM_CREATE:hdc = GetDC(hwnd);SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));GetTextMetrics(hdc, &tm);cxChar = tm.tmAveCharWidth;cyChar = tm.tmHeight;DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));ReleaseDC(hwnd, hdc);case WM_SIZE:if (message == WM_SIZE){cxClient = LOWORD(lParam);cyClient = HIWORD(lParam);}cxBuffer = max(1, cxClient/cxChar);cyBuffer = max(1, cyClient/cyChar);if (pBuffer != NULL)free(pBuffer);pBuffer = (TCHAR *)malloc(sizeof(TCHAR) * cxBuffer * cyBuffer);for (y = 0; y < cyBuffer; y++)for (x = 0; x < cxBuffer; x++)BUFFER(x, y) = ' ';xCaret = 0;yCaret = 0;if (hwnd == GetFocus())SetCaretPos(xCaret * cxChar, yCaret * cyChar);InvalidateRect(hwnd, NULL, TRUE);return 0;case WM_SETFOCUS:CreateCaret(hwnd, NULL, cxChar, cyChar);SetCaretPos(xCaret*cxChar, yCaret*cyChar);ShowCaret(hwnd);return 0;case WM_KILLFOCUS:HideCaret(hwnd);DestroyCaret();return 0;case WM_KEYDOWN:switch (wParam){case VK_HOME:xCaret = 0;break;case VK_END:xCaret = cxBuffer - 1;break;case VK_PRIOR:yCaret = 0;break;case VK_NEXT:yCaret = cyBuffer - 1;break;case VK_LEFT:xCaret = max(xCaret-1, 0);break;case VK_RIGHT:xCaret = min(xCaret+1, cxBuffer-1);break;case VK_UP:yCaret = max(yCaret-1, 0);break;case VK_DOWN:yCaret = min(yCaret+1, cyBuffer-1);break;case VK_DELETE:for (x = xCaret; x < cxBuffer-1; x++)BUFFER(x, yCaret) = BUFFER(x+1, yCaret);BUFFER(cxBuffer-1, yCaret) = ' ';HideCaret(hwnd);hdc = GetDC(hwnd);SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));TextOut(hdc, xCaret*cxChar, yCaret*cyChar, &BUFFER(xCaret, yCaret), cxBuffer-xCaret);DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));ReleaseDC(hwnd, hdc);ShowCaret(hwnd);break;}SetCaretPos(xCaret*cxChar, yCaret*cyChar);return 0;case WM_CHAR:for (i = 0; i < (int)LOWORD(lParam); i++){switch (wParam){case '\b':          // backspaceif (xCaret > 0){xCaret--;SendMessage(hwnd, WM_KEYDOWN, VK_DELETE, 1);}break;case '\t':         // tabdo{SendMessage(hwnd, WM_CHAR, ' ', 1);}while (xCaret % 8 != 0);break;case '\n':          // line feedif (++yCaret == cyBuffer)yCaret = 0;break;case '\r':         // carriage returnxCaret = 0;if (++yCaret == cyBuffer)yCaret = 0;break;case '\x1B':     // escapefor (y = 0; y < cyBuffer; y++)for (x = 0; x < cxBuffer; x++)BUFFER(x, y) = ' ';xCaret = 0;yCaret = 0;InvalidateRect(hwnd, NULL, FALSE);break;default:         // character codesBUFFER(xCaret, yCaret) = (TCHAR)wParam;HideCaret(hwnd);hdc = GetDC(hwnd);SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));TextOut(hdc, xCaret*cxChar, yCaret*cyChar, &BUFFER(xCaret, yCaret), 1);DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));ReleaseDC(hwnd, hdc);ShowCaret(hwnd);if (++xCaret == cxBuffer){xCaret = 0;if (++yCaret == cyBuffer)yCaret = 0;}break;}}SetCaretPos(xCaret*cxChar, yCaret*cyChar);return 0;case WM_PAINT:hdc = BeginPaint(hwnd, &ps);SelectObject(hdc, CreateFont(0, 0, 0, 0, 0, 0, 0, 0, dwCharSet, 0, 0, 0, FIXED_PITCH, NULL));for (y = 0; y < cyBuffer; y++)TextOut(hdc, 0, y*cyChar, &BUFFER(0, y), cxBuffer);DeleteObject(SelectObject(hdc, GetStockObject(SYSTEM_FONT)));EndPaint(hwnd, &ps);return 0;case WM_DESTROY:PostQuitMessage(0);return 0;}return DefWindowProc(hwnd, message, wParam, lParam);
}

Win32 键盘事件 - 击键消息、字符消息、插入符号(光标)相关推荐

  1. java按键事件空格_java键盘事件 空格键

    public void keyPressed(KeyEvent e) {//键盘按键按下事件 // TODO Auto-generated method stub switch(e.getKeyCod ...

  2. vue 绑定 keyup.enter 绑定回车键盘事件 enter键防止页面刷新

    为祖国的复兴而读书!!! 一般方法,这样写: <div class="btn submit" @keyup.enter="submit" @click=& ...

  3. Windows程序设计--击键消息和字符消息

    键盘消息分为击键消息和字符消息.而击键消息就是指当你按下一个键时它是哪个键. 一般有以下四个击键消息: WM_KEYDOWN.WM_SYSKEYDOWN.WM_KEYUP.WM_SYSKEYUP.这里 ...

  4. python绑定按键pageup键_键盘事件keydown、keypress、keyup随笔整理总结(摘抄)

    原文1:http://www.cnblogs.com/silence516/archive/2013/01/25/2876611.html 原文2:http://www.cnblogs.com/leo ...

  5. keyup常用事件_键盘事件keydown、keypress、keyup随笔整理总结

    键盘 英文输入法: 事件触发顺序:keydown - > keypress - > keyup 中文输入法: firfox:输入触发keydown,回车确认输入触发keyup chrome ...

  6. 键盘事件keydown、keypress、keyup随笔整理总结(摘抄)

    原文1:http://www.cnblogs.com/silence516/archive/2013/01/25/2876611.html 原文2:http://www.cnblogs.com/leo ...

  7. java keydown_键盘事件keydown、keypress、keyup随笔整理总结

    英文输入法: 事件触发顺序:keydown - > keypress - > keyup 中文输入法: firfox:输入触发keydown,回车确认输入触发keyup chrome:输入 ...

  8. 键盘事件keydown、keypress、keyup随笔整理总结

    键盘事件keydown.keypress.keyup随笔整理总结 英文输入法: 事件触发顺序:keydown - > keypress - > keyup 中文输入法: firfox:输入 ...

  9. JQuery 键盘事件使用整理

    1. Js 键盘事件 1.键盘按下,keydown,在键盘上按下某个键时触发.如果按住某个键,会不断触发该事件 2.键盘松开,keyup,该事件仅在松开键盘时触发一次,不是一个持续的响应状态. 3.字 ...

最新文章

  1. 【转载】Python对接六大主流数据库,只需三步
  2. JavaScript多浏览器兼容问题
  3. Shell的一些基本用法
  4. 设计模式之反射与配置文件
  5. QT4到QT5的变化!
  6. OpenCV中SurfDescriptorExtractor
  7. 泛函分析4——希尔伯特空间
  8. Javascript中的arguments数组对象
  9. c 设计计算机报告,C课程设计(计算器)报告
  10. 纷杂的Spring-boot-starter: 5 应用安全与spring-boot-starter-security
  11. c语言程序设计100题,编程题(c语言编程题库100题)
  12. matlab里面计算相关系系数的显著性,数学建模笔记——相关系数
  13. 工具分享: 一键保存网页为PDF文件
  14. 黄河金岸诗词大赛获奖作品选登(2:现代新诗)
  15. graphpad两组t检验_GraphPad prism -- t检验操作步骤解析~
  16. php怎么做网站?如何用PHP开发一个完整的网站?
  17. 【个人经验】关于BFM
  18. “和合信诺”获启赋资本数千万元Pre-A轮融资-专注监管科技、助力金融业落地监管合规最后一公里
  19. 产业分析:视频云服务行业
  20. (Java实现) 洛谷 P1200 你的飞碟在这儿

热门文章

  1. Kali渗透测试——被动信息收集之Recon-NG框架
  2. 【JLPT N1】2010年7月
  3. @Modifying注解误用错误
  4. CocoaPods安装 2018
  5. 开篇-五年的工作总结与接下来的的学习方向
  6. Kotlin中自定义dialog
  7. RK3568 Debian10(buster) 基础操作
  8. 用 Python 替代Excel 表格,轻而易举实现办公自动化
  9. Java第二十二篇:详述嵌套for循环执行顺序,小白看了也能懂
  10. Niushop开源商城系统bug多?不适合商用?