블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2797)
Unity3D (853)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (185)
협업 (61)
3DS Max (3)
Game (12)
Utility (68)
Etc (98)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (55)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

Hello :)

I'm working on a bit of a 2D engine and want it to work with the IME.  Now, normally with a desktop app you don't need any particularly special IME support for an IME to work with your app, you can just start typing in a text box and voila, asian characters (for the most part).  What's actually happening when you're typing asian characters is the IME is drawing windows above your application's window that contains these characters, as I understand it.  In a fullscreen game without typical input widgets, the IME has no idea where to display these windows, and even if it knew where to display those widgets, they wouldn't show up in your fullscreen app.  This means you need to read and send information to the IME directly and take any information you get from it and duplicate what it would've done by itself had you been making a regular desktop app (meaning, draw your own character candidate display, composition display, etc)

My
 2D engine thus far is in .NET 2.0 C# Managed DX.  In the August 2006 SDK, the VC++ DX utility classes contain an example textbox class that contains IME support.  The Managed DX utility classes do not contain any IME support example.  Most of the information I've found by researching around is only for desktop apps that want to extend their support for IMEs beyond the default, rather than support for fullscreen apps.


First I'll lay out what information I've found to be useful in this endeavor:

MSDN: Using an Input Method Editor in a Game (this helps to explain the VC++ DX textbox IME example)
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/Using_an_Input_Method_Editor_in_a_Game.asp

MSDN: Input Method Editor Function Reference
http://msdn.microsoft.com/library/en-us/intl/ime_038z.asp

Header file containing actual enumeration values I didn't find anywhere else
http://www.rpi.edu/dept/cis/software/yesterday/g77-mingw32/include/imm.h

August 2006 SDK C++ DXUT class containing textbox with IME support
C:\Program Files\Microsoft DirectX SDK (August 2006)\Samples\C++\DXUT\Optional\DXUTgui.cpp

Some IME Reference Stuff
http://www.osronline.com/ddkx/appendix/imeimes2_35ph.htm
http://www.osronline.com/ddkx/appendix/imeimes_0h2s.htm

Misc IME Related C# Code
http://www.koders.com/csharp/fidEB8980C0605213D81D1D8364B00F09538F1DF83D.aspx
http://tsuge.astgate.biz/witchgarden/?C%23+Tips%2FWitchPaper%A4%C7%BC%C2%C1%F5%A4%B7%A4%BFIME%C0%A9%B8%E6
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=7712&forum=7

.NET Win32 API Reference Stuff (since you need to use external functions in imm32.dll and user32.dll)
http://www.dotnetwire.com/frame_redirect.asp?newsid=5368
http://www.pinvoke.net/
http://custom.programming-in.net/


So, that's where I'm coming from.  Here's where I'm at.  If you are familiar with the IME language bar, the floating toolbar allows you to select which input language you'd like to use at the moment, along with the input mode.  This input language and other details that you select are context sensitive and will only be used for the window/thread you set them in.  So if you open up Notepad.exe and switch to Japanese input, you'll have Japanese input available in Notepad, but if you switch to another Notepad.exe that you happened to have open, you'll still be in English language mode (until you set it to Japanese also).

Now, if you click somewhere on an app that isn't a textbox, so you have no text entry area selected while you're in Japanese input mode, you'll notice all of the icons on the IME language bar go disabled, naturally, because you can't input anything, so it won't bother trying to handle any input or send any characters.  The second you select a text entry area, bam, those icons become available again.

When I run my 2D engine in windowed mode and watch the IME language bar, I can use the ALT+SHIFT hotkey to switch language modes and receive that window message via WndProc, allowing me to spew text in my engine that says what the current input language is set to, but all of the language bar icons are disabled.  This is common sense and is expected.

