c# - Simulate input of non-ASCII characters -


i looking way simulate input of non-ascii characters (e.g. cjk characters) using windows apis. keybd_event or sendinput won't work because input characters may not valid virtual keys.

what want

i want simulate input of unicode character(s) using windows api, without needing write ime or tsf provider.

what i've tried

i've tried send wm_ime_char message focused window:

// gets focused input control (if any) internal static intptr getactivewindowcontrol() {     intptr activewin = getforegroundwindow();     if (activewin == intptr.zero)     {         return intptr.zero;     }     uint threadid = getwindowthreadprocessid(activewin, intptr.zero);     guithreadinfo guithreadinfo = new guithreadinfo();     guithreadinfo.cbsize = marshal.sizeof(guithreadinfo);     getguithreadinfo(threadid, ref guithreadinfo);     if (guithreadinfo.hwndfocus == intptr.zero)     {         return activewin; // example: console     }     else     {         return guithreadinfo.hwndfocus;     } }  internal void simulateinput() {     // encoding.default on computer cp950 (big5)     byte[] b = encoding.default.getbytes("我"); // 1 single chinese character     intptr activehwnd = getactivewindowcontrol();     if (activehwnd != intptr.zero)     {         int ch = 0;         (int = 0; < b.length; i++) // assumed b has <=2 elements         {             ch = (ch << 8) | b[i];         }         uint wm_ime_char = 0x0286;         sendmessage(activehwnd, wm_ime_char, (intptr)ch, (intptr)0)     } } 

problem encountered

so far code seems have worked quite in cases, however doesn't work on notepad++. instead of desired character, got garbage input instead.

further investigation using spy++ shows when using ime input, there isn't wm_ime_char message sent notepad++ edit window. wm_ime_startcomposition, wm_ime_endcomposition, wm_ime_request, wm_ime_notify , wm_ime_setcontext. seems notepad++ handles ime input different other programs. (also believe there exist more programs acts similar notepad++, haven't found 1 yet.)

also, code not work if character(s) outside default character encoding of target operating system (e.g. simplified chinese not work big5).

things want prevent

  • putting character(s) in clipboard , invoking paste on target window

additional information

i realize windows 7 tablet pc input panel perform text insertion nicely (even works on gtk+ applications). tried emulate sends appears repeat last ime-entered character. doesn't work appears same seen in spy++.

sendmessage(active, wm_ime_startcomposition, (intptr)0, (intptr)0); //sendmessage(active, wm_ime_composition, (intptr)ch, (intptr)0x0800); sendmessage(active, wm_ime_composition, (intptr)0xa7da, (intptr)0x0800); sendmessage(active, wm_ime_notify, (intptr)0x010d, (intptr)0); sendmessage(active, wm_ime_endcomposition, (intptr)0, (intptr)0); sendmessage(active, wm_ime_notify, (intptr)0x010e, (intptr)0); 

i've found sendkeys class in .net. used in application?

after bit more searching, turned out sendinput could used send unicode input keyeventf_unicode.

now code looks (inputsender own class):

internal static void inputstring(string str) {     char[] chars = str.tochararray();     inputsender.input[] inputs = new inputsender.input[chars.length * 2];      (int = 0; < chars.length; i++)     {         ushort ch = (ushort)chars[i];         // key down         inputs[i * 2].type = inputsender.inputtype.keyboard;         inputs[i * 2].ki.wscan = ch;         inputs[i * 2].ki.dwflags = inputsender.keyboardeventflags.unicode;         // key         inputs[i * 2 + 1].type = inputsender.inputtype.keyboard;         inputs[i * 2 + 1].ki.wscan = ch;         inputs[i * 2 + 1].ki.dwflags = inputsender.keyboardeventflags.unicode | inputsender.keyboardeventflags.keyup;     }     inputsender.sendinput(inputs); } 

but turned out doesn't work quite gtk+ programs. bit searching shows should fixed while ago programs uses older version of gtk+ may still encounter problems. tried newest gtk+ geany newest gtk+ fine, while inkscape refuses interpret input.

anyway if ignore problem of gtk+, using sendinput sufficient (and should better wm_ime_char). haven't tried this answer fixes gtk+'s problem because don't know how , believe not feasible.


Comments

Popular posts from this blog

Delphi XE2 Indy10 udp client-server interchange using SendBuffer-ReceiveBuffer -

Qt ActiveX WMI QAxBase::dynamicCallHelper: ItemIndex(int): No such property in -

Enable autocomplete or intellisense in Atom editor for PHP -