Browse Source

Windows: setup a default handler for ImeSetInputScreenPosFn so IME (Japanese/Chinese) inputs are positioned correctly.

User need to set io.ImeWindowHandle
ocornut 10 years ago
parent
commit
e269125c3a

+ 2 - 0
examples/directx11_example/main.cpp

@@ -448,7 +448,9 @@ void InitImGui()
     io.KeyMap[ImGuiKey_X] = 'X';
     io.KeyMap[ImGuiKey_X] = 'X';
     io.KeyMap[ImGuiKey_Y] = 'Y';
     io.KeyMap[ImGuiKey_Y] = 'Y';
     io.KeyMap[ImGuiKey_Z] = 'Z';
     io.KeyMap[ImGuiKey_Z] = 'Z';
+
     io.RenderDrawListsFn = ImImpl_RenderDrawLists;
     io.RenderDrawListsFn = ImImpl_RenderDrawLists;
+    io.ImeWindowHandle = hWnd;
 
 
     // Create the vertex buffer
     // Create the vertex buffer
     {
     {

+ 1 - 0
examples/directx9_example/main.cpp

@@ -240,6 +240,7 @@ void InitImGui()
     io.KeyMap[ImGuiKey_Z] = 'Z';
     io.KeyMap[ImGuiKey_Z] = 'Z';
 
 
     io.RenderDrawListsFn = ImImpl_RenderDrawLists;
     io.RenderDrawListsFn = ImImpl_RenderDrawLists;
+    io.ImeWindowHandle = hWnd;
     
     
     // Create the vertex buffer
     // Create the vertex buffer
     if (g_pd3dDevice->CreateVertexBuffer(10000 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)
     if (g_pd3dDevice->CreateVertexBuffer(10000 * sizeof(CUSTOMVERTEX), D3DUSAGE_DYNAMIC | D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL) < 0)

+ 12 - 2
examples/opengl3_example/main.cpp

@@ -10,14 +10,21 @@
 #include "../../imgui.h"
 #include "../../imgui.h"
 #include <stdio.h>
 #include <stdio.h>
 
 
-// Gl3w/Glfw
+// Gl3W / GLFW
 #include <GL/gl3w.h>
 #include <GL/gl3w.h>
 #include <GLFW/glfw3.h>
 #include <GLFW/glfw3.h>
-#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
+#ifdef _MSC_VER
+#undef APIENTRY
+#define GLFW_EXPOSE_NATIVE_WIN32
+#define GLFW_EXPOSE_NATIVE_WGL
+#include <GLFW/glfw3native.h>
+#endif
 
 
 static GLFWwindow* window;
 static GLFWwindow* window;
 static bool mousePressed[2] = { false, false };
 static bool mousePressed[2] = { false, false };
 
 
+#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
+
 // Shader variables
 // Shader variables
 static int shader_handle, vert_handle, frag_handle;
 static int shader_handle, vert_handle, frag_handle;
 static int texture_location, proj_mtx_location;
 static int texture_location, proj_mtx_location;
@@ -279,6 +286,9 @@ void InitImGui()
     io.RenderDrawListsFn = ImImpl_RenderDrawLists;
     io.RenderDrawListsFn = ImImpl_RenderDrawLists;
     io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
     io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
     io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
     io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
+#ifdef _MSC_VER
+    io.ImeWindowHandle = glfwGetWin32Window(window);
+#endif
 
 
     LoadFontsTexture();
     LoadFontsTexture();
 }
 }

+ 13 - 3
examples/opengl_example/main.cpp

@@ -10,13 +10,20 @@
 #include "../../imgui.h"
 #include "../../imgui.h"
 #include <stdio.h>
 #include <stdio.h>
 
 
-// Glfw
+// GLFW
 #include <GLFW/glfw3.h>
 #include <GLFW/glfw3.h>
-#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
+#ifdef _MSC_VER
+#undef APIENTRY
+#define GLFW_EXPOSE_NATIVE_WIN32
+#define GLFW_EXPOSE_NATIVE_WGL
+#include <GLFW/glfw3native.h>
+#endif
 
 
 static GLFWwindow* window;
 static GLFWwindow* window;
 static bool mousePressed[2] = { false, false };
 static bool mousePressed[2] = { false, false };
 
 
+#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
+
 // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
 // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
 // If text or lines are blurry when integrating ImGui in your engine:
 // If text or lines are blurry when integrating ImGui in your engine:
 // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
 // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
@@ -92,7 +99,7 @@ static void ImImpl_SetClipboardTextFn(const char* text)
     glfwSetClipboardString(window, text);
     glfwSetClipboardString(window, text);
 }
 }
 
 
