Cocos2dx enables keyboard input on windows

Source: Internet
Author: User
Tags textout

Cocos2d is mainly intended for touch screen devices. In WINDOWS, positioning is more or less equivalent to a simulator. Therefore, there is not much important keyboard support in PCs. However, the response to keyboard messages can be convenient for debugging. Below you add a Keyboard Message response by changing the source code of the cocos2d-x. 1. Open \ cocos2dx \ include \ CCLayer. h add virtual void processWin32KeyPress (UINT message, WPARAM wParam, LPARAM lParam) {} 2 to the public of the CCLayer class, open \ cocos2dx \ platform \ win32 \ CCEGLView_win32.h and declare it on the definition of the CCEGLView class? 1 class CCLayer; Add the variable CCLayer * m_pLayWin32Key under private of the CCEGLView class; Add the function void SetWin32KeyLayer (CCLayer * pLayer) {m_pLayWin32Key = pLayer under public ;}? 1. Open \ cocos2dx \ platform \ win32 \ CCEGLView_win32.cpp and add # include "CCLayer. h "initialize CCLayer (NULL) in the CCEGLView constructor. Add if (NULL! = M_pLayWin32Key) {m_pLayWin32Key-> processWin32KeyPress (message, wParam, lParam);} 4. regenerate libcocos2d to generate libcocos2d. lib and libcocos2d. in this way, you can capture win32 messages in your program. You only need to add CCDirector: shareddire()-> getOpenGLView ()-> SetWin32KeyLayer (this) in the initialization part of a Layer, and then re-inherit the virtual function processWin32KeyPress to process the message. Of course, do not forget to call CCDirector: shareddire()-> getOpenGLView ()-> SetWin32KeyLayer (NULL) before the Layer is destroyed. In addition, A few days ago I thought of a more convenient way to add the following macro # 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 is then called in the UPDATE function # if (CC_TARGET_PLATFORM = CC_PLATFORM_WIN32) if (KEY_DOWN (VK_DOWN )) {// do something} # endif: The down arrow key is returned here. For details about how to respond to other keys, see WinUser. h. Note how to add character input: 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 ); // character input part break; }}} windows sdk keyboard input: because most PCs only have one keyboard, all running WINDOWS programs must share it. WINDOWS will be responsible for sending the hit key message to the application with the input focus. Although there may be several application windows at the same time on the screen, only one window at a time has an input focus. The title bar of the application with the input focus is always displayed in high brightness. In fact, you can look at keyboard messages from two perspectives: First, you can think of it as a collection of a large number of key messages. In this case, when you press a key, in WINDOWS, WM_KEYDOWN is sent to the application with the input focus, reminding it that a key is pressed. When you release the key, WINDOWS sends a WM_KYEUP message indicating that a key is released. You can treat each key as a button, and you can consider the keyboard as a character input device. When you press the "a" Key, WINDOWS sends a WM_CHAR message to the application with the input focus, telling it that the "a" Key is pressed. In fact, WINDOWS sends WM_KEYDOWN and WWM_KEYUP messages to applications with input focus, and these messages are translated into WM_CHAR messages by calling TranslateMessage. The WINDOWS window procedure function determines whether to process received messages. Generally, you do not need to process WM_KEYDOWN and WM_KEYUP messages. In the message loop, the TranslateMessage function converts the preceding messages to WM_CHAR messages. In our course, only WM_CHAR will be processed. Example: (See 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 is the ascii code of space, ensure that the program is properly displayed when no buttons are available. 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, OEM_CHARSET, character, expiration, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SCRIPT, FontName ); hOldFont = (HFONT) SelectObject (hDC, hFont); SetTextColor (hDC, RGB (200,200, 50); SetBkColor (hDC, RGB (255,); TextOut (hDC, (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 hPrevInstan Ce, 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. hInst Ance = hInstance; RegisterClassEx (& stdWndClass); hWinMain = createjavaswex (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;} analysis: WPARAM keyChar = 0x20; this variable saves the characters received from the keyboard. Because it is transmitted through the WPARAM type variable in the window process, we simply define it as the WPARAM type. We set the window to a space character (20 h) because there is no keyboard input during the first refresh (that is, the first time the window was created ), in this way, you cannot see anything. Case WM_CHAR: {keyChar = wParam; InvalidateRect (hWnd, NULL, TRUE);} This section is used to process WM_CHAR messages. It puts the received characters into the keyChar variable, and then calls InvalidateRect. InvalidateRect invalidates the client area of the window, which will send a WM_PAINT message, the WM_PAINT message forces WINDOWS to redraw its customer zone. The syntax of this function is as follows: BOOL InvalidateRect (HWND hWnd, // handle to window const rect * lpRect, // rectangle coordinates BOOL bErase // erase state ); lpRect is a pointer to a square struct that we want to invalidate in the customer zone. If the value is NULL, the entire customer zone is invalid. The Boolean bErase tells WINDOWS whether to erase the background. If the value is TRUE, WINDOWS will erase the background when calling the BeginPaint function. So here we will save all the data about the redrawing customer area, then send the WM_PAINT message, the program segment for processing the message, and re-draw the customer area based on the relevant data. Although this is a bit like a detour, WINDOWS does not have certain rules to deal with such a large message group. In fact, we can call GetDC to get the device context handle, draw characters, and then call ReleaseDC to release the device context handle. Without a doubt, this can also draw the correct characters in the customer zone. However, if the user receives the WM_PAINT message to be processed, the customer zone will refresh the message, and the previously drawn characters will disappear. Therefore, to keep characters correctly displayed, you must put them into the WM_PAINT processing process. In this message processing, you can send the WM_PAINT message. TextOut (hDC, (char *) & keyChar, 1); When InvalidateRect is called, The WM_PAINT message is sent to the WINDOWS window processing process, and the program process is transferred to the program segment that processes the WM_PAINT message, call BeginPaint to obtain the device context handle, and then call TextOut to output the stored key characters at () in the customer zone. In this way, no matter what key you press, you can display it in the upper left corner of the customer area. In addition, no matter how you scale the window (Force WINDOWS to redraw its customer area ), the characters are displayed in the correct place. Therefore, all important draw actions must be placed in the program segment for processing the WM_PAINT message.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.