
非常に基本的なことを質問して申し訳ございません。
●やりたいこと●
ある親ウィンドウに「テキスト」と「OKボタン」があります。
OKボタンはひとつだけです。
このOKボタンを押して、親ウィンドウを閉じるだけです。
OKボタンを押せば、親ウィンドウは勝手に閉じます。
親ウィンドウのハンドルは取得できたのですが、
子ウィンドウ(ボタン"OK")のハンドルが取得できず、
その後の処理もできておりません。
ボタンはひとつだけなので、ボタンのハンドルを検索したりしなくても、
押すことはできるような気がするのですが・・・
初心者の浅知恵で申し訳ございません。
やはり、ボタンのハンドルを取得して、押すコマンドを実行しないといけないのでしょうか?
ボタンのハンドルを取得して、押すコマンドを実行する場合、
その方法を教えていただけると幸いです。
親ウィンドウのハンドルは変数「hWindow」に入っているとして、
コードをお願いいたします。
親ウィンドウのハンドル取得に使ったFindWindow以外に宣言が必要であればご教授お願いいたします。
No.3ベストアンサー
- 回答日時:
子ウィンドウを探すには、下の2つのAPIの使います。
EnumChildWindows(hWnd,lpEnumFunc,0&)
GetClassName(hWnd,lpClassName,nMaxCount)
EnumChildWindows が、親ウィンドウのハンドルと、子ウィンドウを受け取る関数を
与えます。ただし、子ウィンドウを受け取る関数はフォームモジュールではなく、
標準モジュールにないと駄目です。
すると与えた子ウィンドウを受け取る関数に、親ウィンドウに含まれる全ての子ウィンドウの
ハンドルが返ってきます。
返ってきたハンドルを元に GetClassName で、クラス名を取得し、ボタンのウィンドウを
特定します。今回の場合は、ボタンが1個しかないとのことなので、取得したクラス名が
Buttonであればそのハンドルがボタンのハンドルになります。
参考までに、複数個のボタンがあれば、この場合、どのボタンがOKボタンなのかを特定しない
といけません。「スパイ」とか言うソフトがあれば簡単に特定できるのですが、ない場合は、
子ウィンドウに含まれる、上記の手順で得た全てのボタンのハンドルに対して、プログラムで
BM_CLICKのメッセージを送り一つづつ確認していくしかありません。ただこの場合でも、
特性があって、親ウィンドウに複数個のボタンがあっても、子ウィンドウを受け取る関数には
必ず一定の順番にしか、ハンドルが返ってきないので、最初に一度だけ何番目のボタンかを特定
すればよいです。対象のアプリケーションを再度起動してもこの順番は変わりません。
あと、ボタンのクリックは、SendMessageで、BM_CLICK を送ればOKです。
今回は、簡単な他アプリの制御なので、そんなに問題がないですが、複雑な制御だと、
更に、ウエイトの方法だとか、制御するアプリが確実に動作しているか、確認する操作を
1ステップずつ挿入していかないと駄目です。そうすれば、全ての他のアプリケーションを
自由に操る事ができます。
本格的に作るとなると大変なので、フリーのソフトで沢山でていると思います。一度さがされたら
よいと思います。DLLタイプになっているのがよいとは思います。
以前私も使ったことがありますが、憶えていません。あしからず。現在は自作しております。
自作のがよりきめ細かく制御出来るからです。
何度もご返答いただき誠にありがとうございます。
やはり子ウィンドウを探す必要があるのですね。
教えていただいた内容は、ほとんど理解できたので
なんとか構築できそうです。
勉強不足の稚拙な質問に対して、何度も非常に丁寧に
具体的な回答していただき誠にありがとうございます。
No.2
- 回答日時:
FindWindowでは子コントロールは探せないので GetWindowとGetWidnowText、GetClassNameなどを組み合わせて ボタンのハンドルを特定しないといけないでしょう
hBtn = GetWindow( hWindow, GW_CHILD )
sText = String( 255, vbNullChar )
GetWindowText hBtn, sText, len( sText )
sClass = String( 255, vbNullChar )
GetClassName hBtn, sClass, len(sClass)
といった具合で sTextがOK、sClassにBUTTONが含まれるなどの条件を満たす物を探すことになりそうです
クリックイベントを送信するには SendMessage
ボタンのリソースIDの取得にはGetDlgCtrlID
を使います
Declare Function SendMessage Lib "User32" ( ByVal hWnd as Long, ByVal wParam as Long, ByVal lParam as long) as Long
Declare Function GetDlgCtrlID Lib "User32" ( byVal hWnd as long) as long
といった宣言をしておいて
nID = GetDlgCtrlID( hBtn )
SendMessage hWindow, WM_COMMAND, BN_CLICKED * &H10000 + nID, hBtn
といった具合に クリックメッセージを送るといった具合になるともいます
この回答への補足
ありがとうございます。
教えていただいた内容を、試行錯誤しております。
たびたび申し訳ございません、
子ウィンドウのハンドルの取得についてですが、
hBtn = FindWindowEx(hwindow, 0, "Button", "OK")
これでは取得できないのでしょうか?
エラーの0しか帰ってきません。hwindowには親ウィンドウのハンドルが
ちゃんと取得されて入っております。
No.1
- 回答日時:
# 開発環境の情報なども投稿しましょう
VBのバージョンは何でしょう? VB6以前、VB.NET系列
VB6以前なら そのOKボタンのイベントハンドラのアクセス指定子をPrivateからPublicに変更して Form1.OK_Clickといった具合でいいと思います
VB2005以降なら VB6同様にPrivateからPublicに変更して
MyオブジェクトのFormsコレクションからForm1などのOK_Clickメソッドを適切な引数で呼び出しましょう
VB.NET2002/2003の場合、閉じるフォーム側に閉じられるフォームのオブジェクト変数が必要になるでしょう
ボタンクリックのアクセス指定子の変更は他の場合同様に行います
Form1が閉じられる側、Form2が閉じる側なら
Form2側に Form1型の変数またはプロパティを用意します
Public oForm as Form1
Form1からForm2を開く際に
Dim frm as new Form2
frm.oForm = me
frm.Show
といった具合にします
Form2側からForm1を閉じるイベントで
oForm.OK_Click( oForm.OK, new EventArgs() )
といった具合でしょう
この回答への補足
大変申し訳ございません。
開発環境は、ExcelVBAです。Excelは2003です。
OKをクリックする対処のウィンドウは
VBとは全く関係ない、外部のアプリケーションのウインドウです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 動かなくなってしまった古いVBAを動くようにしたい 8 2022/09/20 13:57
- Visual Basic(VBA) Vba LongPtrについて教えてください 2 2022/08/19 11:14
- Access(アクセス) Access 登録ボタンからサブフォームの更新 1 2022/07/22 10:23
- メルカリ メルカリについて至急回答希望です 出品したものが売れて 商品発送後 不備があったみたいで 使えないと 1 2023/03/15 17:45
- 健康・生活トーク エレベータを降りるときに、、、 1 2023/03/02 23:44
- マウス・キーボード キーボード設定で困っています。長文です。 2 2022/12/10 12:44
- その他(Microsoft Office) windows10で作業を終了する際の「保存しますか はい いいえ」を表示させずに自動で保存する方法 6 2023/03/15 11:29
- プリンタ・スキャナー キャノンmp490プリンター【エラー番号5400】で【プリンタートラブルが発生しました。電源を入れ直 2 2023/07/24 17:45
- その他(生活家電) パナソニックインターホンについて 2 2023/05/31 01:21
- Windows 10 ファイルエクスプローラーでフォルダを閉じる操作について 2 2022/10/15 11:06
このQ&Aを見た人はこんなQ&Aも見ています
-
他のウィンドウのボタンを自動的に押したい
C言語・C++・C#
-
メッセージボックスのOKボタンをVBAでクリックさせたい
Visual Basic(VBA)
-
WinAPIで電卓をクリック
Visual Basic(VBA)
-
-
4
EnumChildWindowsの使い方(VBA)
Visual Basic(VBA)
-
5
VB.netでFindWindowExやると・・・9222812402616107008!?
Visual Basic(VBA)
-
6
ExcelVBAでAPIを使って外部ウインドウのエディットテキストを取得する方法
Visual Basic(VBA)
-
7
VBA(エクセル)で自動的にボタンをクリックさせるには
その他(プログラミング・Web制作)
-
8
Excel VBAで他アプリケーションの文字列取得
Excel(エクセル)
-
9
Alt+P,Alt+NをPostmessageで送るには
Visual Basic(VBA)
-
10
ウィンドウにキー送信で ENTER を送りたい
Visual Basic(VBA)
-
11
【C#】FindWindowExの使い方を教えてください
その他(プログラミング・Web制作)
-
12
他アプリの操作(メニューバー)
Visual Basic(VBA)
-
13
vbaから他のアプリを終了
Visual Basic(VBA)
-
14
ExcelVBAにてアプリをタスクマネージャーから強制終了させたいのですが
Visual Basic(VBA)
-
15
SendMessage で ESC など
C言語・C++・C#
-
16
プロセスIDからウィンドウハンドルを取得する方法
C言語・C++・C#
-
17
VBAでコントロールのハンドルを取得したい
Visual Basic(VBA)
-
18
VB.NETのSendMessageを教えてください
Visual Basic(VBA)
-
19
他のアプリケーションの操作について
C言語・C++・C#
-
20
SendMessageによるチェックボックスの状態取得
Visual Basic(VBA)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
勝手にウィンドウが開いて止ま...
-
ゲームでは結局どっちが良いの?
-
ラジオボタンの初期指定
-
EnumChildWindowsの使い方(VBA)
-
VBA .Value=.Value ?
-
ExcelVBA:フォームの最小化ボ...
-
Vba LongPtrについて教えてくだ...
-
「&HFFFF」「&H1A」とは?
-
ウィンドウにキー送信で ENTER ...
-
[VBA] UserForm を Excel の W...
-
他のアプリケーションの終了処理
-
VBで外部プログラムを位置のみ...
-
C#でファイル転送プログラムWin...
-
Excelの上下を固定したい
-
別ウインドウのハンドル取得の方法
-
指定したインアクティブウィン...
-
Excel2010-ファイルが開かない...
-
Alt+P,Alt+NをPostmessageで送...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで作った新しいウイン...
-
「アイテムは収集されました」...
-
ラジオボタンの初期指定
-
勝手にウィンドウが開いて止ま...
-
Vba LongPtrについて教えてくだ...
-
検索の画面がでなくなってしま...
-
Excelの上下を固定したい
-
ExcelのBOOKが消えた!
-
[VBA] UserForm を Excel の W...
-
VBA .Value=.Value ?
-
作成したウインドウのサイズを...
-
Console.WriteLine で表示されない
-
エクセルで1行目から3行目が消...
-
「&HFFFF」「&H1A」とは?
-
【VB2008】 マウス操作の一時的...
-
UWSCで特定のChromeのタブをア...
-
他のアプリケーションの終了処理
-
MFCでハンドルを取得するには
-
VBAで単一ブック複数窓を閉じる...
-
EnumChildWindowsの使い方(VBA)
おすすめ情報