The problem is, so far I have had no luck in getting the IME to recognize the input context and accept my commands to it to switch the ConversionStatus or even to begin it's composition string for me to detect. I'm not sure if I have to tell it to start a composition string and then it notifies the window back that it's starting, or if I just wait, but it won't bother starting any composition string until it's even in the right conversion mode (I imagine).

So now, I will refer to an area of the MSDN: Using an Input Method Editor in a Game (link above) article that has been stuck in my head.

"A full-screen application must properly handle the following IME-related messages:

"
I am handling WM_INPUTLANGCHANGE(via the .NET built in OnInputLanguageChange) and WM_IME_SETCONTEXT.  The other messages I won't receive until the IME is ready to do something, and so far I haven't gotten the IME to be ready to actually do anything :). I am sure there's more I need to do than just get these basic messages and respond to them, because it doesn't seem to be doing much.  If anyone knows anyone who might be able to point me in the right direction, it would be magically delicious.


For now, here is some of the code.  I have created a namespace called External that has a class called IME in it.  So IME.Something is referring to stuff in this class.  I have all of the dll imports and struct values contained in it.

// Incoming Window Message Events
protected override void WndProc(ref Message m) {
   switch ((IME.Message)m.Msg) {
      case IME.Message.WM_IME_SETCONTEXT:
         IME.imcHandle = IME.ImmGetContext(this.Handle);
         USER32.SendMessage(IME.imcHandle, m.Msg, m.WParam, IntPtr.Zero);
         IME.ImmReleaseContext(this.Handle, IME.imcHandle);
         break;
   }

   base.WndProc(ref m);
}

// OnInputLanguageChanged Event
protected override void OnInputLanguageChanged(InputLanguageChangedEventArgs e) {

   // Get IMC Handle
   IME.imcHandle = IME.ImmGetContext(this.Handle);

   // Get language and layout details
  
keys.languageFullName = e.InputLanguage.Culture.EnglishName;
   keys.languageShortName = e.InputLanguage.Culture.TwoLetterISOLanguageName;
   keys.layoutID = e.InputLanguage.Culture.KeyboardLayoutId;

   // Get current Conversion and Sentence Modes into IME.current*
  
IME.ImmGetConversionStatus(IME.imcHandle,ref IME.currentConversionMode,ref IME.currentSentenceMode);

   if (IME.currentConversionMode == 0 && keys.languageShortName == "ja") {
      IME.currentConversionMode = (int) IME.ConversionMode.IME_CMODE_NATIVE;
      IME.currentSentenceMode = (int) IME.SentenceMode.IME_SMODE_AUTOMATIC;

      IME.ImmSetConversionStatus(IME.imcHandle,(int)IME.ConversionMode.IME_CMODE_NATIVE | (int) IME.ConversionMode.IME_CMODE_FULLSHAPE, (int)IME.SentenceMode.IME_SMODE_AUTOMATIC);

   }

   if (IME.currentConversionMode != 0 && keys.languageShortName == "en") {
      IME.currentConversionMode = 0;
      IME.currentSentenceMode = (int) IME.SentenceMode.IME_SMODE_NONE;

      IME.ImmSetConversionStatus(IME.imcHandle, (int) IME.ConversionMode.IME_CMODE_ALPHANUMERIC, (int) IME.SentenceMode.IME_SMODE_NONE);

   }

   // Release IMC Handle
   IME.ImmReleaseContext(this.Handle, IME.imcHandle);

   base.OnInputLanguageChanged(e);

}


Of course that is only a very small portion of code that will be necessary for this whole thing to work when it's complete.  I'll also restate, I do not expect this code to do what I'm after, I'm looking for info on what to do next in order to achieve the desired result.  I've tried a couple things, but if anyone has done this before or has further insight, it would sure speed things up.  I imagine it's something very simple.

-Crache


출처 : http://social.msdn.microsoft.com/forums/en-US/gametechnologiesdirectx101/thread/32e53d65-4f99-4e47-9207-7254a96af33e/

반응형
Posted by blueasa
, |