ab.com コミュニティ https://www.activebasic.com/forum/ |
|
SendInputが上手く動作しない https://www.activebasic.com/forum/viewtopic.php?t=2594 |
ページ 1 / 1 |
作成者: | 西野孝雄 [ 2009年10月03日(土) 16:41 ] |
記事の件名: | SendInputが上手く動作しない |
お久しぶりです。宜しくお願いします。 件名のままの質問ですが、まずコードを載せます。 コード: Const INPUT_MOUSE = 0 Const INPUT_KEYBOARD = 1 Const INPUT_HARDWARE = 2 Type INPUT types As DWord ki As KEYBDINPUT End Type Type KEYBDINPUT wVk As Word wScan As Word dwFlags As DWord time As DWord dwExtraInfo As ULONG_PTR End Type Declare Function SendInput Lib "user32" (ByVal cInputs As DWord, ByRef pInputs As INPUT, ByVal cbSize As Long) As DWord Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal uCode As DWord, ByVal uMapType As DWord) As DWord Declare Function GetMessageExtraInfo Lib "user32.dll" () As Long Sub MainWnd_CommandButton1_Click() Dim in As INPUT With in .types = INPUT_KEYBOARD .ki.wVk = VK_LWIN .ki.wScan = MapVirtualKey(VK_LWIN, 0) .ki.dwFlags = KEYEVENTF_EXTENDEDKEY .ki.time = 0 .ki.dwExtraInfo = GetMessageExtraInfo() End With SendInput( 1, in, SizeOf(INPUT) ) Sleep(500) in.ki.dwFlags = KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP SendInput( 1, in, SizeOf(INPUT) ) End Sub 以上の様にして、とりあえず実験でWindowsキーを押してみようとしてるんですが一向に反応が有りません。 他ののキ―も試しましたし、メモ帳やテキストボックスに文字を打つようにしてみましたが変化はありません。 dwExtraInfoの所は0で説明してるページが多いですがGetMessageExtraInfo()で説明してる所もあったので試しましたが変化はありません。 検索して見つけた、個別にSendInputせずにINPUT構造体の配列を作り、まとめてSendInputという方法でも変化はありません。 http://dev.activebasic.com/trac/ablib/changeset/418 AB関連のページ?の様なのですが、気になるところと言えば、 共有体の部分がコメントアウトされていてunion[5] As DWordになっている事です。 AB独自の設定かと思いKEYBDINPUTの内容を順番に入れると マウスがカーソルが右上に飛んだり、スクリーンセーバーが急に立ち上がったり良く分からない動作になります。 一体どこが間違っているのでしょうか。 どなたかご存知の方は教えていただけるとありがたいです。 AB 4.13 OS Win Xp Home SP3 |
作成者: | konisi [ 2009年10月04日(日) 13:50 ] |
記事の件名: | |
Sleepを抜いて、サイズを調整したら上手く行きましたよ。 [ここをクリックすると内容が表示されます]
差分。 コード: Type KEYBDINPUT wVk As Word wScan As Word dwFlags As DWord time As DWord dwExtraInfo As ULONG_PTR padding[7] As Byte End Type Declare Function SendInput Lib "user32" (cInputs As DWord,pInputs As *INPUT,cbSize As Long) As DWord Sub MainWnd_CommandButton1_Click() Dim in[1] As INPUT With in[0] .types=INPUT_KEYBOARD .ki.wVk=VK_LWIN .ki.wScan=MapVirtualKey(.ki.wVk,0) .ki.dwFlags=KEYEVENTF_EXTENDEDKEY .ki.time=0 .ki.dwExtraInfo=GetMessageExtraInfo() End With With in[1] .types=INPUT_KEYBOARD .ki.wVk=VK_LWIN .ki.wScan=MapVirtualKey(.ki.wVk,0) .ki.dwFlags=KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP .ki.time=0 .ki.dwExtraInfo=GetMessageExtraInfo() End With SendInput(2,in,SizeOf(INPUT)) End Sub |
作成者: | 西野孝雄 [ 2009年10月05日(月) 07:59 ] |
記事の件名: | SendInputが上手く動作しない |
konisiさん、返信ありがとうございます。 書かれた通りにやるとちゃんと動作してくれました。 しかしなぜこのような事が起きるのでしょうか? INPUT構造体が前回書いたアドレス先の様にするのが正解だとすると サイズはDWORDが7つで28バイト。 コード: Type INPUT types As DWord union[5] As DWord End Type前回書いたINPUT構造体では8バイト足りないので padding[7] As Byte で確かに数値は合いますが これはAB独自の仕様なのでしょうか? それとも何か別の理由があるのでしょうか? 後の為にも知っておきたいので教えて下さい。 |
作成者: | konisi [ 2009年10月05日(月) 17:46 ] |
記事の件名: | |
MSDNのSendInputに関する記事によると、 引用: cbSize と書いてあります。つまりこれはWindowsのAPIの仕様です。INPUT 構造体のサイズを指定します。cbSize パラメータの値が INPUT 構造体のサイズと等しくない場合、関数は失敗します。 同じ関数でマウスやキーボードやハードウェアを同期式に割り込み無しに順番に操作する為に、構造体のサイズを揃えたかったのでしょう。 揃える意味があんまないような気もするけど。 #大学から投稿してみる。 |
作成者: | 西野孝雄 [ 2009年10月06日(火) 07:49 ] |
記事の件名: | SendInputが上手く動作しない |
konisiさん、すいません。私の書き方が解り難かったですね。 構造体のサイズが違うとダメなのは分るのですが 聞きたかったのは、ABではなぜ構造体のサイズ調整が必要なのかなという事です。 SendInputで検索しても当然、ABでの説明は皆無なのですが 他言語の説明で、構造体のサイズ調整をしている物などひとつもなかったので これはAB特有の問題なのかなと思ったわけです。 |
作成者: | Toshi [ 2009年10月06日(火) 14:35 ] |
記事の件名: | |
C++ での宣言はこうなっています。 コード: typedef struct tagINPUT { DWORD type; union { MOUSEINPUT mi; KEYBDINPUT ki; HARDWAREINPUT hi; }; } INPUT, *PINPUT, FAR* LPINPUT;このとき、INPUT 構造体のサイズは共用体の中で一番大きい MOUSEINPUT 構造体に合わせられ、28 バイトになります。(32 ビットの場合) そして、SendInput API に渡すときにはそのサイズでないと受け付けてくれません。 今回の場合、最初の宣言で INPUT 構造体を「KEYBDINPUT 専用」にしていますよね。 コード: Type INPUT types As DWord ki As KEYBDINPUT End Type Type KEYBDINPUT wVk As Word wScan As Word dwFlags As DWord time As DWord dwExtraInfo As ULONG_PTR End Typeこのとき KEYBDINPUT のサイズが 16 バイトになり INPUT 構造体のサイズは 20 バイトです。 しかしサイズを 28 バイトにして渡さなければなりませんので、 コード: padding[7] As Byteこれを足すことで合わせます。 AB は今のところ共用体が使えませんので、このような対処が必要になります。 |
作成者: | NoWest [ 2009年10月06日(火) 23:27 ] |
記事の件名: | Re: SendInputが上手く動作しない |
引用: > SendInputで検索しても当然、ABでの説明は皆無なのですが
混乱させてしまったようで、申し訳ないです。ページをコミットした者です。> 他言語の説明で、構造体のサイズ調整をしている物などひとつもなかったので 既にkonisiさんとToshiさんが書き込まれているように、 今回の問題はWin32APIの仕様を踏まえて、 共用体を用いて実装されているC++用のINPUT構造体を 共用体を使用することができないActiveBasic用に実装する必要に迫られたので 仕方なくパディング調整を行っていることが原因です。 ただし、ActiveBasicはメモリ操作(ポインタ操作)が可能なので、 コード: Type INPUT types As DWord union[5] As DWord End Typeをそのまま使っていただいて コード: Dim input As INPUT Dim pki As *KEYBDINPUT pki = input.union As *KEYBDINPUTのようにすればKEYBDINPUT専用のINPUT構造体を作成する必要はありません。 同様にMOUSEINPUT構造体もHARDWAREINPUT構造体も読み込めます。 逆に書き込みたい場合は コード: Dim ki As KEYBDINPUT memcpy(input.union As VoidPtr,VarPtr(ki) As VoidPtr,SizeOf(KEYBDINPUT))とすることもできます。 引用: > これはAB特有の問題なのかなと思ったわけです。
共用体を仕様に持たない言語であればAB以外でもこの問題は発生します。ただし、Win32API自体が共用体を必ずしも必要としている訳ではありません。 Win32APIが必要としているのはあるメモリ領域に指定のフォーマットで 且つデータの基本サイズが28byteの1つ以上の並びです。 |
作成者: | 西野孝雄 [ 2009年10月07日(水) 08:05 ] |
記事の件名: | SendInputが上手く動作しない |
Toshiさん、NoWestさん、 とてもわかりやすい説明ありがとうございます。 サイズが共用体の中で一番大きい構造体に合わせられるってのがポイントですね。 それで、共有体が使えないからKEYBDINPUT専用にしたのが原因ですね。 いやぁ、凄く納得しました。本当にありがとうございます。 |
ページ 1 / 1 | 全ての表示時間は UTC+09:00 です |
Powered by phpBB® Forum Software © phpBB Limited https://www.phpbb.com/ |