关于CEGUI的中文输入与显示
来源:互联网 发布:淘宝扫码领取粮票 编辑:程序博客网 时间:2024/04/29 04:27
项目终于进行到中文的输入和显示了,貌似这是个老话题,同样还是先求助于前辈,很多方案,照着做了一下,很好用,整理一个版本,希望能方便到更多需要用到这个功能的朋友。
感谢腾讯网友襄樊石开和Azure。
中文的显示:
中文的显示很简单,因为CEGUI本来就支持utf-8,只是他默认的demo里没有带中文字体,自己根据.ttf文件创建一个就是了。
Step1: 在控制面板里找到一种.ttf格式的字体,我用了自己喜欢的微软雅黑,文件名为MSYH.TTF,将其拷贝至datafiles文件下的font里。
Step2: 在font文件夹下新建一个记事本文件,另存为msyh.font,里面输入
view plaincopy to clipboardprint?
<?xml version="1.0" ?>
<Font Name="MSYH" Filename="MSYH.TTF" Type="FreeType" Size="10" NativeHorzRes="800" NativeVertRes="600" AutoScaled="true" />
<?xml version="1.0" ?>
<Font Name="MSYH" Filename="MSYH.TTF" Type="FreeType" Size="10" NativeHorzRes="800" NativeVertRes="600" AutoScaled="true" />
Step3: 以CEGUI自带的FontDemo为例,如下修改源码:
在static const char *FontList [] = {}里添加项 "MSYH"(就是字体名,.font文件里定义的)
在
view plaincopy to clipboardprint?
static struct
{
utf8 *Language;
utf8 *Text;
} LangList []
static struct
{
utf8 *Language;
utf8 *Text;
} LangList []
的最后加上
view plaincopy to clipboardprint?
{
(utf8 *)"MSYH. Chinese",
(utf8 *)"简体中文测试,微软雅黑/n",
}
{
(utf8 *)"MSYH. Chinese",
(utf8 *)"简体中文测试,微软雅黑/n",
}
Step4: 将FontDemo对应的FontDemo.layout文件用记事本打开,另存为utf-8。
OK,现在看看你的成就吧,呵呵。
中文的输入:
中文的输入比较复杂,涉及到一些底层的东西,这里拿来主义,不进行深究,只简单的完成功能。
需要修改CEGUISampleHelper里的Win32AppHelper.h和Win32AppHelper.cpp,下面直接贴上修改后的源文件,可以直接将原文件覆盖掉重新编译。
view plaincopy to clipboardprint?
/***********************************************************************
filename: Win32AppHelper.h
created: 17/10/2004
author: Paul D Turner
*************************************************************************/
/***************************************************************************
* Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#ifndef _Win32AppHelper_h_
#define _Win32AppHelper_h_
#if defined( __WIN32__ ) || defined( _WIN32 )
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
// 这个是新加的
#include "imm.h"
#include <dinput.h>
// undefine Microsoft macro evilness
# undef min
# undef max
#endif
#if defined(_WIN32)
# pragma comment(lib, "dinput8.lib")
# pragma comment(lib, "dxguid.lib")
# pragma comment(lib, "imm32.lib")
#endif
#include "CEGUIString.h"
/*!
/brief
All static utility class containing helper / common functions used for the Win32 apps
*/
class Win32AppHelper
{
public:
struct DirectInputState
{
DirectInputState() : directInput(0), keyboardDevice(0)
{}
LPDIRECTINPUT8 directInput;
LPDIRECTINPUTDEVICE8 keyboardDevice ;
};
static HWND createApplicationWindow(int width, int height);
static void mouseEnters(void);
static void mouseLeaves(void);
static bool initialiseDirectInput(HWND window, Win32AppHelper::DirectInputState& dis);
static void cleanupDirectInput(Win32AppHelper::DirectInputState& dis);
static void doDirectInputEvents(const Win32AppHelper::DirectInputState& dis);
static bool doWin32Events(bool& idle);
/////// 中文输入注入字符 (Added by Azure)
static bool ChnInjectChar(CEGUI::utf32 code_point);
///////
/////// 虚拟按键转扫描码 (Added by Azure)
static UINT VirtualKeyToScanCode(WPARAM wParam, LPARAM lParam);
/////// 获得输入框的坐标 (Added by Azure)
static bool getFocusedInputBoxCoord(POINT& point, float& height);
////// 输入法跟随 (Added by Azure)
static bool IMEFollow(HWND hWnd);
static LRESULT CALLBACK wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
/*************************************************************************
Constants
*************************************************************************/
// name of the application, used for class and window creation
static const TCHAR APPLICATION_NAME[];
// error strings displayed during initialisation
static const TCHAR REGISTER_CLASS_ERROR[];
static const TCHAR CREATE_WINDOW_ERROR[];
// other error strings used
static const TCHAR CREATE_D3D_ERROR[];
static const TCHAR CREATE_DEVICE_ERROR[];
private:
static bool d_mouseInWindow;
};
#endif // end of guard _Win32AppHelper_h_
/***********************************************************************
filename: Win32AppHelper.h
created: 17/10/2004
author: Paul D Turner
*************************************************************************/
/***************************************************************************
* Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#ifndef _Win32AppHelper_h_
#define _Win32AppHelper_h_
#if defined( __WIN32__ ) || defined( _WIN32 )
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
// 这个是新加的
#include "imm.h"
#include <dinput.h>
// undefine Microsoft macro evilness
# undef min
# undef max
#endif
#if defined(_WIN32)
# pragma comment(lib, "dinput8.lib")
# pragma comment(lib, "dxguid.lib")
# pragma comment(lib, "imm32.lib")
#endif
#include "CEGUIString.h"
/*!
/brief
All static utility class containing helper / common functions used for the Win32 apps
*/
class Win32AppHelper
{
public:
struct DirectInputState
{
DirectInputState() : directInput(0), keyboardDevice(0)
{}
LPDIRECTINPUT8 directInput;
LPDIRECTINPUTDEVICE8 keyboardDevice ;
};
static HWND createApplicationWindow(int width, int height);
static void mouseEnters(void);
static void mouseLeaves(void);
static bool initialiseDirectInput(HWND window, Win32AppHelper::DirectInputState& dis);
static void cleanupDirectInput(Win32AppHelper::DirectInputState& dis);
static void doDirectInputEvents(const Win32AppHelper::DirectInputState& dis);
static bool doWin32Events(bool& idle);
/////// 中文输入注入字符 (Added by Azure)
static bool ChnInjectChar(CEGUI::utf32 code_point);
///////
/////// 虚拟按键转扫描码 (Added by Azure)
static UINT VirtualKeyToScanCode(WPARAM wParam, LPARAM lParam);
/////// 获得输入框的坐标 (Added by Azure)
static bool getFocusedInputBoxCoord(POINT& point, float& height);
////// 输入法跟随 (Added by Azure)
static bool IMEFollow(HWND hWnd);
static LRESULT CALLBACK wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
/*************************************************************************
Constants
*************************************************************************/
// name of the application, used for class and window creation
static const TCHAR APPLICATION_NAME[];
// error strings displayed during initialisation
static const TCHAR REGISTER_CLASS_ERROR[];
static const TCHAR CREATE_WINDOW_ERROR[];
// other error strings used
static const TCHAR CREATE_D3D_ERROR[];
static const TCHAR CREATE_DEVICE_ERROR[];
private:
static bool d_mouseInWindow;
};
#endif // end of guard _Win32AppHelper_h_
view plaincopy to clipboardprint?
/***********************************************************************
filename: Win32AppHelper.cpp
created: 17/10/2004
author: Paul D Turner
*************************************************************************/
/***************************************************************************
* Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#if defined(CEGUI_SAMPLES_USE_DIRECTX_8) || defined(CEGUI_SAMPLES_USE_DIRECTX_9)
#include "Win32AppHelper.h"
#include "../../../RendererModules/directx9GUIRenderer/d3d9renderer.h"
#include "CEGUI.h"
#include <TCHAR.H>
/*************************************************************************
Static Data Definitions
*************************************************************************/
// name of the application, used for class and window creation
const TCHAR Win32AppHelper::APPLICATION_NAME[] = _TEXT("Crazy Eddie's GUI Mk-2 - Sample Application");
// error strings displayed during initialisation
const TCHAR Win32AppHelper::REGISTER_CLASS_ERROR[] = _TEXT("Failed to register window class.");
const TCHAR Win32AppHelper::CREATE_WINDOW_ERROR[] = _TEXT("Failed to create window.");
// other error strings used
const TCHAR Win32AppHelper::CREATE_D3D_ERROR[] = _TEXT("Failed to create main Direct3D object.");
const TCHAR Win32AppHelper::CREATE_DEVICE_ERROR[] = _TEXT("Failed to create Direct3D Device object.");
// variable for tracking Win32 cursor
bool Win32AppHelper::d_mouseInWindow = false;
/*************************************************************************
Create main application window.
*************************************************************************/
HWND Win32AppHelper::createApplicationWindow(int width, int height)
{
WNDCLASS wndClass; // structure used to register window class
// Initialise WNDCLASS structure.
wndClass.style = 0;
wndClass.lpfnWndProc = wndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = GetModuleHandle(0);
wndClass.hIcon = LoadIcon(0, IDI_WINLOGO);
wndClass.hCursor = LoadCursor(0, IDC_ARROW);
wndClass.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
wndClass.lpszMenuName = 0;
wndClass.lpszClassName = APPLICATION_NAME;
HWND window = 0;
// register class. Report error & exit upon failure
if (RegisterClass(&wndClass))
{
// create new window
window = CreateWindow(APPLICATION_NAME, APPLICATION_NAME, WS_OVERLAPPEDWINDOW,
0, 0, width, height, 0, 0, GetModuleHandle(0), 0);
}
else
{
MessageBox(0, REGISTER_CLASS_ERROR, APPLICATION_NAME, MB_ICONERROR|MB_OK);
}
return window;
}
//寻找到有输入焦点的EditBox的左上坐标
bool Win32AppHelper::getFocusedInputBoxCoord(POINT& point, float& height)
{
//遍历所有窗口
CEGUI::WindowManager::WindowIterator wit = CEGUI::WindowManager::getSingleton().getIterator();
while(!wit.isAtEnd())
{
const CEGUI::Window* widget = (*wit)->getActiveChild();
//如果是EditBox或者MultiLineEditBox
if(widget)
{
CEGUI::String windowType = widget->getType();
if(windowType == "TaharezLook/Editbox") //根据具体的scheme来修改
{
const CEGUI::UVector2& winPos = widget->getPosition();
height = widget->getPixelRect().getHeight();
CEGUI::Vector2 winPos1 = CEGUI::CoordConverter::windowToScreen(*widget, winPos);
point.x = winPos1.d_x;
point.y = winPos1.d_y;
return true;
}
}
wit++;
}
return false;
}
bool Win32AppHelper::IMEFollow(HWND hWnd)
{
//判断输入法是否打开
if (!ImmIsIME(GetKeyboardLayout(0)))
return false;
//获得输入框左上坐标
bool result;
POINT point;
float height;
result = getFocusedInputBoxCoord(point, height);
if(!result)
return false;
//获得客户区的坐标
RECT rect;
GetClientRect(hWnd, &rect);
point.x+=rect.left;
point.y+=rect.top;
//设置输入法位置
HIMC hImc = ImmGetContext(hWnd);
if(hImc==NULL) return false;
COMPOSITIONFORM form;
ImmGetCompositionWindow(hImc, &form);
form.ptCurrentPos.x = point.x;
form.ptCurrentPos.y = point.y + height;
ImmSetCompositionWindow(hImc, &form);
return true;
}
// 虚键转扫描码
UINT Win32AppHelper::VirtualKeyToScanCode(WPARAM wParam, LPARAM lParam)
{
if(HIWORD(lParam) & 0x0F00)
{
UINT scancode = MapVirtualKey(wParam, 0);
return scancode | 0x80;
}
else
{
return HIWORD(lParam) & 0x00FF;
}
}
// 中文字符输入
bool Win32AppHelper::ChnInjectChar(CEGUI::utf32 code_point)
{
#ifndef UNICODE
static char s_tempChar[3] = "";
static wchar_t s_tempWchar[2] = L"";
static bool s_flag = false;
unsigned char uch = (unsigned char)code_point;
if( uch >= 0xA1 )
{
if( !s_flag )
{
s_tempChar[0] = (char)uch; //第一个字节
s_flag = true;
return true;
}
else if( uch >= 0xA1 )
{
s_tempChar[1] = (char)uch; //第二个字节
s_flag = false;
MultiByteToWideChar( 0, 0, s_tempChar, 2, s_tempWchar, 1); //转成宽字节
s_tempWchar[1] = L'/0';
CEGUI::utf32 code = (CEGUI::utf32)s_tempWchar[0];
return CEGUI::System::getSingleton().injectChar( code );
}
else
{
return CEGUI::System::getSingleton().injectChar(code_point);
}
}
else
{
s_flag = false;
return CEGUI::System::getSingleton().injectChar(code_point);
}
#else
return CEGUI::System::getSingleton().injectChar(code_point );
#endif
}
/*************************************************************************
Win32 'Window Procedure' function
*************************************************************************/
LRESULT CALLBACK Win32AppHelper::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CHAR:
// 不要这个
//CEGUI::System::getSingleton().injectChar((CEGUI::utf32)wParam);
// 改用自己的注入
ChnInjectChar((CEGUI::utf32)wParam);
break;
case WM_MOUSELEAVE:
mouseLeaves();
break;
case WM_NCMOUSEMOVE:
mouseLeaves();
break;
case WM_MOUSEMOVE:
mouseEnters();
CEGUI::System::getSingleton().injectMousePosition((float)(LOWORD(lParam)), (float)(HIWORD(lParam)));
break;
case WM_LBUTTONDOWN:
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);
break;
case WM_LBUTTONUP:
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);
break;
case WM_RBUTTONDOWN:
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);
break;
case WM_RBUTTONUP:
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton);
break;
case WM_MBUTTONDOWN:
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);
break;
case WM_MBUTTONUP:
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton);
break;
case 0x020A: // WM_MOUSEWHEEL:
CEGUI::System::getSingleton().injectMouseWheelChange(static_cast<float>((short)HIWORD(wParam)) / static_cast<float>(120));
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
// TODO: Notify about new size
{
//if(CEGUI::System::getSingletonPtr())
//{
// RECT rect;
// GetClientRect(hWnd, &rect);
// CEGUI::DirectX9Renderer* dx9render = static_cast<CEGUI::DirectX9Renderer*>(CEGUI::System::getSingletonPtr()->getRenderer());
// dx9render->setDisplaySize(CEGUI::Size(rect.right-rect.left, rect.bottom-rect.top));
//}
}
break;
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
}
case WM_KEYDOWN:
{
//输入法跟随
IMEFollow(hWnd);
//输入法状态时,输入不传递到UI系统中去。
UINT vk = (UINT)ImmGetVirtualKey(hWnd);
if(vk == wParam)
break;
CEGUI::System::getSingleton().injectKeyDown((CEGUI::utf32)(VirtualKeyToScanCode(wParam, lParam)));
}
break;
case WM_KEYUP:
CEGUI::System::getSingleton().injectKeyUp((CEGUI::utf32)(VirtualKeyToScanCode(wParam, lParam)));
break;
default:
return(DefWindowProc(hWnd, message, wParam, lParam));
break;
}
return 0;
}
// 鼠标进入区域
void Win32AppHelper::mouseEnters(void)
{
if (!d_mouseInWindow)
{
d_mouseInWindow = true;
ShowCursor(false);
}
}
// 鼠标离开区域
void Win32AppHelper::mouseLeaves(void)
{
if (d_mouseInWindow)
{
d_mouseInWindow = false;
ShowCursor(true);
}
}
// 初始化Direct Input,没用上
bool Win32AppHelper::initialiseDirectInput(HWND window, Win32AppHelper::DirectInputState& dis)
{
//if (SUCCEEDED(DirectInput8Create(GetModuleHandle(0), DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&dis.directInput, 0)))
//{
// if (SUCCEEDED(dis.directInput->CreateDevice(GUID_SysKeyboard, &dis.keyboardDevice, 0)))
// {
// if (SUCCEEDED(dis.keyboardDevice->SetDataFormat(&c_dfDIKeyboard)))
// {
// if (SUCCEEDED(dis.keyboardDevice->SetCooperativeLevel(window, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE)))
// {
// DIPROPDWORD inputProp;
// // the header
// inputProp.diph.dwSize = sizeof(DIPROPDWORD);
// inputProp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
// inputProp.diph.dwObj = 0;
// inputProp.diph.dwHow = DIPH_DEVICE;
// inputProp.dwData = 16;
// if (SUCCEEDED(dis.keyboardDevice->SetProperty(DIPROP_BUFFERSIZE, &inputProp.diph)))
// {
// dis.keyboardDevice->Acquire();
// return true;
// }
// else
// {
// MessageBox(0, _TEXT("Failed to set buffer size for keyboard device."), APPLICATION_NAME, MB_ICONERROR|MB_OK);
// }
// }
// else
// {
// MessageBox(0, _TEXT("Failed to set co-operative level for keyboard device."), APPLICATION_NAME, MB_ICONERROR|MB_OK);
// }
// }
// else
// {
// MessageBox(0, _TEXT("Failed to set data format for keyboard device."), APPLICATION_NAME, MB_ICONERROR|MB_OK);
// }
// dis.keyboardDevice->Release();
// dis.keyboardDevice = 0;
// }
// else
// {
// MessageBox(0, _TEXT("Failed to create DirectInput keyboard device."), APPLICATION_NAME, MB_ICONERROR|MB_OK);
// }
// dis.directInput->Release();
// dis.directInput = 0;
//}
//else
//{
// MessageBox(0, _TEXT("Failed to create main DirectInput object."), APPLICATION_NAME, MB_ICONERROR|MB_OK);
//}
return true;
}
// 清楚Direct Input,没用上
void Win32AppHelper::cleanupDirectInput(Win32AppHelper::DirectInputState& dis)
{
//if (dis.keyboardDevice)
//{
// dis.keyboardDevice->Unacquire();
// dis.keyboardDevice->Release();
// dis.keyboardDevice = 0;
//}
//if (dis.directInput)
//{
// dis.directInput->Release();
// dis.directInput = 0;
//}
}
// 处理Direct Input事件,没用上
void Win32AppHelper::doDirectInputEvents(const Win32AppHelper::DirectInputState& dis)
{
//// handle direct input based inputs
//DIDEVICEOBJECTDATA devDat;
//DWORD itemCount = 1;
//HRESULT res = dis.keyboardDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &devDat, &itemCount, 0);
//if (SUCCEEDED(res))
//{
// if (itemCount > 0)
// {
// if (LOBYTE(devDat.dwData) & 0x80)
// {
// // force quit on ESCAPE key
// if (devDat.dwOfs == CEGUI::Key::Escape)
// {
// PostQuitMessage(0);
// }
// else
// {
// CEGUI::System::getSingleton().injectKeyDown(devDat.dwOfs);
// }
// }
// else
// {
// CEGUI::System::getSingleton().injectKeyUp(devDat.dwOfs);
// }
// }
//}
//else
//{
// // try to re-acquire device if that was the cause of the error.
// if ((res == DIERR_NOTACQUIRED) || (res == DIERR_INPUTLOST))
// {
// dis.keyboardDevice->Acquire();
// }
//}
}
// 处理Win32事件
bool Win32AppHelper::doWin32Events(bool& idle)
{
MSG msg;
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
return false;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
idle = false;
}
else
{
idle = true;
}
return true;
}
#endif
/***********************************************************************
filename: Win32AppHelper.cpp
created: 17/10/2004
author: Paul D Turner
*************************************************************************/
/***************************************************************************
* Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
***************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#if defined(CEGUI_SAMPLES_USE_DIRECTX_8) || defined(CEGUI_SAMPLES_USE_DIRECTX_9)
#include "Win32AppHelper.h"
#include "../../../RendererModules/directx9GUIRenderer/d3d9renderer.h"
#include "CEGUI.h"
#include <TCHAR.H>
/*************************************************************************
Static Data Definitions
*************************************************************************/
// name of the application, used for class and window creation
const TCHAR Win32AppHelper::APPLICATION_NAME[] = _TEXT("Crazy Eddie's GUI Mk-2 - Sample Application");
// error strings displayed during initialisation
const TCHAR Win32AppHelper::REGISTER_CLASS_ERROR[] = _TEXT("Failed to register window class.");
const TCHAR Win32AppHelper::CREATE_WINDOW_ERROR[] = _TEXT("Failed to create window.");
// other error strings used
const TCHAR Win32AppHelper::CREATE_D3D_ERROR[] = _TEXT("Failed to create main Direct3D object.");
const TCHAR Win32AppHelper::CREATE_DEVICE_ERROR[] = _TEXT("Failed to create Direct3D Device object.");
// variable for tracking Win32 cursor
bool Win32AppHelper::d_mouseInWindow = false;
/*************************************************************************
Create main application window.
*************************************************************************/
HWND Win32AppHelper::createApplicationWindow(int width, int height)
{
WNDCLASS wndClass; // structure used to register window class
// Initialise WNDCLASS structure.
wndClass.style = 0;
wndClass.lpfnWndProc = wndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = GetModuleHandle(0);
wndClass.hIcon = LoadIcon(0, IDI_WINLOGO);
wndClass.hCursor = LoadCursor(0, IDC_ARROW);
wndClass.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
wndClass.lpszMenuName = 0;
wndClass.lpszClassName = APPLICATION_NAME;
HWND window = 0;
// register class. Report error & exit upon failure
if (RegisterClass(&wndClass))
{
// create new window
window = CreateWindow(APPLICATION_NAME, APPLICATION_NAME, WS_OVERLAPPEDWINDOW,
0, 0, width, height, 0, 0, GetModuleHandle(0), 0);
}
else
{
MessageBox(0, REGISTER_CLASS_ERROR, APPLICATION_NAME, MB_ICONERROR|MB_OK);
}
return window;
}
//寻找到有输入焦点的EditBox的左上坐标
bool Win32AppHelper::getFocusedInputBoxCoord(POINT& point, float& height)
{
//遍历所有窗口
CEGUI::WindowManager::WindowIterator wit = CEGUI::WindowManager::getSingleton().getIterator();
while(!wit.isAtEnd())
{
const CEGUI::Window* widget = (*wit)->getActiveChild();
//如果是EditBox或者MultiLineEditBox
if(widget)
{
CEGUI::String windowType = widget->getType();
if(windowType == "TaharezLook/Editbox") //根据具体的scheme来修改
{
const CEGUI::UVector2& winPos = widget->getPosition();
height = widget->getPixelRect().getHeight();
CEGUI::Vector2 winPos1 = CEGUI::CoordConverter::windowToScreen(*widget, winPos);
point.x = winPos1.d_x;
point.y = winPos1.d_y;
return true;
}
}
wit++;
}
return false;
}
bool Win32AppHelper::IMEFollow(HWND hWnd)
{
//判断输入法是否打开
if (!ImmIsIME(GetKeyboardLayout(0)))
return false;
//获得输入框左上坐标
bool result;
POINT point;
float height;
result = getFocusedInputBoxCoord(point, height);
if(!result)
return false;
//获得客户区的坐标
RECT rect;
GetClientRect(hWnd, &rect);
point.x+=rect.left;
point.y+=rect.top;
//设置输入法位置
HIMC hImc = ImmGetContext(hWnd);
if(hImc==NULL) return false;
COMPOSITIONFORM form;
ImmGetCompositionWindow(hImc, &form);
form.ptCurrentPos.x = point.x;
form.ptCurrentPos.y = point.y + height;
ImmSetCompositionWindow(hImc, &form);
return true;
}
// 虚键转扫描码
UINT Win32AppHelper::VirtualKeyToScanCode(WPARAM wParam, LPARAM lParam)
{
if(HIWORD(lParam) & 0x0F00)
{
UINT scancode = MapVirtualKey(wParam, 0);
return scancode | 0x80;
}
else
{
return HIWORD(lParam) & 0x00FF;
}
}
// 中文字符输入
bool Win32AppHelper::ChnInjectChar(CEGUI::utf32 code_point)
{
#ifndef UNICODE
static char s_tempChar[3] = "";
static wchar_t s_tempWchar[2] = L"";
static bool s_flag = false;
unsigned char uch = (unsigned char)code_point;
if( uch >= 0xA1 )
{
if( !s_flag )
{
s_tempChar[0] = (char)uch; //第一个字节
s_flag = true;
return true;
}
else if( uch >= 0xA1 )
{
s_tempChar[1] = (char)uch; //第二个字节
s_flag = false;
MultiByteToWideChar( 0, 0, s_tempChar, 2, s_tempWchar, 1); //转成宽字节
s_tempWchar[1] = L'/0';
CEGUI::utf32 code = (CEGUI::utf32)s_tempWchar[0];
return CEGUI::System::getSingleton().injectChar( code );
}
else
{
return CEGUI::System::getSingleton().injectChar(code_point);
}
}
else
{
s_flag = false;
return CEGUI::System::getSingleton().injectChar(code_point);
}
#else
return CEGUI::System::getSingleton().injectChar(code_point );
#endif
}
/*************************************************************************
Win32 'Window Procedure' function
*************************************************************************/
LRESULT CALLBACK Win32AppHelper::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_CHAR:
// 不要这个
//CEGUI::System::getSingleton().injectChar((CEGUI::utf32)wParam);
// 改用自己的注入
ChnInjectChar((CEGUI::utf32)wParam);
break;
case WM_MOUSELEAVE:
mouseLeaves();
break;
case WM_NCMOUSEMOVE:
mouseLeaves();
break;
case WM_MOUSEMOVE:
mouseEnters();
CEGUI::System::getSingleton().injectMousePosition((float)(LOWORD(lParam)), (float)(HIWORD(lParam)));
break;
case WM_LBUTTONDOWN:
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::LeftButton);
break;
case WM_LBUTTONUP:
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::LeftButton);
break;
case WM_RBUTTONDOWN:
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::RightButton);
break;
case WM_RBUTTONUP:
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::RightButton);
break;
case WM_MBUTTONDOWN:
CEGUI::System::getSingleton().injectMouseButtonDown(CEGUI::MiddleButton);
break;
case WM_MBUTTONUP:
CEGUI::System::getSingleton().injectMouseButtonUp(CEGUI::MiddleButton);
break;
case 0x020A: // WM_MOUSEWHEEL:
CEGUI::System::getSingleton().injectMouseWheelChange(static_cast<float>((short)HIWORD(wParam)) / static_cast<float>(120));
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
// TODO: Notify about new size
{
//if(CEGUI::System::getSingletonPtr())
//{
// RECT rect;
// GetClientRect(hWnd, &rect);
// CEGUI::DirectX9Renderer* dx9render = static_cast<CEGUI::DirectX9Renderer*>(CEGUI::System::getSingletonPtr()->getRenderer());
// dx9render->setDisplaySize(CEGUI::Size(rect.right-rect.left, rect.bottom-rect.top));
//}
}
break;
case WM_PAINT:
{
HDC hDC;
PAINTSTRUCT ps;
hDC = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
}
case WM_KEYDOWN:
{
//输入法跟随
IMEFollow(hWnd);
//输入法状态时,输入不传递到UI系统中去。
UINT vk = (UINT)ImmGetVirtualKey(hWnd);
if(vk == wParam)
break;
CEGUI::System::getSingleton().injectKeyDown((CEGUI::utf32)(VirtualKeyToScanCode(wParam, lParam)));
}
break;
case WM_KEYUP:
CEGUI::System::getSingleton().injectKeyUp((CEGUI::utf32)(VirtualKeyToScanCode(wParam, lParam)));
break;
default:
return(DefWindowProc(hWnd, message, wParam, lParam));
break;
}
return 0;
}
// 鼠标进入区域
void Win32AppHelper::mouseEnters(void)
{
if (!d_mouseInWindow)
{
d_mouseInWindow = true;
ShowCursor(false);
}
}
// 鼠标离开区域
void Win32AppHelper::mouseLeaves(void)
{
if (d_mouseInWindow)
{
d_mouseInWindow = false;
ShowCursor(true);
}
}
// 初始化Direct Input,没用上
bool Win32AppHelper::initialiseDirectInput(HWND window, Win32AppHelper::DirectInputState& dis)
{
//if (SUCCEEDED(DirectInput8Create(GetModuleHandle(0), DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&dis.directInput, 0)))
//{
// if (SUCCEEDED(dis.directInput->CreateDevice(GUID_SysKeyboard, &dis.keyboardDevice, 0)))
// {
// if (SUCCEEDED(dis.keyboardDevice->SetDataFormat(&c_dfDIKeyboard)))
// {
// if (SUCCEEDED(dis.keyboardDevice->SetCooperativeLevel(window, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE)))
// {
// DIPROPDWORD inputProp;
// // the header
// inputProp.diph.dwSize = sizeof(DIPROPDWORD);
// inputProp.diph.dwHeaderSize = sizeof(DIPROPHEADER);
// inputProp.diph.dwObj = 0;
// inputProp.diph.dwHow = DIPH_DEVICE;
// inputProp.dwData = 16;
// if (SUCCEEDED(dis.keyboardDevice->SetProperty(DIPROP_BUFFERSIZE, &inputProp.diph)))
// {
// dis.keyboardDevice->Acquire();
// return true;
// }
// else
// {
// MessageBox(0, _TEXT("Failed to set buffer size for keyboard device."), APPLICATION_NAME, MB_ICONERROR|MB_OK);
// }
// }
// else
// {
// MessageBox(0, _TEXT("Failed to set co-operative level for keyboard device."), APPLICATION_NAME, MB_ICONERROR|MB_OK);
// }
// }
// else
// {
// MessageBox(0, _TEXT("Failed to set data format for keyboard device."), APPLICATION_NAME, MB_ICONERROR|MB_OK);
// }
// dis.keyboardDevice->Release();
// dis.keyboardDevice = 0;
// }
// else
// {
// MessageBox(0, _TEXT("Failed to create DirectInput keyboard device."), APPLICATION_NAME, MB_ICONERROR|MB_OK);
// }
// dis.directInput->Release();
// dis.directInput = 0;
//}
//else
//{
// MessageBox(0, _TEXT("Failed to create main DirectInput object."), APPLICATION_NAME, MB_ICONERROR|MB_OK);
//}
return true;
}
// 清楚Direct Input,没用上
void Win32AppHelper::cleanupDirectInput(Win32AppHelper::DirectInputState& dis)
{
//if (dis.keyboardDevice)
//{
// dis.keyboardDevice->Unacquire();
// dis.keyboardDevice->Release();
// dis.keyboardDevice = 0;
//}
//if (dis.directInput)
//{
// dis.directInput->Release();
// dis.directInput = 0;
//}
}
// 处理Direct Input事件,没用上
void Win32AppHelper::doDirectInputEvents(const Win32AppHelper::DirectInputState& dis)
{
//// handle direct input based inputs
//DIDEVICEOBJECTDATA devDat;
//DWORD itemCount = 1;
//HRESULT res = dis.keyboardDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &devDat, &itemCount, 0);
//if (SUCCEEDED(res))
//{
// if (itemCount > 0)
// {
// if (LOBYTE(devDat.dwData) & 0x80)
// {
// // force quit on ESCAPE key
// if (devDat.dwOfs == CEGUI::Key::Escape)
// {
// PostQuitMessage(0);
// }
// else
// {
// CEGUI::System::getSingleton().injectKeyDown(devDat.dwOfs);
// }
// }
// else
// {
// CEGUI::System::getSingleton().injectKeyUp(devDat.dwOfs);
// }
// }
//}
//else
//{
// // try to re-acquire device if that was the cause of the error.
// if ((res == DIERR_NOTACQUIRED) || (res == DIERR_INPUTLOST))
// {
// dis.keyboardDevice->Acquire();
// }
//}
}
// 处理Win32事件
bool Win32AppHelper::doWin32Events(bool& idle)
{
MSG msg;
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
return false;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
idle = false;
}
else
{
idle = true;
}
return true;
}
#endif
这里仅仅需要注意的是Win32AppHelper.h需要包含"imm.h"和"imm32.lib"。
最后上图:
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/naugthyLeo/archive/2009/05/25/4215687.aspx
- 关于CEGUI的中文输入与显示
- CEGUI/OIS的中文输入与显示
- 实现CEGUI的中文显示和输入
- CEGUI 中文输入的坎坎坷坷
- 关于在ogre的cegui层显示中文
- OGre(1.65)+CEGUI的中文显示和中文输入,新人必看
- ogre与cegui结合之显示中文
- 使用CEGUI的Editbox进行中文输入
- CEGUI编辑框输入中文的解决方案
- CEGUI中文输入的完美解决
- cegui中文输入。。。。
- CEGUI显示中文的一些细节
- CEGUI中文显示问题的解决方法
- CEGUI中文显示问题的解决方法
- CEGUI中文显示提速
- CEGUI显示中文
- CEGUI显示中文解决办法
- CEGUI中文显示提速
- 转之:http://www.cnblogs.com/sopper/archive/2007/06/15/784947.html
- .class文件与.project文件
- sql server 连接池
- 《《锦衣卫》》职场规则
- 利用QQ游戏破解QQ密码
- 关于CEGUI的中文输入与显示
- 转贴的java面试题,有空做做看
- 代码实现程序前后台切换
- 当你输入一个网址的时候,实际会发生什么?
- OGRE3D从新手到入门周边工具集
- 学习ADO和ODBC访问数据库的一些思路整理
- C#日期格式参考小结
- Ogre 天龙八部地形 Heightmap(高度图)+GridInfo(地表信息)初步结果
- vs 2008 显式实现接口 和 隐式实现接口的 区别