summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormichi_cc <michi_cc@openttd.org>2013-08-05 20:37:06 +0000
committermichi_cc <michi_cc@openttd.org>2013-08-05 20:37:06 +0000
commit7422120014b51f0057bb41b3e9b6405957a01b63 (patch)
tree2a56e09275b9e9e75f8be57f4ca1c0b7d39ee3c3 /src
parent13873d2534208ddc4596a9354d23d1e4940339ac (diff)
downloadopenttd-7422120014b51f0057bb41b3e9b6405957a01b63.tar.xz
(svn r25679) -Codechange: [Win32] Get the result string of an IME input directly without a trip through the window messaging system.
Diffstat (limited to 'src')
-rw-r--r--src/console_gui.cpp9
-rw-r--r--src/gfx_func.h1
-rw-r--r--src/textbuf.cpp33
-rw-r--r--src/textbuf_type.h1
-rw-r--r--src/video/win32_v.cpp31
-rw-r--r--src/window.cpp27
-rw-r--r--src/window_gui.h1
7 files changed, 93 insertions, 10 deletions
diff --git a/src/console_gui.cpp b/src/console_gui.cpp
index ce23952d2..0cc2f670e 100644
--- a/src/console_gui.cpp
+++ b/src/console_gui.cpp
@@ -308,6 +308,15 @@ struct IConsoleWindow : Window
return ES_HANDLED;
}
+ virtual void InsertTextString(int wid, const char *str)
+ {
+ if (_iconsole_cmdline.InsertString(str)) {
+ IConsoleWindow::scroll = 0;
+ IConsoleResetHistoryPos();
+ this->SetDirty();
+ }
+ }
+
virtual void OnMouseWheel(int wheel)
{
this->Scroll(-wheel);
diff --git a/src/gfx_func.h b/src/gfx_func.h
index 1e121b4c3..421f9cff6 100644
--- a/src/gfx_func.h
+++ b/src/gfx_func.h
@@ -71,6 +71,7 @@ extern Dimension _cur_resolution;
extern Palette _cur_palette; ///< Current palette
void HandleKeypress(uint keycode, WChar key);
+void HandleTextInput(const char *str);
void HandleCtrlChanged();
void HandleMouseEvents();
void CSleep(int milliseconds);
diff --git a/src/textbuf.cpp b/src/textbuf.cpp
index 58f931f8a..2278be572 100644
--- a/src/textbuf.cpp
+++ b/src/textbuf.cpp
@@ -144,20 +144,18 @@ bool Textbuf::InsertChar(WChar key)
}
/**
- * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard
- * and append this up to the maximum length (either absolute or screenlength). If maxlength
- * is zero, we don't care about the screenlength but only about the physical length of the string
- * @return true on successful change of Textbuf, or false otherwise
+ * Insert a string into the text buffer. If maxwidth of the Textbuf is zero,
+ * we don't care about the visual-length but only about the physical
+ * length of the string.
+ * @param str String to insert.
+ * @return True on successful change of Textbuf, or false otherwise.
*/
-bool Textbuf::InsertClipboard()
+bool Textbuf::InsertString(const char *str)
{
- char utf8_buf[512];
-
- if (!GetClipboardContents(utf8_buf, lengthof(utf8_buf))) return false;
uint16 bytes = 0, chars = 0;
WChar c;
- for (const char *ptr = utf8_buf; (c = Utf8Consume(&ptr)) != '\0';) {
+ for (const char *ptr = str; (c = Utf8Consume(&ptr)) != '\0';) {
if (!IsValidChar(c, this->afilter)) break;
byte len = Utf8CharLen(c);
@@ -171,7 +169,7 @@ bool Textbuf::InsertClipboard()
if (bytes == 0) return false;
memmove(this->buf + this->caretpos + bytes, this->buf + this->caretpos, this->bytes - this->caretpos);
- memcpy(this->buf + this->caretpos, utf8_buf, bytes);
+ memcpy(this->buf + this->caretpos, str, bytes);
this->bytes += bytes;
this->chars += chars;
@@ -187,6 +185,21 @@ bool Textbuf::InsertClipboard()
return true;
}
+/**
+ * Insert a chunk of text from the clipboard onto the textbuffer. Get TEXT clipboard
+ * and append this up to the maximum length (either absolute or screenlength). If maxlength
+ * is zero, we don't care about the screenlength but only about the physical length of the string
+ * @return true on successful change of Textbuf, or false otherwise
+ */
+bool Textbuf::InsertClipboard()
+{
+ char utf8_buf[512];
+
+ if (!GetClipboardContents(utf8_buf, lengthof(utf8_buf))) return false;
+
+ return this->InsertString(utf8_buf);
+}
+
/** Update the character iter after the text has changed. */
void Textbuf::UpdateStringIter()
{
diff --git a/src/textbuf_type.h b/src/textbuf_type.h
index 597615990..7f3673623 100644
--- a/src/textbuf_type.h
+++ b/src/textbuf_type.h
@@ -52,6 +52,7 @@ struct Textbuf {
bool InsertClipboard();
bool InsertChar(uint32 key);
+ bool InsertString(const char *str);
bool DeleteChar(uint16 keycode);
bool MovePos(uint16 keycode);
diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp
index 8d50d812a..c497feb7e 100644
--- a/src/video/win32_v.cpp
+++ b/src/video/win32_v.cpp
@@ -24,6 +24,7 @@
#include "../window_func.h"
#include "win32_v.h"
#include <windows.h>
+#include <imm.h>
/* Missing define in MinGW headers. */
#ifndef MAPVK_VK_TO_CHAR
@@ -498,6 +499,33 @@ static LRESULT HandleCharMsg(uint keycode, WChar charcode)
return 0;
}
+#if !defined(WINCE) || _WIN32_WCE >= 0x400
+/** Handle WM_IME_COMPOSITION messages. */
+static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+ HIMC hIMC = ImmGetContext(hwnd);
+
+ if (hIMC != NULL) {
+ if (lParam & GCS_RESULTSTR) {
+ /* Read result string from the IME. */
+ LONG len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); // Length is always in bytes, even in UNICODE build.
+ TCHAR *str = (TCHAR *)_alloca(len + sizeof(TCHAR));
+ len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, str, len);
+ str[len / sizeof(TCHAR)] = '\0';
+
+ /* Transmit text to windowing system. */
+ if (len > 0) HandleTextInput(FS2OTTD(str));
+
+ /* Don't pass the result string on to the default window proc. */
+ lParam &= ~(GCS_RESULTSTR | GCS_RESULTCLAUSE | GCS_RESULTREADCLAUSE | GCS_RESULTREADSTR);
+ }
+ }
+ ImmReleaseContext(hwnd, hIMC);
+
+ return lParam != 0 ? DefWindowProc(hwnd, WM_IME_COMPOSITION, wParam, lParam) : 0;
+}
+#endif
+
static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
static uint32 keycode = 0;
@@ -633,6 +661,9 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
}
#if !defined(WINCE) || _WIN32_WCE >= 0x400
+ case WM_IME_COMPOSITION:
+ return HandleIMEComposition(hwnd, wParam, lParam);
+
#if !defined(UNICODE)
case WM_IME_CHAR:
if (GB(wParam, 8, 8) != 0) {
diff --git a/src/window.cpp b/src/window.cpp
index 1ef8afa44..522a10a6f 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -2533,6 +2533,33 @@ void HandleCtrlChanged()
}
/**
+ * Insert a text string at the cursor position into the edit box widget.
+ * @param wid Edit box widget.
+ * @param str Text string to insert.
+ */
+/* virtual */ void Window::InsertTextString(int wid, const char *str)
+{
+ QueryString *query = this->GetQueryString(wid);
+ if (query == NULL) return;
+
+ if (query->text.InsertString(str)) {
+ this->SetWidgetDirty(wid);
+ this->OnEditboxChanged(wid);
+ }
+}
+
+/**
+ * Handle text input.
+ * @param str Text string to input.
+ */
+void HandleTextInput(const char *str)
+{
+ if (!EditBoxInGlobalFocus()) return;
+
+ _focused_window->InsertTextString(_focused_window->window_class == WC_CONSOLE ? 0 : _focused_window->nested_focus->index, str);
+}
+
+/**
* Local counter that is incremented each time an mouse input event is detected.
* The counter is used to stop auto-scrolling.
* @see HandleAutoscroll()
diff --git a/src/window_gui.h b/src/window_gui.h
index ade8a3f1d..557fd3145 100644
--- a/src/window_gui.h
+++ b/src/window_gui.h
@@ -489,6 +489,7 @@ public:
bool SetFocusedWidget(int widget_index);
EventState HandleEditBoxKey(int wid, WChar key, uint16 keycode);
+ virtual void InsertTextString(int wid, const char *str);
void HandleButtonClick(byte widget);
int GetRowFromWidget(int clickpos, int widget, int padding, int line_height = -1) const;