あなたの「必」の書き順を教えてください

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

A 回答 (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から実行して表示させたものです。
「他アプリの操作(メニューバー)」の回答画像4
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/09/02 09:12

ショートカットが定義されていないんですか、windowsの基本が


なってないような・・・。

それはさておき、他の方がGetMenu等のやり方を書かれているので違う方法を。

マウスカーソルを操作して、実際の動作をプログラムで実行させるのは
どうでしょうか。これならショートカットが無くてもマウスをメニューの
ところに移動させて、クリック動作、その後サブメニューの上にマウスを
移動させてクリック。。。って感じにすればいけると思います。

Wizard_Zeroさんのより力技っぽいかも(w
    • good
    • 0

Menu処理関係のAPIとPostMessageを使って試してみました。



まず、対象アプリケーションのウィンドウハンドルを取得します。
次に、
GetMenuやGetSubMenuでメニューハンドルを取得
GetMenuItemCountでサブメニューの項目数を取得
GetMenuItemInfoでメニュー情報を取得
この3つを組み合わせて目的のメニューを探し出してメニューIDを取得。
対象のウィンドウに、WM_COMMANDと探し出したメニューのIDをPostMessage。

メモ帳で試してみたところ一応動作しました。かなり強引な方法ですが。。。
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/08/28 11:55

出来ますよ。


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

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

お礼日時:2009/08/27 15:40

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報