- PR -

Windowsサービスから他EXEの入力エリアにデータセットする方法

投稿者投稿内容
ねね
会議室デビュー日: 2007/07/17
投稿数: 11
投稿日時: 2007-07-17 16:12
WindowsXP
VB.NET
でWindowsサービスアプリを作成し、SendMessageを用いて他EXEの入力エリアにデータをセットしようとしています。
情報として与えられているものは、EXE名("TestEXE")、入力エリア名称です。

他EXEの入力エリアが2つあり、それぞれ違う値をセットしたいのですが、2つの入力エリアの
判別方法が分かりません。
どのように実現させるのか、ぜひご教授ください。

以下、ソース
*******************************************************************************
Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer
Public Declare Function GetDlgItem Lib "user32.dll" Alias "GetDlgItem" (ByVal hDlg As Integer, ByVal nIDDlgItem As Integer) As Integer

Public Const WM_SETTEXT As Short = &HC

---

Dim ps As System.Diagnostics.Process() = System.Diagnostics.Process.GetProcessesByName("TestEXE")
Dim p As System.Diagnostics.Process

'対象EXE実行チェック
w_Wnd = FindWindow(vbNullString, p.MainWindowTitle)
If w_Wnd = 0 Then Exit Sub

'対象EXEエリアハンドル設定(spy++で調査済)
w_Handle = "WindowsForms10.EDIT.app.0.●●●●●"

'対象EXEエリアチェック
w_Child = FindWindowEx(w_Wnd, 0, w_Handle, vbNullString)
If w_Child = 0 Then Exit Sub

'データセット
Call SendMessage(w_Child, WM_SETTEXT, 0, "▲▲▲") 'ユーザーID
Call SendMessage(w_Child, WM_SETTEXT, 0, "●●●") 'パスワード
*****************************************************************************

上記のようにすると、2つある入力エリアのうちの1つにしかデータがセットされません。
入力エリアそれぞれのクラスを設定すれば、と思ったのですが、spy++で調べても
同じ値が返ってきます。
SendMessageでは不可能なのでしょうか?

よろしくお願いします。


ゆうじゅん
ぬし
会議室デビュー日: 2004/01/16
投稿数: 347
投稿日時: 2007-07-17 17:04
試していないのでなんとも言えませんが、以下のようなコードで
うまくいかないでしょうか
コード:
'1つ目の入力エリアを検索 
w_Child = FindWindowEx(w_Wnd, 0, w_Handle, vbNullString) 
If w_Child = 0 Then Exit Sub 

'データセット 
Call SendMessage(w_Child, WM_SETTEXT, 0, "▲▲▲") 'ユーザーID 

'2つ目の入力エリアを検索(検索された子ウィンドウのハンドルを引数にして再検索)
w_Child = FindWindowEx(w_Wnd, w_Child, w_Handle, vbNullString) 
If w_Child = 0 Then Exit Sub 

'データセット 
Call SendMessage(w_Child, WM_SETTEXT, 0, "▲▲▲") 'ユーザーID 

todo
ぬし
会議室デビュー日: 2003/07/23
投稿数: 682
投稿日時: 2007-07-17 17:41
引用:

他EXEの入力エリアが2つあり、それぞれ違う値をセットしたいのですが、2つの入力エリアの
判別方法が分かりません。



コントロールIDからコントロールのウインドウハンドルを取得するのがよいでしょう。

GetDlgItemとSendMessageを使ったサンプル
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=28872&forum=7

SendDlgItemMessage
http://msdn.microsoft.com/library/ja/jpwinui/html/_win32_senddlgitemmessage.asp
ねね
会議室デビュー日: 2007/07/17
投稿数: 11
投稿日時: 2007-07-17 19:00
ゆうじゅんさん

早速ありがとうございます。
指摘していただいたようにCDしたところ
別々のエリアにデータをセットすることができました!

が、以下のようなことが起こります。

-------------------------------------------------
画面上部より
  ユーザーID:[    ]
  パスワード:[ ]
のような画面となっています。

1つ目の入力エリアにユーザーIDをセットしたいのですが
2つ目の入力エリア=パスワードにユーザーIDがセットされます。

検索された子ウィンドウのハンドルを引数にして再検索し
2つ目の入力エリアにパスワードをセットすると、ユーザーIDの
エリアにセットされます。
-------------------------------------------------

これは、入力エリアを検索すると最後の入力エリアから検索される
ということですよね?
勉強不足で申し訳ないのですが、なぜ、最後の入力エリアから認識されるのか
教えていただければと思います。

よろしくお願いします。
ねね
会議室デビュー日: 2007/07/17
投稿数: 11
投稿日時: 2007-07-17 19:26
todoさん

ありがとうございます。
サンプルコーディングでわからない部分があるので教えていただければと思います。
VB.NETでCDしているので、勝手ですがVB.NETに置き換えて質問させてください。

--------------------------------------------------------------------------
@
const int WM_SETTEXT = 0x000c;
const int BM_CLICK = 0x00F5; // ボタンのクリック

この「0x000c」というのは、「12」で、VB.NETでは「&HC」ですよね?

A
// ユーザ名に値を設定する(コントロールID 3EA の 中の3EB)
IntPtr hWndDlg = GetDlgItem(hWnd1, 0x03EA);
if (hWndDlg == IntPtr.Zero) return;
IntPtr hWnd4 = GetDlgItem(hWndDlg, 0x3EB);
if (hWnd4 == IntPtr.Zero) return;

この、「3EA の 中の3EB」というのがわかりません。
C#では「0x03EA=1002」、「0x3EB=1003」、「0x3ED=1005」
という値だったのですが、この値がどこから導かれたのか、VB.NETではどうなるのか。
--------------------------------------------------------------------------

教えていただければと思います。
よろしくお願いします。
ゆうじゅん
ぬし
会議室デビュー日: 2004/01/16
投稿数: 347
投稿日時: 2007-07-18 15:30
引用:

ねねさんの書き込み (2007-07-17 19:00) より:
ゆうじゅんさん

早速ありがとうございます。
指摘していただいたようにCDしたところ
別々のエリアにデータをセットすることができました!

が、以下のようなことが起こります。

-------------------------------------------------
画面上部より
  ユーザーID:[    ]
  パスワード:[ ]
のような画面となっています。

1つ目の入力エリアにユーザーIDをセットしたいのですが
2つ目の入力エリア=パスワードにユーザーIDがセットされます。

検索された子ウィンドウのハンドルを引数にして再検索し
2つ目の入力エリアにパスワードをセットすると、ユーザーIDの
エリアにセットされます。
-------------------------------------------------

これは、入力エリアを検索すると最後の入力エリアから検索される
ということですよね?
勉強不足で申し訳ないのですが、なぜ、最後の入力エリアから認識されるのか
教えていただければと思います。

よろしくお願いします。



FindWindowEXはZオーダー順にWindowを検索します。
参照:http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpwinui/html/_win32_findwindowex.asp

おそらく、タブオーダーの順番が「パスワード」→「ユーザID」になっていると思います。
「TAB」キーを押したら、どの順番でコントロールを移動するか確認してみてください。

あと、コントロールIDはspyで確認できます。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-07-18 15:33
引用:

ゆうじゅんさんの書き込み (2007-07-18 15:30) より:

FindWindowEXはZオーダー順にWindowを検索します。
参照:http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpwinui/html/_win32_findwindowex.asp

引用:
おそらく、タブオーダーの順番が「パスワード」→「ユーザID」になっていると思います。
「TAB」キーを押したら、どの順番でコントロールを移動するか確認してみてください。


? TabIndex と ZOrder は別物ですよね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
ゆうじゅん
ぬし
会議室デビュー日: 2004/01/16
投稿数: 347
投稿日時: 2007-07-18 17:28
引用:

じゃんぬねっとさんの書き込み (2007-07-18 15:33) より:
? TabIndex と ZOrder は別物ですよね。



VCの場合、タブオーダーの変更をするとZオーダーが変更されていたので
同じかと思ったのですが、確認したら.NETはTabIndexが変更されるんですね。

という訳で、私の書き込みは無視して下さい。
申し訳ない。

>スレ主様
わざわざ、Zオーダーを直すぐらいならGetDlgItemを使ったほうがいいと思います。
(画面のレイアウトが変更になった場合、Zオーダーより、コントロールIDのほう
が変更される可能性が低いので、コントロールIDを基準にしたほうが良い)

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