ページ 11

メニュー無効化

Posted: 2006年4月03日(月) 16:02
by なっtou
MainWndのMainMenuの中のあるIDだけを無効化させる
方法を教えてください。

できればソースを...(申し訳ありません) (@@;)

Re: メニュー無効化

Posted: 2006年4月03日(月) 16:33
by 7
> MainWndのMainMenuの中のあるIDだけを無効化させる
> 方法を教えてください。
たしかですが、EnableMenuItem()関数で出来たと思います。
ActiveBasic付属のヘルプを読んでも分からなかったらまた投稿して下さい。

Re: メニュー無効化

Posted: 2006年4月03日(月) 16:56
by 淡幻星
最初から無効にする(これはRADの「無効」にチェックすればよい)のではなく、
途中から(例えばボタンを押したときに)無効にする、ということで
良いのでしょうか?

無効化するIDをIDM_Enable、その項目を含むメニューのハンドルをhMenuMainとすると

コード: 全て選択

Dim lpMenuInfo As MENUITEMINFO
Dim retAns As Long

'メニュー項目(IDM_Enable)を動的に無効化する。
lpMenuInfo.cbSize = Len( lpMenuInfo )
lpMenuInfo.fMask = MIIM_STATE
lpMenuInfo.fState = MFS_DISABLED
retAns = SetMenuItemInfo( hMenuMain, IDM_Enable, MF_BYCOMMAND, lpMenuInfo )
'SetMenuItemInfo()を使うと、メニューの内容(文字列)なども変更できる。
'要ヘルプ参照。
でできると思います。

・・・もっと簡単に、直に使用可/不可を変更できるEnableMenuItem()なんて関数もあるみたいです。

コード: 全て選択

'メニュー項目(IDM_Enable)を動的に無効化する。
EnableMenuItem( hMenuMain, IDM_Enable, MF_BYCOMMAND Or MF_GRAYED )
試してませんが、ヘルプに載ってました。


とここまで書いてから、RADではメニューハンドルなんぞは
明示的には扱わないのではないか、と疑問が浮かびました。
(RADではメニューの状態変更はやったことないので^^;)
いちいちCallback.wbpを調べるのもどうかと思うので・・・こんな方法を考えてみます。

下記のようなメニュー(IDをMainMenuとします)があったとします。
--------------------------------
  ファイル(ID_F)-ヘルプ(ID_H)
    +開く(ID_O)  +バージョン情報(ID_V)
    +保存(ID_S)
--------------------------------
ここで、サブメニューの相対位置は「開く」が0、「保存」が1です。
「開く」を指定する場合は
Dim hMenuMain As HMENU
hMenuMain = GetSubMenu( GetSubMenu(hMenu_ID_MainMenu, 0), 0 )
「保存」を指定する場合は
hMenuMain = GetSubMenu( GetSubMenu(hMenu_ID_MainMenu, 0), 1 )
「ファイル」を指定する場合は
hMenuMain = GetSubMenu(hMenu_ID_MainMenu, 0)
「ヘルプ」を指定する場合は
hMenuMain = GetSubMenu(hMenu_ID_MainMenu, 1)
「バージョン情報」を指定する場合は
hMenuMain = GetSubMenu( GetSubMenu(hMenu_ID_MainMenu, 1), 0 )
を“項目を含むメニューのハンドル”として指定してやれば、
良いのではないかと思います。
なお、hMenu_ID_MainMenuはRADが自動定義しているメニューの親ハンドルです。


うーん。コードがちょっと手間ですね(^^;)
もっと簡単な方法があるのかもしれません。
知ってる方いらっしゃいましたら、宜しくお願いします。

Re: メニュー無効化

Posted: 2006年4月03日(月) 17:04
by 淡幻星
あ。
書いているうちに、投稿が7さんと前後してしまいましたね。
メニューの無効/有効の変更はやっぱEnableMenuItem()ですか。
今の今まで知りませんでした^^;


う~ん。
「hMenu As HMENU:項目を含むメニューのハンドルを指定します。」
のメニューハンドルって、RADでは明示されてないですよね?^^;≫7さん
(ハンドルを得るためのGetDlgItem()は窓専用みたいですし・・・)。

Re: メニュー無効化

Posted: 2006年4月03日(月) 17:21
by 7
> 「hMenu As HMENU:項目を含むメニューのハンドルを指定します。」
> のメニューハンドルって、RADでは明示されてないですよね?^^;
暗示ですが(?)、例えば"MainMenu"というメニューを作ると"Dim hMenu_MainMenu As HMENU"とRADがCallback.wbpに定義してくれます。
そしてこれが"MainMenu"のハンドルになるのでこれを指定してやることでメニューアイテムを無効にしたりできます。

