• ベストアンサー

他アプリの操作(メニューバー)

市販されているアプリケーションを自分で作成しているソフトで操作したいのですが、どの様に制御したらいいのか判りません。プログラムはVB6.0で作成しております。 したい事は他のアプリケーションでメニューバーの中の項目の 印刷項目を選択したいのですが、メニューバーのハンドルを取得 出来ず困っております。 そもそもメニューバーのハンドルって取得できるのでしょうか?

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

  • ベストアンサー
回答No.4

ウィンドウハンドルの取得については割愛します。 Option Explicit Private Declare Function GetMenu Lib "user32" (ByVal hWnd As Long) As Long Private Declare Function GetMenuItemCount Lib "user32" (ByVal hMenu As Long) As Long Private Declare Function GetMenuItemInfo Lib "user32" Alias "GetMenuItemInfoA" (ByVal hMenu As Long, ByVal un As Long, ByVal b As Long, lpMenuItemInfo As MENUITEMINFO) 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 Private Const WM_COMMAND = &H111 Private Type MENUITEMINFO cbSize As Long fMask As Long fType As Long fState As Long wID As Long hSubMenu As Long hbmpChecked As Long hbmpUnchecked As Long dwItemData As Long dwTypeData As String cch As Long End Type ' hWndに指定したウィンドウのメニュークリックをエミュレート ' Menusには、メニューを辿る順序を文字列配列で定義 ' ファイル -> 印刷 であれば Menus() = {"ファイル", "印刷"} Private Sub EmulateMenuClick(ByVal hWnd As Long, Menus() As String) Dim hMenu As Long, lngID As Long, intMenuIndex As Integer hMenu = GetMenu(hWnd) ' メニュー階層をたどる For intMenuIndex = 0 To UBound(Menus) If ContainMenu(hMenu, Menus(intMenuIndex), lngID) = False Then Call MsgBox("一致するメニューはありません。") Exit Sub End If Next ' 最終的に見つかったメニューのIDをWM_COMMANDでPostMessage Call PostMessage(hWnd, WM_COMMAND, lngID, 0&) End Sub ' hMenuのメニューハンドル内でTextの文字列と一致するメニューがあるかどうかを返す ' 見つかればTrue。このとき、hMenuにはサブメニューのハンドル、IDにはメニューのIDが返される ' 見つからなければFalse Private Function ContainMenu(hMenu As Long, ByVal Text As String, ID As Long) As Boolean Dim lngCount As Long, lngPos As Long Dim typMenuItem As MENUITEMINFO lngCount = GetMenuItemCount(hMenu) ' メニューの個数でループ For lngPos = 0 To lngCount - 1 typMenuItem.fMask = &H3F& typMenuItem.dwTypeData = vbNullChar typMenuItem.cch = 0 typMenuItem.cbSize = Len(typMenuItem) Call GetMenuItemInfo(hMenu, lngPos, 1, typMenuItem) typMenuItem.dwTypeData = String(typMenuItem.cch, " ") typMenuItem.cch = typMenuItem.cch + 1 typMenuItem.cbSize = Len(typMenuItem) Call GetMenuItemInfo(hMenu, lngPos, 1, typMenuItem) Debug.Print typMenuItem.dwTypeData ' メニューの文字列を比較(比較方法はどちらでも) 'If typMenuItem.dwTypeData = Text Then If typMenuItem.dwTypeData Like Text Then ' 一致したらIDとサブメニューハンドルを返す ID = typMenuItem.wID hMenu = typMenuItem.hSubMenu ContainMenu = True Exit Function End If Next ContainMenu = False End Function EmulateMenuClickにウィンドウハンドルと実行したいメニューを辿る文字列配列を渡してください。 画像は、このコードを利用してAPIビューアのバージョン情報をForm1から実行して表示させたものです。

Simanohito
質問者

お礼

連絡が大変遅くなりましてもうしわけございません。 上記サンプルのおかげでやりたい事が出来るようになりました。 大変ありがとうございます。

その他の回答 (3)

  • mokekyo
  • ベストアンサー率18% (2/11)
回答No.3

ショートカットが定義されていないんですか、windowsの基本が なってないような・・・。 それはさておき、他の方がGetMenu等のやり方を書かれているので違う方法を。 マウスカーソルを操作して、実際の動作をプログラムで実行させるのは どうでしょうか。これならショートカットが無くてもマウスをメニューの ところに移動させて、クリック動作、その後サブメニューの上にマウスを 移動させてクリック。。。って感じにすればいけると思います。 Wizard_Zeroさんのより力技っぽいかも(w

回答No.2

Menu処理関係のAPIとPostMessageを使って試してみました。 まず、対象アプリケーションのウィンドウハンドルを取得します。 次に、 GetMenuやGetSubMenuでメニューハンドルを取得 GetMenuItemCountでサブメニューの項目数を取得 GetMenuItemInfoでメニュー情報を取得 この3つを組み合わせて目的のメニューを探し出してメニューIDを取得。 対象のウィンドウに、WM_COMMANDと探し出したメニューのIDをPostMessage。 メモ帳で試してみたところ一応動作しました。かなり強引な方法ですが。。。

Simanohito
質問者

お礼

ご回答ありがとうございます。 いろいろ調べてみて GetMenuやGetSubMenuでメニューハンドルを取得 GetMenuItemCountでサブメニューの項目数を取得 まではできました。 それ以降が出来ず困っております。 出来ればサンプルのプログラムでご教示頂けないでしょうか。 大変申し訳ございませんがよろしくお願い致します。

  • mokekyo
  • ベストアンサー率18% (2/11)
回答No.1

出来ますよ。 以前同じようなソフトをやっつけで作った事がありますので。 ただ、かなり昔なので記憶が薄れていますが。。。 メニューの操作をする場合、そのソフトウェアに対して ショートカットを送って実行させてたかな? ctrl+ほげ、少し時間を開けて次のctrl+ほげほげって 感じで操作しました。そのときは他のソフトウェアが 動いていると困りますので、それは運用でなんとかするようにしてください(汗

Simanohito
質問者

お礼

ご連絡ありがとうございます。 残念ならが制御したい側のアプリケーションにショートカットが設定されおらず、ショートカットでの制御はできません。 他にいい方法があればご教示お願い致します。

関連するQ&A