Commit 0cea1bc5 authored by mercury233's avatar mercury233

wide char clipboard & IME support

parent 22f631c5
...@@ -26,11 +26,11 @@ public: ...@@ -26,11 +26,11 @@ public:
} }
//! Copies text to the clipboard //! Copies text to the clipboard
virtual void copyToClipboard(const c8* text) const = 0; virtual void copyToClipboard(const c16* text) const = 0;
//! Get text from the clipboard //! Get text from the clipboard
/** \return Returns 0 if no string is in there. */ /** \return Returns 0 if no string is in there. */
virtual const c8* getTextFromClipboard() const = 0; virtual const c16* getTextFromClipboard() const = 0;
//! Get the processor speed in megahertz //! Get the processor speed in megahertz
/** \param MHz The integer variable to store the speed in. /** \param MHz The integer variable to store the speed in.
......
...@@ -48,6 +48,9 @@ typedef __int16 s16; ...@@ -48,6 +48,9 @@ typedef __int16 s16;
typedef signed short s16; typedef signed short s16;
#endif #endif
//! 16 bit character variable.
/** This is a typedef for wchar_t, it ensures portability of the engine. */
typedef wchar_t c16;
//! 32 bit unsigned variable. //! 32 bit unsigned variable.
......
...@@ -287,7 +287,7 @@ bool CGUIEditBox::processKey(const SEvent& event) ...@@ -287,7 +287,7 @@ bool CGUIEditBox::processKey(const SEvent& event)
const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd; const s32 realmbgn = MarkBegin < MarkEnd ? MarkBegin : MarkEnd;
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
core::stringc s; core::stringw s;
s = Text.subString(realmbgn, realmend - realmbgn).c_str(); s = Text.subString(realmbgn, realmend - realmbgn).c_str();
Operator->copyToClipboard(s.c_str()); Operator->copyToClipboard(s.c_str());
} }
...@@ -300,7 +300,7 @@ bool CGUIEditBox::processKey(const SEvent& event) ...@@ -300,7 +300,7 @@ bool CGUIEditBox::processKey(const SEvent& event)
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
// copy // copy
core::stringc sc; core::stringw sc;
sc = Text.subString(realmbgn, realmend - realmbgn).c_str(); sc = Text.subString(realmbgn, realmend - realmbgn).c_str();
Operator->copyToClipboard(sc.c_str()); Operator->copyToClipboard(sc.c_str());
...@@ -330,16 +330,10 @@ bool CGUIEditBox::processKey(const SEvent& event) ...@@ -330,16 +330,10 @@ bool CGUIEditBox::processKey(const SEvent& event)
const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin; const s32 realmend = MarkBegin < MarkEnd ? MarkEnd : MarkBegin;
// add new character // add new character
const c8* p = Operator->getTextFromClipboard(); const c16* p = Operator->getTextFromClipboard();
if (p) if (p)
{ {
// TODO: we should have such a function in core::string irr::core::stringw widep(p);
size_t lenOld = strlen(p);
wchar_t *ws = new wchar_t[lenOld + 1];
size_t len = mbstowcs(ws,p,lenOld);
ws[len] = 0;
irr::core::stringw widep(ws);
delete[] ws;
if (MarkBegin == MarkEnd) if (MarkBegin == MarkEnd)
{ {
......
...@@ -20,6 +20,8 @@ ...@@ -20,6 +20,8 @@
#include "COSOperator.h" #include "COSOperator.h"
#include "dimension2d.h" #include "dimension2d.h"
#include "IGUISpriteBank.h" #include "IGUISpriteBank.h"
#include "IGUIEnvironment.h"
#include "IGUIElement.h"
#include <winuser.h> #include <winuser.h>
#if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_) #if defined(_IRR_COMPILE_WITH_JOYSTICK_EVENTS_)
#ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ #ifdef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
...@@ -749,6 +751,24 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) ...@@ -749,6 +751,24 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
return 0; return 0;
} }
dev = getDeviceFromHWnd(hWnd);
if (dev)
{
irr::gui::IGUIElement* ele = dev->getGUIEnvironment()->getFocus();
if (!ele || (ele->getType() != irr::gui::EGUIET_EDIT_BOX) || !ele->isEnabled())
{
HIMC hIMC = ImmGetContext(hWnd);
if (hIMC)
{
ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
ImmReleaseContext(hWnd, hIMC);
}
ImmAssociateContextEx(hWnd, NULL, 0);
}
else
ImmAssociateContextEx(hWnd, NULL, IACE_DEFAULT);
}
switch (message) switch (message)
{ {
case WM_PAINT: case WM_PAINT:
...@@ -773,7 +793,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) ...@@ -773,7 +793,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
event.KeyInput.Key = (irr::EKEY_CODE)wParam; event.KeyInput.Key = (irr::EKEY_CODE)wParam;
event.KeyInput.PressedDown = (message==WM_KEYDOWN || message == WM_SYSKEYDOWN); event.KeyInput.PressedDown = (message==WM_KEYDOWN || message == WM_SYSKEYDOWN);
#ifdef MAPVK_VSC_TO_VK_EX
const UINT MY_MAPVK_VSC_TO_VK_EX = MAPVK_VSC_TO_VK_EX;
#else
const UINT MY_MAPVK_VSC_TO_VK_EX = 3; // MAPVK_VSC_TO_VK_EX should be in SDK according to MSDN, but isn't in mine. const UINT MY_MAPVK_VSC_TO_VK_EX = 3; // MAPVK_VSC_TO_VK_EX should be in SDK according to MSDN, but isn't in mine.
#endif
if ( event.KeyInput.Key == irr::KEY_SHIFT ) if ( event.KeyInput.Key == irr::KEY_SHIFT )
{ {
// this will fail on systems before windows NT/2000/XP, not sure _what_ will return there instead. // this will fail on systems before windows NT/2000/XP, not sure _what_ will return there instead.
...@@ -904,6 +928,53 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) ...@@ -904,6 +928,53 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
KEYBOARD_INPUT_HKL = GetKeyboardLayout(0); KEYBOARD_INPUT_HKL = GetKeyboardLayout(0);
KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) ); KEYBOARD_INPUT_CODEPAGE = LocaleIdToCodepage( LOWORD(KEYBOARD_INPUT_HKL) );
return 0; return 0;
case WM_IME_STARTCOMPOSITION:
{
dev = getDeviceFromHWnd(hWnd);
irr::gui::IGUIElement* ele = dev->getGUIEnvironment()->getFocus();
if (!ele)
break;
irr::core::position2di pos = ele->getAbsolutePosition().UpperLeftCorner;
COMPOSITIONFORM CompForm = { CFS_POINT, { pos.X, pos.Y + ele->getAbsolutePosition().getHeight() } };
HIMC hIMC = ImmGetContext(hWnd);
ImmSetCompositionWindow(hIMC, &CompForm);
ImmReleaseContext(hWnd, hIMC);
}
break;
case WM_IME_CHAR:
event.EventType = irr::EET_KEY_INPUT_EVENT;
event.KeyInput.PressedDown = true;
#ifdef _UNICODE
event.KeyInput.Char = wParam;
#else
BYTE ch[3];
if (wParam >> 8) {
ch[0] = wParam >> 8;
ch[1] = wParam & 0xff;
ch[2] = 0;
} else {
ch[0] = wParam;
ch[1] = 0;
}
WORD unicodeChar;
MultiByteToWideChar(
KEYBOARD_INPUT_CODEPAGE,
MB_PRECOMPOSED, // default
(LPCSTR)ch,
sizeof(wParam),
(WCHAR*)&unicodeChar,
1);
event.KeyInput.Char = unicodeChar;
#endif
event.KeyInput.Key = irr::KEY_ACCEPT;
event.KeyInput.Shift = 0;
event.KeyInput.Control = 0;
dev = getDeviceFromHWnd(hWnd);
if (dev)
dev->postEventFromUser(event);
return 0;
} }
return DefWindowProc(hWnd, message, wParam, lParam); return DefWindowProc(hWnd, message, wParam, lParam);
} }
...@@ -1797,8 +1868,8 @@ void CIrrDeviceWin32::handleSystemMessages() ...@@ -1797,8 +1868,8 @@ void CIrrDeviceWin32::handleSystemMessages()
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{ {
// No message translation because we don't use WM_CHAR and it would conflict with our // conflict with deadkey handling.
// deadkey handling. TranslateMessage(&msg);
if (ExternalWindow && msg.hwnd == HWnd) if (ExternalWindow && msg.hwnd == HWnd)
WndProc(HWnd, msg.message, msg.wParam, msg.lParam); WndProc(HWnd, msg.message, msg.wParam, msg.lParam);
......
...@@ -52,9 +52,9 @@ const core::stringc& COSOperator::getOperatingSystemVersion() const ...@@ -52,9 +52,9 @@ const core::stringc& COSOperator::getOperatingSystemVersion() const
//! copies text to the clipboard //! copies text to the clipboard
void COSOperator::copyToClipboard(const c8* text) const void COSOperator::copyToClipboard(const c16* text) const
{ {
if (strlen(text)==0) if (wcslen(text)==0)
return; return;
// Windows version // Windows version
...@@ -66,15 +66,15 @@ void COSOperator::copyToClipboard(const c8* text) const ...@@ -66,15 +66,15 @@ void COSOperator::copyToClipboard(const c8* text) const
EmptyClipboard(); EmptyClipboard();
HGLOBAL clipbuffer; HGLOBAL clipbuffer;
char * buffer; wchar_t * buffer;
clipbuffer = GlobalAlloc(GMEM_DDESHARE, strlen(text)+1); clipbuffer = GlobalAlloc(GMEM_DDESHARE, sizeof(wchar_t) * (wcslen(text) + 1));
buffer = (char*)GlobalLock(clipbuffer); buffer = (wchar_t*)GlobalLock(clipbuffer);
strcpy(buffer, text); wcscpy(buffer, text);
GlobalUnlock(clipbuffer); GlobalUnlock(clipbuffer);
SetClipboardData(CF_TEXT, clipbuffer); SetClipboardData(CF_UNICODETEXT, clipbuffer);
CloseClipboard(); CloseClipboard();
// MacOSX version // MacOSX version
...@@ -93,7 +93,7 @@ void COSOperator::copyToClipboard(const c8* text) const ...@@ -93,7 +93,7 @@ void COSOperator::copyToClipboard(const c8* text) const
//! gets text from the clipboard //! gets text from the clipboard
//! \return Returns 0 if no string is in there. //! \return Returns 0 if no string is in there.
const c8* COSOperator::getTextFromClipboard() const const c16* COSOperator::getTextFromClipboard() const
{ {
#if defined(_IRR_XBOX_PLATFORM_) #if defined(_IRR_XBOX_PLATFORM_)
return 0; return 0;
...@@ -101,10 +101,10 @@ const c8* COSOperator::getTextFromClipboard() const ...@@ -101,10 +101,10 @@ const c8* COSOperator::getTextFromClipboard() const
if (!OpenClipboard(NULL)) if (!OpenClipboard(NULL))
return 0; return 0;
char * buffer = 0; wchar_t * buffer = 0;
HANDLE hData = GetClipboardData( CF_TEXT ); HANDLE hData = GetClipboardData( CF_UNICODETEXT );
buffer = (char*)GlobalLock( hData ); buffer = (wchar_t*)GlobalLock( hData );
GlobalUnlock( hData ); GlobalUnlock( hData );
CloseClipboard(); CloseClipboard();
return buffer; return buffer;
......
...@@ -27,11 +27,11 @@ public: ...@@ -27,11 +27,11 @@ public:
virtual const core::stringc& getOperatingSystemVersion() const; virtual const core::stringc& getOperatingSystemVersion() const;
//! copies text to the clipboard //! copies text to the clipboard
virtual void copyToClipboard(const c8* text) const; virtual void copyToClipboard(const c16* text) const;
//! gets text from the clipboard //! gets text from the clipboard
//! \return Returns 0 if no string is in there. //! \return Returns 0 if no string is in there.
virtual const c8* getTextFromClipboard() const; virtual const c16* getTextFromClipboard() const;
//! gets the processor speed in megahertz //! gets the processor speed in megahertz
//! \param Mhz: //! \param Mhz:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment