子ウインドウを特定する方法とは?

このQ&Aのポイント
  • VisualBasic2008Expressでプログラミングをしています。楽天ツールバーの検索窓のハンドルを取得してsendmessageで文字列を送るプログラムを作ろうとしています。
  • UISpy.exeで調べてところ"edit"というクラス名で深い階層にあるようで、FindWindowExでは取得できないようです。なので下のURLのコードを基に検索窓のクラス名"edit"からハンドルを取得できるように作り替えようと思っています。
  • 列挙された子ウインドウの中からクラス名"edit"を特定してハンドルを取得するには、どのようにコードを作り直せばよいのでしょうか。何も分からない状態でお手数をおかけするでしょうが、どうかよろしくお願いします。
回答を見る
  • ベストアンサー

子ウインドウを特定する

VisualBasic2008Expressでプログラミングをしています。 楽天ツールバーの検索窓のハンドルを取得してsendmessageで文字列を送るプログラムを作ろうとしています。 UISpy.exeで調べてところ"edit"というクラス名で深い階層にあるようで、FindWindowExでは取得できないようです。なので下のURL http://homepage2.nifty.com/nonnon/SoftSample/VB.NET/SampleEnumWindows.html のコードを基に検索窓のクラス名"edit"からハンドルを取得できるように作り替えようと思っています。 ですが、このenumChildWindowsやGetClassNameの使い方が全く分からない。FindWindowExの場合は、クラス名とタイトル名を指定すればハンドルが返ってくるのですが、これはコールバック関数やポインタが出てきてどう扱えばいいのかが分からず手が出せない状態です。 列挙された子ウインドウの中からクラス名"edit"を特定してハンドルを取得するには、どのようにコードを作り直せばよいのでしょうか。何も分からない状態でお手数をおかけするでしょうが、どうかよろしくお願いします。

noname#255144
noname#255144

質問者が選んだベストアンサー

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

こんな感じでしょうか ★標準モジュール Module Module1     Delegate Function ウィンドウ列挙( _         ByVal ウィンドウ As Integer, _         ByVal ダミー As Integer) As Integer     Declare Function EnumChildWindows Lib "USER32" _         (ByVal ウィンドウ As Integer, _          ByVal コールバック As ウィンドウ列挙, _          ByVal 対象 As Integer) As Integer     Declare Function GetClassName Lib "USER32" Alias "GetClassNameA" _         (ByVal ウィンドウ As Integer, _          ByVal 名前 As String, _          ByVal 文字数 As Integer) As Integer     Declare Function lstrlen Lib "KERNEL32" Alias "lstrlenA" _         (ByVal 文字列 As String) As Integer     Declare Function SysAllocStringByteLen Lib "OLEAUT32" _         (ByVal 文字列 As String, _          ByVal バイト数 As Integer) As String     Public 対象ウィンドウ As Integer     Function コールバック(ByVal ウィンドウ As Integer, _                ByVal ダミー As Integer) As Integer         Dim クラス名 As String         クラス名 = Space(128)         GetClassName(ウィンドウ, クラス名, Len(クラス名))         クラス名 = SysAllocStringByteLen(クラス名, lstrlen(クラス名))         If クラス名 = "edit" Then             対象ウィンドウ = ウィンドウ         Else             EnumChildWindows(ウィンドウ, AddressOf コールバック, 0)             If 対象ウィンドウ = 0 Then コールバック = 1         End If     End Function End Module ★実行例 対象ウィンドウ = 0 EnumChildWindows(Me.Handle, AddressOf コールバック, 0) 原理を説明します。 (1)EnumChildWindowsを実行すると、指定したウィンドウの  子ウィンドをパラメータにしてコールバックを呼び出します。 (2)コールバック内ではパラメータのウィンドウのクラス名を  GetClassNameを使って取得します。 (3)名前領域は広く取ってあるので、必要な部分を整形して  文字列化します。ここでlastrlen(文字列のバイト数を得る)  とSysAllocStringByteLen(VB文字列作成)を使います。 (4)クラス名が"edit"なら共通変数にウィンドウハンドルを  設定します。コールバック関数の戻り値は何も指定しない  ので0(FALSE)になります。EnumChildWindowsはコール  バックが0を返すと列挙を中止します。 (5)クラス名"edit"でない場合は更に内側のウィンドウを列挙  するため、EnumChildWindowsを呼び出します。これで孫、  曾孫、玄孫、・・・と列挙できます。  目的のウィンドウが見つからない場合は戻り値を1(TRUE)に  します。1を返すと列挙が継続されます。 コールバック関数を使うポイントはデリゲード型を定義します。 デリゲードは関数のポインタのようなもので、内部的には ただの整数なのですが、間違った関数形式を指定しないよう 型チェックを厳しくしてあります。

