Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9525

C# - SendInputでマルチバイト文字列を送信する

$
0
0

経緯

MS Wordの書式なしコピーの振る舞いが気に食わなかった(MS Office特有の余計なお世話を色々としてくれる)ので、キー入力を模擬することでプレーンテキストを入力できるようなプログラム素材を作っておこうと思いたった。

キャプチャ

image.png

Send text ボタンを押すと、カウントダウンを開始し、6秒後に直下のテキストボックス内の文字列をSendInputで送信します。(カウントダウン中に、SendInputを流し込みたいウィンドウやコントロールにフォーカスを合わせてください。)

※受け取り側によっては対応していない可能性があります。
ちなみにWordではIMEの状態によって挙動が変わるっぽい。(「あ」(全角)の状態だと、SendInputが行われたあとに、変換候補の選択状態になった。)

ソースコード

usingSystem;usingSystem.Drawing;usingSystem.Runtime.InteropServices;usingSystem.Threading;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;classMainForm:Form{TextBoxtxt;Buttonbtn;System.Windows.Forms.Timertmr;int_counter;MainForm(){_counter=0;tmr=newSystem.Windows.Forms.Timer();tmr.Interval=200;tmr.Tick+=(s,e)=>{if(_counter>0){_counter--;intinMsec=_counter*tmr.Interval;Text=(inMsec/1000).ToString()+"."+((inMsec%1000)/100).ToString();}else{tmr.Stop();txt.ReadOnly=false;btn.Enabled=true;SendKeyInput(txt.Text);}};btn=newButton(){Size=newSize(100,30),Text="Test",};btn.Click+=(s,e)=>{txt.ReadOnly=true;btn.Enabled=false;if(!tmr.Enabled){_counter=30;tmr.Start();}};Controls.Add(btn);txt=newTextBox(){Location=newPoint(0,30),Size=newSize(100,30),Text="Test",};Controls.Add(txt);}privatestaticclassNativeMethods{[DllImport("user32.dll",SetLastError=true)]publicexternstaticvoidSendInput(intnInputs,Input[]pInputs,intcbsize);//[DllImport("user32.dll", EntryPoint = "MapVirtualKeyA")]//public extern static int MapVirtualKey(int wCode, int wMapType);//[DllImport("user32.dll", SetLastError = true)]//public extern static IntPtr GetMessageExtraInfo();}[StructLayout(LayoutKind.Sequential)]privatestructPOINT{publicintx;publicinty;}[StructLayout(LayoutKind.Sequential)]structMouseInput{publicintX;publicintY;publicintData;publicintFlags;publicintTime;publicIntPtrExtraInfo;}[StructLayout(LayoutKind.Sequential)]structKeyboardInput{publicshortVirtualKey;publicshortScanCode;publicintFlags;publicintTime;publicIntPtrExtraInfo;}[StructLayout(LayoutKind.Sequential)]structHardwareInput{publicintuMsg;publicshortwParamL;publicshortwParamH;}[StructLayout(LayoutKind.Sequential)]structInput{publicintType;publicInputUnionui;}[StructLayout(LayoutKind.Explicit)]structInputUnion{[FieldOffset(0)]publicMouseInputMouse;[FieldOffset(0)]publicKeyboardInputKeyboard;[FieldOffset(0)]publicHardwareInputHardware;}privateconstintKEYEVENTF_EXTENDEDKEY=0x0001;privateconstintKEYEVENTF_KEYUP=0x0002;privateconstintKEYEVENTF_SCANCODE=0x0008;privateconstintKEYEVENTF_UNICODE=0x0004;privateconstintMAPVK_VK_TO_VSC=0;// private const int MAPVK_VSC_TO_VK = 1;voidSendKeyInput(strings){BeginInvoke((MethodInvoker)delegate(){SendInputKeyPressAndRelease(s);});}privatestaticvoidSendInputKeyPressAndRelease(strings){Input[]inputs=newInput[2*s.Length];for(intk=0;k<s.Length;k++){inttk=s[k];//int vsc = NativeMethods.MapVirtualKey(tk, MAPVK_VK_TO_VSC);inputs[2*k]=newInput();inputs[2*k].Type=1;// KeyBoard = 1inputs[2*k].ui.Keyboard.VirtualKey=0;inputs[2*k].ui.Keyboard.ScanCode=(short)tk;inputs[2*k].ui.Keyboard.Flags=KEYEVENTF_UNICODE;inputs[2*k].ui.Keyboard.Time=0;inputs[2*k].ui.Keyboard.ExtraInfo=IntPtr.Zero;inputs[2*k+1]=newInput();inputs[2*k+1].Type=1;// KeyBoard = 1inputs[2*k+1].ui.Keyboard.VirtualKey=0;inputs[2*k+1].ui.Keyboard.ScanCode=(short)tk;inputs[2*k+1].ui.Keyboard.Flags=KEYEVENTF_UNICODE|KEYEVENTF_KEYUP;inputs[2*k+1].ui.Keyboard.Time=0;inputs[2*k+1].ui.Keyboard.ExtraInfo=IntPtr.Zero;}NativeMethods.SendInput(inputs.Length,inputs,Marshal.SizeOf(inputs[0]));}[STAThread]staticvoidMain(string[]args){Application.Run(newMainForm());}}

参考サイト

https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-keybdinput


Viewing all articles
Browse latest Browse all 9525

Trending Articles