[Win32]Win32 SDK编程系列文章——键盘输入消息

理论

因为大多数的PC只有一个键盘,所以所有运行中的WINDOWS程序必须共用它。WINDOWS 将负责把击键消息送到具有输入焦点的那个应用程序中去。尽管屏幕上可能同时有几个应用程序窗口,但一个时刻仅有一个窗口有输入焦点。有输入焦点的那个应用程序的标题条总是高亮度显示的。 实际上您可以从两个角度来看键盘消息:一是您可以把它看成是一大堆的按键消息的集合,在这种情况下,当您按下一个键时,WINDOWS就会发送一个WM_KEYDOWN给有输入焦点的那个应用程序,提醒它有一个键被按下。当您释放键时,WINDOWS又会发送一个WM_KYEUP消息,告诉有一个键被释放。您把每一个键当成是一个按钮;另一种情况是:您可以把键盘看成是字符输入设备。当您按下“a”键时,WINDOWS发送一个WM_CHAR消息给有输入焦点的应用程序,告诉它“a”键被按下。实际上WINDOWS 内部发送WM_KEYDOWN和WWM_KEYUP消息给有输入焦点的应用程序,而这些消息将通过调用TranslateMessage翻译成WM_CHAR消息。WINDOWS窗口过程函数将决定是否处理所收到的消息,一般说来您不大会去处理WM_KEYDOWN、WM_KEYUP消息,在消息循环中TranslateMessage函数会把上述消息转换成WM_CHAR消息

实例

关键代码
TCHAR FontName[]=_T("script");
WPARAM keyChar =0x20;//0x20(十六进制)是空格的ascii码,亳州没有按键的时候程序正常显示
TCHAR keyDownUp[50]; 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;
	HFONT hFont,hOldFont;
	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 分析菜单选择:
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO: 在此添加任意绘图代码...
		hFont=CreateFont(24,16,0,0,400,0,0,0,OEM_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_SCRIPT,FontName);
		hOldFont =(HFONT)SelectObject(hdc,hFont);
		SetTextColor(hdc,RGB(200,200,50));
		SetBkColor(hdc,RGB(0,0,255));
		TextOut(hdc,40,40,(TCHAR*)&keyChar,1);//在设备环境的坐标(40,40)处,化长度为1的keyChar字符串
		EndPaint(hWnd, &ps);
		break;
	case WM_CHAR://按下某键, 并已发出WM_KEYDOWN, WM_KEYUP消息 
		keyChar=wParam;//接收到的字符放入变量keyChar中,接着调用InvalidateRect,而InvalidateRect使得窗口的客户区无效,这样它会发出WM_PAINT消息,而WM_PAINT消息迫使Windows重新绘制它的客户区。
		InvalidateRect(hWnd,NULL,TRUE);
		//我们将保存所有有关重绘客户区的数据,然后发送WM_PAINT消息,处理该消息的程序段然后根据相关数据重新绘制客户区。尽管这么做事有点像走了弯路,但WINDOWS要处理那么庞大的消息群,没有一定的规矩可不行。 实际上我们完全可以通过调用GetDC 获得设备上下文句柄,然后绘制字符,然后再调用ReleaseDC释放设备上下文句柄,毫无疑问这样也能在客户区绘制出正确的字符。但是如果这之后接收到WM_PAINT消息要处理时,客户区会重新刷新,而我们这稍前所绘制的字符就会消失掉。所以为了让字符一直正确地显示,就必须把它们放到WM_PAINT的处理过程中处理。而在本消息处理中发送WM_PAINT消息即可。
		break;
	case WM_KEYDOWN://按下一个键,当一个非系统键被按下时该消息发送给具有键盘焦点的窗口。非系统键即不与ALT联用的情况。 
		wsprintf(keyDownUp,L"keyDown:%c",wParam);
	    SetWindowText(hWnd,keyDownUp);
		break;
	case WM_SYSKEYUP://释放一个系统键,系统键alt+x
		wsprintf(keyDownUp,L"SysKeyUp:%c",wParam);
		SetWindowText(hWnd,keyDownUp);
		break; 
	case WM_KEYUP:
		if (GetAsyncKeyState(VK_CONTROL))//GetAsyncKeyState()实时检查键盘硬件状态返回结果。GetKeyState函数并非实时检查键盘状态,它只是检查当前正在处理的消息发生之前和发生之时的键盘状态,它是通过读取消息队列中该键的按键消息来实现的。
		{
			if (wParam == VK_NUMPAD1)
			{
				wsprintf(keyDownUp,L"Control+%c",wParam);//组合键消息
				SetWindowText(hWnd,keyDownUp);
			}		
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
/* 1.  BOOL InvalidateRect(
__in_opt HWND hWnd,
__in_opt CONST RECT *lpRect,//是指向客户区我们想要其无效的一个正方形结构体的指针。如果为NULL,则整个客户区都无效
__in BOOL bErase);//是否擦除背景
*/
效果图:

 

转载于:https://www.cnblogs.com/dyllove98/archive/2013/06/05/3119875.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值