[[20190719082845]] 『FindWindowExについて』(高橋) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『FindWindowExについて』(高橋)

FindWindowExで親ウィンドウの中にあるボタンのハンドルを取得したいと考えておりますが何故か0が返ってきます。

Sub test

Dim ParentHandle as LongPtr,ChildHandle as LongPtr

ParentHandle=FindWindowEx(0,0,"親のクラス名","親のウィンドウ名")
''この上の行まではうまくいきます。

ChildHandle=FindWindowEx(ParentHandle,0,"子のクラス名","子のウィンドウ名")
''この上の行でChildHandleに0が代入されます。

End Sub

また、ChildHandle=FindWindowEx(ParentHandle,0,vbNullString,vbNullString)にすると親のウィンドウの何かしらの子のハンドルは取得できております。

このウィンドウ名、子のウィンドウ名はENumChildWindowsで取得したものなので大きな間違いはない…と思うんですが。
正しいかの確認方法等があったら教えていただきたいです。
(Spy++は会社の規約により利用できません。)

< 使用 Excel:Excel2013、使用 OS:unknown >


FindWindowExは、クラス名かウィンドウ名か、どっちか指定しないといけません。(両方vbNullStringだと、最前面のウィンドウの情報を返す) ウィンドウ名を得ているならば、クラス名だけvbNullStringにしてはどうでしょうか?
(???) 2019/07/19(金) 09:26

もうひとつ、思いつきました。 ボタンの場合、ウィンドウ名には表示されている文字列になるかと思いますが、それはどんな文字列でしょうか?

例えば、以下はWINDOWS標準で付属する「文字コード表」のボタンを探してクリックする例になります。 見た目のキャプションは「選択(S)」なのですが、ショートカットキー付きなので、& を加える必要があります。

 Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
 Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hwnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
 Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
 Const WM_ACTIVATE = &H6
 Const BM_CLICK = &HF5

 Sub test()
    Dim hwnd As Long
    Dim hBtn As Long

    hwnd = FindWindow(vbNullString, "文字コード表")
    hBtn = FindWindowEx(hwnd, 0, "Button", "選択(&S)")
    PostMessage hBtn, WM_ACTIVATE, 1, 0
    PostMessage hBtn, BM_CLICK, 0, 0
 End Sub
(???) 2019/07/19(金) 11:36

ChildHandle=FindWindowEx(ParentHandle,0,"子のクラス名","子のウィンドウ名")
ChildHandle=FindWindowEx(ParentHandle,0,vbNullString,"子のウィンドウ名")
ChildHandle=FindWindowEx(ParentHandle,0,"子のクラス名",vbNullString)
ChildHandle=FindWindowEx(ParentHandle,0,vbNullString,vbNullString)
の4パターンを試してみました。
4つ目は上述の通り、何かハンドルを返しました。(多分親ウィンドウのどこかのテキストかなんかだとは思うんですが)
他の3つは0を返します。
0を返すとなるとウィンドウ名、クラス名が取得できておらず、存在していないことが原因かとは思うのですが
ENumChildWindowsで取得したため誤ったクラス名、ウィンドウ名であるとも思えず困っております。

クラス名はアルファベットの単語で、ウィンドウ名は漢字8文字で、クリックで動作するボタンである以外に特殊なものでもないのでショートカットキーは特についていないと思うのですが。

クラス名、ウィンドウ名が正しいか確認するすべはないでしょうか。
(高橋) 2019/07/20(土) 01:31


VBAのUserFormではCommandButton/TextBox等、
個々のコントロールのハンドルは取得できません。

取得できるのは UserForm自体の "ThunderDFrame"
UserForm内の領域全体を覆う "F3 Server nnnnnnn" (n は数字)
というクラス名に対するハンドルだけです。

(AddinBox 角田) 2019/07/20(土) 10:14


クラス名だけ指定しても、ウィンドウ名だけ指定しても、どちらもハンドルが得られなかったのならば、指定したどちらも実際とは一致していないのでしょうね。(または、親を間違えている?) 私の書いた例だと、クラス名部分をvbNullStringにしても、「選択(&S)」というボタンは1つしかないので、正常動作しますよ。

ショートカットキー指定の有無は、ボタン文字列の後ろに、アンダーバー付きのアルファベットがあるかどうかで判断できます。文字コード表なら、アンダーバー付きの「(S)」になっていますよね? こうなっている場合、「&」を付けないと、ウィンドウ名が一致しないのですが、どうやらそういう訳ではないようです。

具体的に、ボタンを押したいアプリは何なのでしょう? ExcelのUserFormの別Formなのですか? それとも、全然違うアプリで、ボタンに見えて、実はマウス移動を検知してボタンのように描画しているだけ、とか?
(???) 2019/07/22(月) 09:24


???様、AddinBox 角田様
回答ありがとうございます。

仕事で使っているアプリなのですが起動直後のボタンや画面遷移後の(親を取り直した後の)ボタンや、同じ親の隣のボタンは正常に押せるのでこのボタンだけ何かしら変なことになっているんでしょうね。

今回は解決できませんでしたが、回答ありがとうございます。
(高橋) 2019/07/24(水) 22:09


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.