- PR -

キーボードの自動入力について[C#]

投稿者投稿内容
ant
常連さん
会議室デビュー日: 2004/03/24
投稿数: 44
投稿日時: 2004-04-08 11:28
引用:

Jittaさんの書き込み (2004-04-08 08:28) より:

 SendKeyも、中はSendInputを呼んでいるだけ、つまりラッパーだと思いますよ。

 まぁ、暇があれば作ってみます。要はWin32APIのラッパーなので。



いえ、SendKeysのSendメソッド(SendWaitは内部的にSendを呼び出している)は実際にはSetKeyboardStateを呼び出しています。それはNum Lockキーなどのインジケータランプなどの様子からも明らかです。
シゲル
常連さん
会議室デビュー日: 2004/04/03
投稿数: 27
投稿日時: 2004-04-08 11:39
引用:

ぢゃん♪さんの書き込み (2004-04-08 11:16) より:
引用:

シゲルさんの書き込み (2004-04-08 11:09) より:

ボタンを押した後にきちんと直前のウィンドウがアクティブになっています。


いえ、問題は「押した後」ではなく「押した瞬間」の方ですよ。
つまり、SendKeys.SendWaitを実行している瞬間に、どのウィンドウがアクティブで、どのコントロールにフォーカスがあるか、が関わってきます。



プログラム的には、ボタンを押すと
直前のウィンドウがアクティブになり、
それからSendWait("^c");しています。

プログラム的にはそうだけれども、
実際の処理では、SendWait("^c");する瞬間には
まだ直前のウィンドウがアクティブになっていない
ということがありうるんでしょうか?

なんだかあり得そうな気もしますね。

ということは、SendWaitする前に、
直前のウィンドウがアクティブになっているかどうかを
確認すればよいということですね?

直前のウィンドウをアクティブにするのに、
SetForegroundWindowを使っていますが
たとえばSendWaitのように、
その処理が終わるまで他の処理をストップさせるような
方法ってなにかあるんでしょうか?



[ メッセージ編集済み 編集者: シゲル 編集日時 2004-04-08 11:47 ]
シゲル
常連さん
会議室デビュー日: 2004/04/03
投稿数: 27
投稿日時: 2004-04-08 11:49
引用:

antさんの書き込み (2004-04-08 11:28) より:
引用:

Jittaさんの書き込み (2004-04-08 08:28) より:

 SendKeyも、中はSendInputを呼んでいるだけ、つまりラッパーだと思いますよ。

 まぁ、暇があれば作ってみます。要はWin32APIのラッパーなので。



いえ、SendKeysのSendメソッド(SendWaitは内部的にSendを呼び出している)は実際にはSetKeyboardStateを呼び出しています。それはNum Lockキーなどのインジケータランプなどの様子からも明らかです。



ということは、SendWaitではだめでも、
SendInputならうまくいく可能性はあるんですよね?
todo
ぬし
会議室デビュー日: 2003/07/23
投稿数: 682
投稿日時: 2004-04-08 12:50
引用:

シゲルさんの書き込み (2004-04-08 11:39) より:
直前のウィンドウをアクティブにするのに、
SetForegroundWindowを使っていますが
たとえばSendWaitのように、
その処理が終わるまで他の処理をストップさせるような
方法ってなにかあるんでしょうか?


自アプリのフォームであれば、
prvForm2.Activate();
でいいのでしょうけど、SetForegroundWindowを使っているところを見ると
他のアプリをアクティブするのですよね。
SetForegroundWindowの後、少しsleepしてGetForegroundWindowで確認するとか。

追加:
あるいは、VB.NETのAppActivate関数を使う(既出)


[ メッセージ編集済み 編集者: todo 編集日時 2004-04-08 12:59 ]
シゲル
常連さん
会議室デビュー日: 2004/04/03
投稿数: 27
投稿日時: 2004-04-08 14:15
引用:

todoさんの書き込み (2004-04-08 12:50) より:
引用:

シゲルさんの書き込み (2004-04-08 11:39) より:
直前のウィンドウをアクティブにするのに、
SetForegroundWindowを使っていますが
たとえばSendWaitのように、
その処理が終わるまで他の処理をストップさせるような
方法ってなにかあるんでしょうか?


自アプリのフォームであれば、
prvForm2.Activate();
でいいのでしょうけど、SetForegroundWindowを使っているところを見ると
他のアプリをアクティブするのですよね。
SetForegroundWindowの後、少しsleepしてGetForegroundWindowで確認するとか。

追加:
あるいは、VB.NETのAppActivate関数を使う(既出)


[ メッセージ編集済み 編集者: todo 編集日時 2004-04-08 12:59 ]



GetForegroundWindow やってみました。

do{
SetForegroundWindow(hd);
}while(hd != GetForegroundWindow());

でも、やはりSendWait()は効いたり効かなかったりです。

やはり、Windowだけではなく、コントロールにフォーカスが
あたってないとだめってことではないかと思います。

とりあえず、SendInputを試す前に直前のウィンドウだけではなく、
コントロールにもフォーカスが戻っているかどうかを
確認してから、SendWait()しようと思っています。

そこで、Window内で最後にアクティブだったコントロールって、
どうやったらわかるんでしょう?








Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2004-04-08 15:00
 「見た目」は、ちゃんとフォームにフォーカスが移っているのでしょうか?アクティブタイトルバーの色などで確認できると思いますが。
 また、コントロール以外のキーはどうでしょう?たとえば、ALTキーだけ送ると、ツールメニューがアクティブ?になりますが、そういうのは確認できますか?

 あと、特定のコントロールにフォーカスがない「電卓」とか、「メモ帳」に適当な文字列を送り込むとか。
シゲル
常連さん
会議室デビュー日: 2004/04/03
投稿数: 27
投稿日時: 2004-04-08 16:10
引用:

Jittaさんの書き込み (2004-04-08 15:00) より:
 「見た目」は、ちゃんとフォームにフォーカスが移っているのでしょうか?アクティブタイトルバーの色などで確認できると思いますが。
 また、コントロール以外のキーはどうでしょう?たとえば、ALTキーだけ送ると、ツールメニューがアクティブ?になりますが、そういうのは確認できますか?

 あと、特定のコントロールにフォーカスがない「電卓」とか、「メモ帳」に適当な文字列を送り込むとか。



見た目ではきちんと直前のウィンドウがアクティブになっています。
やはり、コントロールにフォーカスがあたっていないときに、
SendWait()されているものと思います。
きっと微妙なタイミングでずれているのだと思います。

しかし、直前にアクティブだったウィンドウ内で、
フォーカスされていたコントロールをチェックするのは
今のぼくには難しすぎるので、
他にいい方法がないかと考えたところ、
クリップボードにある文字列が、
ボタンを押す前のものと変更になるまで、
do・・・whileでSendWaitを繰り返させるという方法を思いつきました。

それで、これを試してみたところ、
なんと、きちんとクリップボードに文字列を
送れるようにはなりました!

しかし、なにか処理が遅いような感じです。
シゲル
常連さん
会議室デビュー日: 2004/04/03
投稿数: 27
投稿日時: 2004-04-08 17:37
一応、望んだ結果が得られるようになりました。

Jittaさん、todoさん、antさん、MMXさん、ゆうじゅんさん、おさるさん、ぢゃん♪さん

約2週間前から勉強を始めて、
初めてWindowsアプリケーションを作りはじめた超初心者のぼくに
いろいろと親切に教えていただき本当にありがとうございました。

今後もまたすぐに問題にぶち当たると思いますが、
その節にはまたよろしくお願いいたします。

今回は本当にありがとうございました。



スキルアップ/キャリアアップ(JOB@IT)