ただ、将来的にずっとこういう仕様だとも限らないのでGetMenu()関数を使うのが一番いいやり方だと思います。

コード: 全て選択

EnableMenuItem(GetMenu(hMainWnd),IDM_HOGE,MF_BYCOMMAND or MF_GRAYED)
GetMenu()関数はウィンドウに関連付けられているメニューのハンドルを返します。

Re: メニュー無効化

Posted: 2006年4月03日(月) 18:18
by 淡幻星
なっtouさんを放っておいての議論になってしまいそうで恐縮ですが、
7さんにレスしますm(_ _)m
7さん さんが書きました:> 暗示ですが(?)、例えば"MainMenu"というメニューを作ると"Dim hMenu_MainMenu As HMENU"とRADがCallback.wbpに定義してくれます。
そうですね。
私もCallback.wbpを見て、上記のコードを書きました。
しかし、Callback.wbpはRADによって自動生成&更新されるので、
ユーザーは極力触れるべきではないと思っています。
ただ、今気づきましたが「hMenu_ID_MainMenu As HMENU」もまた、
ユーザーがどんなメニューIDを使うかによって変わってしまうんですねぇ^^;
うっかりしてました。

とすると、 上記の私のレスで言えばhMenu_ID_MainMenuの部分を
GetMenu(hMainWnd)で置き換えるのが良さそうですね。
それから気になったのですが、
IDで項目を指定する場合に、トップの親メニューハンドルさえ
指定すれば良いのでしょうか? 自身のメニューハンドルでないと
ダメだとばかり思っていたのですが・・・。
(上記のレスで言えば、GetSubMenu()は使わなくても良いのか、ということです。)

Re: メニュー無効化

Posted: 2006年4月03日(月) 19:29
by 7
> IDで項目を指定する場合に、トップの親メニューハンドルさえ
> 指定すれば良いのでしょうか? 自身のメニューハンドルでないと
> ダメだとばかり思っていたのですが・・・。
> (上記のレスで言えば、GetSubMenu()は使わなくても良いのか、ということです。)
IDで項目を指定する場合、GetSubMenu()関数は必要ありません。

ただメニューを動的に操作する場合などは、GetSubMenu()関数が必要になります。(と思ってます)
コマンドボタンを押したらサブメニューが増えていく、減っていく、なんていう処理をするにはIDではなくて相対位置を指定する方が簡単だからです。

codeを整形に使っちゃいます...ちょっと分かり辛い表現かもしれませんけど...一応メニューってことです。

コード: 全て選択

|--------------------------------------------|
|  親メニュー0   |   親メニュー1   |   親メニュー2  |
|--------------------------------------------|
| サブメニュー0,0 | サブメニュー1,0 | サブメニュー2,0 |
| サブメニュー0,1 | サブメニュー1,1 | サブメニュー2,1 |
| サブメニュー0,2 | サブメニュー1,2 | サブメニュー2,2 |
|--------------------------------------------|
GetMenu()関数とIDを使ったらサブメニューだろうがハンドルを取得できるんですが、相対位置を使うと"親メニュー0","親メニュー1","親メニュー2"、のハンドルしか取得できません。
そこでGetSubMenu()関数の出番になります。
GetSubMenu()関数の第二引数には"親メニュー"の相対位置を指定し、EnableMenuItem()関数の第二引数には"サブメニュー"の相対位置を指定します。

すみません!上手く説明できません...。

コード: 全て選択

Dim hSubMenu As HMENU
	hSubMenu=GetSubMenu(GetMenu(hMainWnd),0)
	EnableMenuItem(hSubMenu,1,MF_BYPOSITION or MF_GRAYED)
上のようなコードを実行すると、もっと上で書いた"サブメニュー0,1"が無効になるんですが、分かるでしょうか?

Re: メニュー無効化

Posted: 2006年4月03日(月) 21:01
by 淡幻星
≫7さん
>IDで項目を指定する場合、GetSubMenu()関数は必要ありません。
そうだったのですか。どうもです。
一方で、相対位置が必要になるのは、項目追加などの場合ですね。
その場合はGetSubMenu()と。


≫なっtouさん
私の疑問点も書いてしまったので、ちょっと話がこんがらがってしまいましたが^^。
結論としては、
上から5番目の7さんのコードが一番簡単で分かりやすいと思います。
IDM_HOGEが無効にするメニューのIDですね。