ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2024年3月29日(金) 05:10

全ての表示時間は UTC+09:00 です




新しいトピックを投稿する  トピックへ返信する  [ 8 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2009年10月03日(土) 16:41 
お久しぶりです。宜しくお願いします。
件名のままの質問ですが、まずコードを載せます。
コード:
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


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2009年10月04日(日) 13:50 
オフライン

登録日時: 2005年7月25日(月) 13:27
記事: 893
お住まい: 埼玉県東松山市
Sleepを抜いて、サイズを調整したら上手く行きましたよ。

_________________
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。


通報する
ページトップ
投稿記事Posted: 2009年10月05日(月) 07:59 
konisiさん、返信ありがとうございます。

書かれた通りにやるとちゃんと動作してくれました。
しかしなぜこのような事が起きるのでしょうか?
INPUT構造体が前回書いたアドレス先の様にするのが正解だとすると
サイズはDWORDが7つで28バイト。
コード:
Type INPUT 
    types As DWord 
    union[5] As DWord
End Type
前回書いたINPUT構造体では8バイト足りないので
padding[7] As Byte で確かに数値は合いますが
これはAB独自の仕様なのでしょうか?
それとも何か別の理由があるのでしょうか?
後の為にも知っておきたいので教えて下さい。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2009年10月05日(月) 17:46 
オフライン

登録日時: 2005年7月25日(月) 13:27
記事: 893
お住まい: 埼玉県東松山市
MSDNのSendInputに関する記事によると、
引用:
cbSize
INPUT 構造体のサイズを指定します。cbSize パラメータの値が INPUT 構造体のサイズと等しくない場合、関数は失敗します。
と書いてあります。つまりこれはWindowsのAPIの仕様です。
同じ関数でマウスやキーボードやハードウェアを同期式に割り込み無しに順番に操作する為に、構造体のサイズを揃えたかったのでしょう。
揃える意味があんまないような気もするけど。

#大学から投稿してみる。

_________________
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。


通報する
ページトップ
投稿記事Posted: 2009年10月06日(火) 07:49 
konisiさん、すいません。私の書き方が解り難かったですね。

構造体のサイズが違うとダメなのは分るのですが
聞きたかったのは、ABではなぜ構造体のサイズ調整が必要なのかなという事です。

SendInputで検索しても当然、ABでの説明は皆無なのですが
他言語の説明で、構造体のサイズ調整をしている物などひとつもなかったので
これはAB特有の問題なのかなと思ったわけです。


通報する
ページトップ
   
 記事の件名:
投稿記事Posted: 2009年10月06日(火) 14:35 
オフライン

登録日時: 2005年7月19日(火) 19:47
記事: 98
お住まい: 山形県
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 は今のところ共用体が使えませんので、このような対処が必要になります。

_________________
Toshi's Recess Room
http://toshi.my.land.to/


通報する
ページトップ
投稿記事Posted: 2009年10月06日(火) 23:27 
オフライン

登録日時: 2005年5月31日(火) 10:52
記事: 264
お住まい: 高知
引用:
> 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つ以上の並びです。


通報する
ページトップ
投稿記事Posted: 2009年10月07日(水) 08:05 
Toshiさん、NoWestさん、
とてもわかりやすい説明ありがとうございます。

サイズが共用体の中で一番大きい構造体に合わせられるってのがポイントですね。
それで、共有体が使えないからKEYBDINPUT専用にしたのが原因ですね。

いやぁ、凄く納得しました。本当にありがとうございます。


通報する
ページトップ
   
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 8 件の記事 ] 

全ての表示時間は UTC+09:00 です


オンラインデータ

このフォーラムを閲覧中のユーザー: Ahrefs [Bot] & ゲスト[19人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by ocean