noname#255144
質問者

補足

素早いご回答ありがとうございます。 上記の基にしたコードに追加してみたのですが、GetClassNameのクラス名がString型になったせいかbytClassでエラーになってしまいました。この場合どう書き直せばよいでしょうか。 それとフォームモジュール(Form1.vb) で目的の子ウインドウの情報を表示させるにはどう書き直せばよいのでしょうか。 分からないことだらけで申し訳ないですがどうかよろしくお願いします。

関連するQ&A

  • ウインドウハンドルのつかみ方について質問です。

    visualbasic6.0で開発をしています。 例えば、同親内の子コントロールに同じ「edit」クラスが2つ存在していたとします。 私は、ハンドルを掴むのにクラス名とキャプション名で掴んでいます。 しかし、クラス名は一緒で、キャプション名は存在しません。 すると、2つのコントロールを区別することができません。 現在は、FindWindowExで取得したハンドルを、アプリケーション「spy」等であっているか確認しています。 上記のような、クラス名とキャプションで判断できないものは、皆さんどのようにハンドルを取得していますか? 自分のように順次取得して、順番で判断していますか? だとしたら、FindWindowExで取得した順番はOS環境や、取得する時々で変わったりしないモノなのでしょうか? よろしくお願いします。

  • C++ 子ウィンドウのハンドルを取得したいのですが

    C++で別ウィンドウのアプリケーションを動かすというものを作っているのですが、そのウィンドウの子ウィンドウのハンドルを取得するのに困ったことがあるのでアドバイスをいただけると大変ありがたいです。 基本的にSPY++というソフトを使ってウィンドウ名その他を探し、FindWindowExまたはGetDlgItem関数を使って取得という方法をとっているのですが、クラス名、ウィンドウ名が全く同じもので、コントロールIDも0という状態のものがあり、片方を取得したい場合どうしたらよいのかという状態です。 知人にSPY++でみて上から何番目にあるやつと指定して得ることができる方法があるかもしれないと聞いたのですが、よくわかりません。 例としてその画像ものせますので、良い知恵がありましたらお貸しください。

  • VB.netでSendMessageを使用して電卓を閉じたい

    環境:Win XP,VB.net 2003 sendmessageを使用して電卓を閉じるプログラムを作成しているのですが、どうもあと少しでうまくいかないので質問させていただきます。 Dim hfwnd As Long hfwnd = FindWindowEx(0, 0, "SciCalc", "電卓") If FindWindowEx(0, 0, vbNullString, "電卓") Then MsgBox("電卓動いてます。") Call SendMessage(hfwnd, WM_CLOSE, 0&, 0&) end if この時点で電卓が開いているかどうかの判定はうまくいっています。 ですが、sendmessageのところでうまくいっておらず、hfwndに取得したウインドハンドルが代入されていない?と思いGetWindowTextでタイトル取得してみたところ空白でした。電卓をSendMessageを使用して終了させるにはどのようにしたら良いのでしょうか?

  • javaプログラムから他のjavaプログラムを操作

    javaのプログラムから他のjavaプログラムを操作するにはどのようにすればいいのでしょうか? 他の方が作った既存のjavaプログラムのウィンドウ内のリストビューの項目を自動的に選択したり、エディットビューの表示文字列をクリップボードにコピーしたいと思っています。 Windowsネイティブプログラムから他のWindowsネイティブプログラムを操作する場合は、FindWindowで親ウィンドウのウィンドウハンドルを取得し、そこからFindWindowExで子ウィンドウのハンドルを取得してサブクラス化するそうですが、javaではどうやるのかが知りたいです。 また、子ウィンドウのハンドルを得るために子ウィンドウを特定するための情報(Windowsネイティブプログラムなら、FindWindowExに引数として渡す「GetClassNameで得られるクラス名」)はどのようにすれば調べられるのでしょうか(EnumChildWindows、GetClassNameなどに該当するメンバ関数はあるのでしょうか)?

    • ベストアンサー
    • Java
  • ウインドウの取得

    かんたんYouTubeプレーヤーというソフトのウインドウハンドルを取得し、プレーヤーウインドウのサイズや位置を変更するプログラムをVB2008で作成しようとしました。このプレーヤーはリストウインドウとプレーヤーウインドウの二つがあるのですが、窓ちぇき!というソフトでタイトルとクラス名を調べたら二つとも同じタイトルとクラス名になっていました。これだとFindWindow関数でウインドウハンドルを取得できません。どうすればよいでしょうか。

  • windows7のエクスプローラをVBAで操作-2

    アドバイスをお願いします。 Excel-VBAで起動しているエクスプローラに対してハンドルを取得してクリックしたり、テキストボックスに文字をセットするプログラムを作って動かしています。 WindowsXPのときはできていたのですが、Windows7になったら正しく動作しなくなりました。 下のコードはエクスプローラのフォルダパスの右のボタン(添付ファイル参照)をクリックすべく、コーディングしたものです。 最後のSendMessage(hwnd, BM_CLICK, 0, 0) でクリックしたいのですが、その前にボタンのハンドルが取得できません。SDKのInspect Objectsで調べると、このボタンはClass="ToolbarWindow32"でName="前の場所"ですが、NativeWindowHandleが表示されず、Legacy.IAccessible.ChildID=1となっています。 このようなウィンドゥは別のやり方(IAccessible?)でないとクリックできないように感じていますが如何せん知識がありません。 どうしたらできるか、アドバイスよろしくお願いします。 Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" ( _ ByVal hwndParent As Long, _ ByVal hwndChildAfter As Long, _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As Long Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal MSG As Long, ByVal wParam As Long, lParam As Any) As Long Const BM_CLICK = &HF5 Private hwnd As Long Sub Click_button() hwnd = FindWindow("CabinetWClass", vbNullString) hwnd = FindWindowEx(hwnd, 0, "WorkerW", vbNullString) hwnd = FindWindowEx(hwnd, 0, "ReBarWindow32", vbNullString) hwnd = FindWindowEx(hwnd, 0, "Address Band Root", vbNullString) hwnd = FindWindowEx(hwnd, 0, "msctls_progress32", vbNullString) hwnd = FindWindowEx(hwnd, 0, "ToolbarWindow32", vbNullString) ' この次が分からない。 RC = SendMessage(hwnd, BM_CLICK, 0, 0) end sub

  • 子ウィンドウの操作について(VC++)

    Windows98 Visual C++6.0 雛型でMDIを作成して、アクティブな子ウィンドウに記述されている文字列を操作したいと思っています。 ダイアログボックスを表示して、その中のボタンを押したら、アクティブな子ウィンドウから文字列を取得しある処理した結果をダイアログボックスのtextに表示したいと考えています。 今のところダイアログボックスを表示する所まで出来ています。 問題点は 1.アクティブな子ウィンドウのハンドルはどのようすれば取得できるのでしょうか? 使用すべき関数名等を教えてください。 2.アクティブな子ウィンドウに記述されているデータを取得するには、GetWindowTextやsendMessageで出来るのでしょうか?(なるべくならSJISで処理をしたいと考えているのですが。) わかりずらい質問かも知れませんが宜しくお願いします。

  • windows7のエクスプローラをVBAで操作-1

    アドバイスをお願いします。 Excel-VBAで起動しているエクスプローラに対してハンドルを取得してクリックしたり、テキストボックスに文字をセットするプログラムを作って動かしています。 WindowsXPのときはできていたのですが、Windows7になったら正しく動作しなくなりました。 下のコードはエクスプローラの現在のフォルダパスが表示されるところに(添付ファイル参照)文字を入れるものです。 最後のSendMessageAnyで1が返ってしまいます。何が考えられますでしょうか。どう対策したらいいでしょうか。 なおハンドルの値はSDKのInspect Objectsで確認していますので、正しく取得できていると思っています。 よろしくお願いします。 Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As Any, ByVal lpWindowName As Any) As Long Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" ( _ ByVal hwndParent As Long, _ ByVal hwndChildAfter As Long, _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As Long Declare Function SendMessageAny Lib "user32.dll" _ Alias "SendMessageA" _ (ByVal hwnd As Long, _ ByVal MSG As Long, _ ByVal wParam As Long, _ ByVal lParam As Any) As Long Const WM_SETTEXT = &HC Private hwnd As Long Private FOLDER As String Sub Put_folder_name1() hwnd = FindWindow("CabinetWClass", vbNullString) hwnd = FindWindowEx(hwnd, 0, "WorkerW", vbNullString) hwnd = FindWindowEx(hwnd, 0, "ReBarWindow32", vbNullString) hwnd = FindWindowEx(hwnd, 0, "Address Band Root", vbNullString) hwnd = FindWindowEx(hwnd, 0, "msctls_progress32", vbNullString) hwnd = FindWindowEx(hwnd, 0, "ComboBoxEx32", vbNullString) hwnd = FindWindowEx(hwnd, 0, "ComboBox", vbNullString) hwnd = FindWindowEx(hwnd, 0, "Edit", vbNullString) FOLDER = "\\xx.xx.xx.xx\test" RC = SendMessageAny(hwnd, WM_SETTEXT, 0, ByVal FOLDER) end sub

  • VB.NETで子ウィンドウの列挙の仕方がわかりません。

    VB.NET+FrameWork1.1環境なのですが、 子ウィンドウの取得の仕方がどうしてもわからず教えて頂きたいです。 Dim Oya As Long Oya = FindWindow(vbNullString, "電卓") Dim Ret As Long Ret = EnumChildWindows(Oya, AddressOf EnumChildWnd, 0) このようにして使うAPIのようなのですが、 デリゲート型をLong型に変換できませんと出てしまいます。 色々検索してみたのですが、それらしい記事が見つかるも どうしても理解できず、正常に動作させることが出来ませんでした。 もうしわけございませんが、どなたか実行可能なコードを書いて いただけないでしょうか。 出力結果はConsole.WriteLineに出るようにして頂けると助かります。 よろしくお願いいたします。m(__)m

  • C++で外部の『ファイルを開く』ダイアログ操作

    C++を使い、別のアプリケーションを動かすというプログラムを書いているのですが、行き詰ってしまいました。この解決法など良い知恵があればお願いします。 別アプリケーションの『ファイルを開く』ダイアログを開き、そのパス入力スペースに自動でパスを入力し、『開く』をクリックしたと認識させるところまでを行いたいのです。 //ここでファイルを開くダイアログを表示させています。 SendMessage(hWnd,WM_COMMAND,32797,NULL); ☆//ファイルを開く hWndOpen = FindWindow(NULL, "ファイルを開く"); //ファイルのパス入力 hWndOpenCBE32 =FindWindowEx(hWndOpen , NULL, "ComboBoxEx32" , NULL); hWndOpenCB =FindWindowEx(hWndOpenCBE32 , NULL, "ComboBox" , NULL); hWndOpenEdit =FindWindowEx(hWndOpenCB , NULL, "Edit" , NULL);//パスを入力するところ SendMessage(hWndOpenEdit, WM_SETTEXT, 0, (LPARAM)"aaa.txt"); 『ファイルを開く』のウィンドウが開くところまではいきました。それから先がうまくいきません。 確認として、『ファイルを開く』がすでに表示されている状態で☆部分以降の処理を行うと、うまくとおります。SendMessage(hWnd,WM_COMMAND,32797,NULL);で自動的に『ファイルを開く』ウィンドウを開いてそのまま自動的にパスを入力→開く の動作がうまくいかないのです。

専門家に質問してみよう