-// GLFW callbacks to get events
+// GLFW callbacks
 static void glfw_error_callback(int error, const char* description)
 static void glfw_error_callback(int error, const char* description)
 {
 {
     fputs(description, stderr);
     fputs(description, stderr);
@@ -190,6 +197,9 @@ void InitImGui()
     io.RenderDrawListsFn = ImImpl_RenderDrawLists;
     io.RenderDrawListsFn = ImImpl_RenderDrawLists;
     io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
     io.SetClipboardTextFn = ImImpl_SetClipboardTextFn;
     io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
     io.GetClipboardTextFn = ImImpl_GetClipboardTextFn;
+#ifdef _MSC_VER
+    io.ImeWindowHandle = glfwGetWin32Window(window);
+#endif
 
 
     LoadFontsTexture();
     LoadFontsTexture();
 }
 }

+ 2 - 1
imconfig.h

@@ -18,8 +18,9 @@
 //#define IMGUI_API __declspec( dllexport )
 //#define IMGUI_API __declspec( dllexport )
 //#define IMGUI_API __declspec( dllimport )
 //#define IMGUI_API __declspec( dllimport )
 
 
-//---- Don't implement default clipboard handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions)
+//---- Don't implement default handlers for Windows (so as not to link with OpenClipboard() and others Win32 functions)
 //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS
 //#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS
+//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS
 
 
 //---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions.
 //---- Include imgui_user.inl at the end of imgui.cpp so you can include code that extends ImGui using its private data/functions.
 //#define IMGUI_INCLUDE_IMGUI_USER_INL
 //#define IMGUI_INCLUDE_IMGUI_USER_INL

+ 38 - 27
imgui.cpp

@@ -207,30 +207,7 @@
 
 
      io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, io.Fonts->GetGlyphRangesJapanese());  // Load Japanese characters
      io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels, io.Fonts->GetGlyphRangesJapanese());  // Load Japanese characters
      io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
      io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8()
-
- If you want to input Japanese/Chinese/Korean in the text input widget:
-
-    - when loading the font, pass a range that contains the characters you need, e.g.: io.Fonts->GetGlyphRangesJapanese()
-    - to have the Microsoft IME cursor appears at the right location in the screen, setup a handler for the io.ImeSetInputScreenPosFn function:
-
-        #include <Windows.h>
-        #include <Imm.h>
-        static void ImImpl_ImeSetInputScreenPosFn(int x, int y)
-        {
-          // Notify OS Input Method Editor of text input position
-          HWND hwnd = glfwGetWin32Window(window);
-          if (HIMC himc = ImmGetContext(hwnd))
-          {
-            COMPOSITIONFORM cf;
-            cf.ptCurrentPos.x = x;
-            cf.ptCurrentPos.y = y;
-            cf.dwStyle = CFS_FORCE_POSITION;
-            ImmSetCompositionWindow(himc, &cf);
-          }
-        }
-
-        // Set pointer to handler in ImGuiIO structure
-        io.ImeSetInputScreenPosFn = ImImpl_ImeSetInputScreenPosFn;
+     io.ImeWindowHandle = MY_HWND;      // To input using Microsoft IME, give ImGui the hwnd of your application
 
 
  - tip: the construct 'IMGUI_ONCE_UPON_A_FRAME { ... }' will run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code.
  - tip: the construct 'IMGUI_ONCE_UPON_A_FRAME { ... }' will run the block of code only once a frame. You can use it to quickly add custom UI in the middle of a deep nested inner loop in your code.
  - tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug"
  - tip: you can create widgets without a Begin()/End() block, they will go in an implicit window called "Debug"
