cocos2dx 在windows上实现键盘输入
cocos2d主要面向的是触摸屏幕设备的,在WINDOWS下的定位感觉多多少少就是相当于一个模拟器,因此并没有太多的PC下重要的键盘支持。然而响应键盘消息对于调试来说可以提供不少方便。下边就通过更改cocos2d-x的源码来添加键盘消息响应。
一,打开\cocos2dx\include\CCLayer.h
在CCLayer类的public下添加
1
|
virtual void processWin32KeyPress( UINT message, WPARAM wParam, LPARAM lParam) {} |
1
|
|
二,打开\cocos2dx\platform\win32\CCEGLView_win32.h
在CCEGLView类的定义上边声明
1
|
class CCLayer; |
在CCEGLView类的private下添加变量
1
|
CCLayer *m_pLayWin32Key; |
在public下添加函数
1
2
3
4
|
void SetWin32KeyLayer(CCLayer *pLayer) { m_pLayWin32Key = pLayer; } |
1
|
|
三,打开\cocos2dx\platform\win32\CCEGLView_win32.cpp
在文件开始部分添加
1
|
#include "CCLayer.h" |
在CCEGLView构造函数中初始化CCLayer(NULL)
在WindowProc函数的开始部分添加
1
2
3
4
|
if (NULL != m_pLayWin32Key) { m_pLayWin32Key->processWin32KeyPress(message, wParam, lParam); } |
1
|
|
四,重新生成libcocos2d将新生成的libcocos2d.lib和libcocos2d.dll放到相应位置
这样就可以在自己的程序中捕获win32的消息了。只需要在某个Layer的初始化部分添加
1
|
CCDirector::sharedDirector()->getOpenGLView()->SetWin32KeyLayer( this ); |
然后重新继承虚函数processWin32KeyPress,就可以处理消息了。当然在Layer销毁前别忘记调用
1
|
CCDirector::sharedDirector()->getOpenGLView()->SetWin32KeyLayer(NULL); |
1
|
|
另外,前几天想到了一个更加方便的办法
在模拟键盘的源文件中添加以下宏
1
2
3
4
5
|
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) #include <windows.h> #define KEY_DOWN(vk_code) (GetAsyncKeyState(vk_code) & 0x8000 ? 1 : 0) #define KEY_UP(vk_code) (GetAsyncKeyState(vk_code) & 0x8000 ? 0 : 1) #endif |
然后在UPDATE函数中调用
1
2
3
4
5
6
|
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) if (KEY_DOWN(VK_DOWN)) { // do something } #endif |
这里响应的是下箭头键,需要响应其他键可以参考WinUser.h中其他虚拟键的宏。
要注意的是如何添加字符输入呢:
void HelloWorld:: processWin32KeyPress(UINT message,
WPARAM wParam,
LPARAM lParam)
{
WPARAM keyChar = 0x20;
switch (message)
{
case WM_LBUTTONDOWN:{
CCLog("WM_LBUTTONDOWN");
break;
}
case WM_CHAR:{
keyChar = wParam;
CCLog("WM_CHAR: %d", keyChar);//字符输入部分
break;
}
}
}
windows 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消息。在我们的课程中将只处理WM_CHAR。
例子: (见光盘FirstWindow4)
#include "Windows.h"
#include "tchar.h"
HWND hWinMain;
TCHAR szClassName[] = _T("MyClass");
TCHAR szCaptionMain[] = _T("My First Window!");
TCHAR FontName[] = _T("script");
WNDCLASSEX stdWndClass;
WPARAM keyChar = 0x20; //0x20是空格的ascii码,保证没有按键的时候程序正常显示。
LRESULT CALLBACK ProcWinMain( HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
)
{
PAINTSTRUCT stPs;
HDC hDC;
HFONT hFont,hOldFont;
switch(Msg)
{
case WM_PAINT:
{
hDC = BeginPaint(hWnd,&stPs);
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,0,0,(char *)&keyChar,1);
SelectObject(hDC,hOldFont);
EndPaint(hWnd,&stPs);
}
break;
case WM_CHAR:
{
keyChar = wParam;
InvalidateRect(hWnd,NULL,TRUE);
}
break;
case WM_DESTROY:
{
PostQuitMessage(NULL);
}
break;
default:
return DefWindowProc(hWnd, Msg, wParam, lParam );
}
return 0;
}
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
MSG stMsg;
WNDCLASSEX stdWndClass;
RtlZeroMemory(&stdWndClass, sizeof(stdWndClass));
stdWndClass.hCursor = LoadCursor(0,IDC_ARROW);
stdWndClass.cbSize = sizeof(stdWndClass);
stdWndClass.style = CS_HREDRAW|CS_VREDRAW;
stdWndClass.lpfnWndProc = ProcWinMain;
stdWndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
stdWndClass.lpszClassName = szClassName;
stdWndClass.hInstance = hInstance;
RegisterClassEx(&stdWndClass);
hWinMain = CreateWindowEx(WS_EX_CLIENTEDGE,szClassName,szCaptionMain,\
WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL);
if(!hWinMain)
return 0;
ShowWindow(hWinMain,SW_SHOWNORMAL);
UpdateWindow(hWinMain);
while(GetMessage(&stMsg,NULL,0,0))
{
TranslateMessage(&stMsg);
DispatchMessage(&stMsg);
}
return stMsg.wParam;
}
分析:
WPARAM keyChar = 0x20;
这个变量将保存从键盘接收到的字符。因为它是在窗口过程中通过WPARAM型变量传送的,所以我们简单地把它定义为WPARAM型。由于我们的窗口在初次刷新时(也即刚被创建的那一次)是没有键盘输入的所以我们把他设成空格符(20h),这样显示时您就什么都看不见。
case WM_CHAR:
{
keyChar = wParam;
InvalidateRect(hWnd,NULL,TRUE);
}
这一段是用来处理WM_CHAR消息的。它把接收到的字符放入变量keyChar 中,接着调用InvalidateRect,而InvalidateRect使得窗口的客户区无效,这样它会发出WM_PAINT消息,而WM_PAINT消息迫使WINDOWS重新绘制它的客户区。该函数的语法如下:
BOOL InvalidateRect(
HWND hWnd, // handle to window
CONST RECT* lpRect, // rectangle coordinates
BOOL bErase // erase state
);
lpRect是指向客户区我们想要其无效的一个正方形结构体的指针。如果该值等于NULL,则整个客户区都无效;布尔值bErase告诉WINDOWS是否擦除背景,如果是TRUE,则WINDOWS在调用BeginPaint函数时把背景擦掉。 所以我们此处的做法是:我们将保存所有有关重绘客户区的数据,然后发送WM_PAINT消息,处理该消息的程序段然后根据相关数据重新绘制客户区。尽管这么做事有点像走了弯路,但WINDOWS要处理那么庞大的消息群,没有一定的规矩可不行。 实际上我们完全可以通过调用GetDC 获得设备上下文句柄,然后绘制字符,然后再调用ReleaseDC释放设备上下文句柄,毫无疑问这样也能在客户区绘制出正确的字符。但是如果这之后接收到WM_PAINT消息要处理时,客户区会重新刷新,而我们这稍前所绘制的字符就会消失掉。所以为了让字符一直正确地显示,就必须把它们放到WM_PAINT的处理过程中处理。而在本消息处理中发送WM_PAINT消息即可。
TextOut(hDC,0,0,(char *)&keyChar,1);
在调用InvalidateRect时,WM_PAINT消息被发送到了WINDOWS窗口处理过程,程序流程转移到处理WM_PAINT消息的程序段,然后调用BeginPaint得到设备上下文的句柄,再调用TextOut在客户区的(0,0)处输出保存的按键字符。这样无论您按什么键都能在客户区的左上角显示,不仅如此,无论您怎么缩放窗口(迫使WINDOWS重新绘制它的客户区),字符都会在正确的地方显示,所以必须把所有重要的绘制动作都放到处理WM_PAINT消息的程序段中去。
cocos2dx 在windows上实现键盘输入的更多相关文章
- 普通键盘Windows上虚拟Cherry机械键盘效果的方法
草台班子--普通键盘Windows上虚拟Cherry机械键盘效果的方法 机械键盘以其独特的手感.绚丽的外形,还有那人神共愤的音效吸引着大批爱好者.最近iQQO 3的机械键盘效果更是吸引了更多 ...
- Windows 窗体—— 键盘输入工作原理
方法 注释 PreFilterMessage 此方法在应用程序级截获排队的(也称为已发送的)Windows 消息. PreProcessMessage 此方法在 Windows 消息处理前在窗体和控件 ...
- 通过VNC连接远程服务器,然后登陆服务器上的虚拟机,出现键盘输入问题的解决方法
前几天由于要在服务器上装一个虚拟机,然后就选择了vmware workstation,装好之后,进入虚拟机中的centOS系统,发现键盘上的Cpas Lock键不起作用,按下之后还是输入小写,而且按住 ...
- 从键盘输入一个字符串(长度不超过30),统计字符串中非数字的个数,并将统计的结果显示在屏幕上,用EXE格式实现。
问题 从键盘输入一个字符串(长度不超过30),统计字符串中非数字的个数,并将统计的结果显示在屏幕上,用EXE格式实现. 源程序 data segment hintinput db "plea ...
- [Windows编程] 使用AttachThreadInput 来捕捉其它窗口的键盘输入
在一些情况下(比如屏幕软键盘或者输入法程序),自己的窗口没有输入焦点但是想要当前焦点窗口的键盘输入消息,可以使用Win32 API函数AttachThreadInput()来解决这个问题.Attach ...
- 使用C#模拟键盘输入、鼠标移动和点击、设置光标位置及控制应用程序的显示
1.模拟键盘输入(SendKeys) 功能:将一个或多个按键消息发送到活动窗口,就如同在键盘上进行输入一样. 语法:SendKeys.Send(string keys);SendKeys.SendWa ...
- VB模拟键盘输入的N种方法
VB模拟键盘输入的N种方法http://bbs.csdn.net/topics/90509805hd378发表于: 2006-12-24 14:35:39用VB模拟键盘事件的N种方法 键盘是我们使用计 ...
- HoloLens开发手记 - Unity之Keyboard input 键盘输入
虽然HoloLens支持很多种输入方式,包括蓝牙键盘在内.但是大部分应用还是不能断定用户有物理键盘可以输入,所以虚拟键盘输入还是必须要提供的. Unity提供了一个TouchScreenKeyboar ...
- while ((ch = getchar()) != EOF)中ch定义为char还是int型?cin、scanf等如何结束键盘输入
2013-07-09 18:55:42 EOF是文件的结束符,具体可以作为文本文件的结束符,也可以作为键盘输入char类型数据时的结束符.对于不同的系统,EOF的定义可能不同,一般定义为-1.因为ch ...
随机推荐
- [LeetCode]题解(python):029-Divide Two Integers
题目来源: https://leetcode.com/problems/divide-two-integers/ 题意分析: 不用乘法,除法和mod运算来实现一个除法.如果数值超过了int类型那么返回 ...
- js基本框架
- 英文:known good board ( KGB) / 中文:测试用标准板,黄金板
作为标准部件提供的.完全符合设计电气性能的在制板,可以作为与其它印制板比较的标准.
- fedora21安装无线驱动
来源:http://www.2cto.com/os/201202/120249.html 一.导入rpmfushion源,使用第三方yum 源: su -c 'yum localinstall --n ...
- BZOJ 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课
题目 1644: [Usaco2007 Oct]Obstacle Course 障碍训练课 Time Limit: 5 Sec Memory Limit: 64 MB Description 考虑一 ...
- 1245 - Harmonic Number (II)(规律题)
1245 - Harmonic Number (II) PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limit: 3 ...
- hdu1698 Just a Hook 线段树:成段替换,总区间求和
转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 Problem ...
- 自定义UIViewController与xib文件关系深入分析
6月14日 上海 OSC 源创会开始报名啦,有很多机械键盘送哦!!! 用xcode模板向工程加入UIViewController sub class的时候,如果选中了with xib for inte ...
- zabbix 添加主机接口
http://192.168.32.101:3000/api/zabbix/add_Host?env=test&host=zjtest9-app&ip=192.168.32.250&a ...
- grep命令參数及使用方法
功能说明:查找文件中符合条件的字符串. 语 法:grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>] ...