@@ -459,6 +436,7 @@ static int          ImTextCountUtf8BytesFromWchar(const ImWchar* in_text, const
 
 
 static const char*  GetClipboardTextFn_DefaultImpl();
 static const char*  GetClipboardTextFn_DefaultImpl();
 static void         SetClipboardTextFn_DefaultImpl(const char* text);
 static void         SetClipboardTextFn_DefaultImpl(const char* text);
+static void         ImeSetInputScreenPosFn_DefaultImpl(int x, int y);
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // Texture Atlas data
 // Texture Atlas data
@@ -562,7 +540,7 @@ ImGuiIO::ImGuiIO()
     MemFreeFn = free;
     MemFreeFn = free;
     GetClipboardTextFn = GetClipboardTextFn_DefaultImpl;   // Platform dependent default implementations
     GetClipboardTextFn = GetClipboardTextFn_DefaultImpl;   // Platform dependent default implementations
     SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
     SetClipboardTextFn = SetClipboardTextFn_DefaultImpl;
-    ImeSetInputScreenPosFn = NULL;
+    ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl;
 }
 }
 
 
 // Pass in translated ASCII characters for text input.
 // Pass in translated ASCII characters for text input.
@@ -8117,11 +8095,13 @@ void ImFont::RenderText(float size, ImVec2 pos, ImU32 col, const ImVec4& clip_re
 
 
 #if defined(_MSC_VER) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS)
 #if defined(_MSC_VER) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS)
 
 
+#ifndef _WINDOWS_
 #define WIN32_LEAN_AND_MEAN
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <windows.h>
+#endif
 
 
 // Win32 API clipboard implementation
 // Win32 API clipboard implementation
-static const char*  GetClipboardTextFn_DefaultImpl()
+static const char* GetClipboardTextFn_DefaultImpl()
 {
 {
     static char* buf_local = NULL;
     static char* buf_local = NULL;
     if (buf_local)
     if (buf_local)
@@ -8163,7 +8143,7 @@ static void SetClipboardTextFn_DefaultImpl(const char* text)
 #else
 #else
 
 
 // Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
 // Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers
-static const char*  GetClipboardTextFn_DefaultImpl()
+static const char* GetClipboardTextFn_DefaultImpl()
 {
 {
     return GImGui->PrivateClipboard;
     return GImGui->PrivateClipboard;
 }
 }
@@ -8185,6 +8165,37 @@ static void SetClipboardTextFn_DefaultImpl(const char* text)
 
 
 #endif
 #endif
 
 
+#if defined(_MSC_VER) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS)
+
+#ifndef _WINDOWS_
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+#include <Imm.h>
+#pragma comment(lib, "imm32")
+
+static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y)
+{
+    // Notify OS Input Method Editor of text input position
+    if (HWND hwnd = (HWND)GImGui->IO.ImeWindowHandle)
+        if (HIMC himc = ImmGetContext(hwnd))
+        {
+            COMPOSITIONFORM cf;
+            cf.ptCurrentPos.x = x;
+            cf.ptCurrentPos.y = y;
+            cf.dwStyle = CFS_FORCE_POSITION;
+            ImmSetCompositionWindow(himc, &cf);
+        }
+}
+
+#else
+
+static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y)
+{
+}
+
+#endif
+
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // HELP
 // HELP
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------

+ 4 - 1
imgui.h

@@ -574,12 +574,15 @@ struct ImGuiIO
     const char* (*GetClipboardTextFn)();
     const char* (*GetClipboardTextFn)();
     void        (*SetClipboardTextFn)(const char* text);
     void        (*SetClipboardTextFn)(const char* text);
 
 
-    // Optional: override memory allocations (default to posix malloc/free). MemFreeFn() may be called with a NULL pointer.
+    // Optional: override memory allocations. MemFreeFn() may be called with a NULL pointer.
+    // (default to posix malloc/free)
     void*       (*MemAllocFn)(size_t sz);
     void*       (*MemAllocFn)(size_t sz);
     void        (*MemFreeFn)(void* ptr);
     void        (*MemFreeFn)(void* ptr);
 
 
     // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME in Windows)
     // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME in Windows)
+    // (default to use native imm32 api on Windows)
     void        (*ImeSetInputScreenPosFn)(int x, int y);
     void        (*ImeSetInputScreenPosFn)(int x, int y);
+    void*       ImeWindowHandle;            // (Windows) Set this to your HWND to get automatic IME cursor positioning.
 
 
     //------------------------------------------------------------------
     //------------------------------------------------------------------
     // Input - Fill before calling NewFrame()
     // Input - Fill before calling NewFrame()