久しぶりの質問です。
環境は Win2000Pro(SP2),VC++ 6.0(SP5),MFC開発 です。
早速ですが、質問します。
現在、データベースのマスター管理システムを開発していまして、
内容は、
1.ツリーでマスターを階層表現し、リストビューで詳細を表現します。
2.ダブルクリックでマスターメンテのダイアログを表示して、
追加、更新、削除を行います。
3.階層に応じて、右クリックで新規作成のメニューを表示し、選択したら、
その階層内に「新規マスター」という項目を追加します。
4.新規マスターを2の処理で追加できるようにする。
1,2,4は問題なくできますが、3がうまくいきません。
・ツリー内を右クリックし「GetSelectedItem」で選択したアイテムを取得したくても、取得し
てくるのは反転したアイテムではなく、フォーカスがある場所を選択アイテムとみなしているみ
たいなのです。できれば、右クリックした時点でフォーカスを反転した場所に移動させたいので
すが、どうしたらよいのでしょうか?
・仮に右クリックがうまくいったとしても、リソースで作成したメニューが表示されません。
(例: メニューIDは「IDR_MENU_TEST」です。
CMenu menu;
if( menu.LoadMenu(IDR_MENU_TEST) != TRUE )
MessageBox(メニュー取得失敗, NULL, MB_OK);
どうしたら、メニューが表示されるのでしょうか?
以上2点の質問ですが、どなたか、良い知恵をください。
よろしくお願いします。
> ・ツリー内を右クリックし「GetSelectedItem」で選択したアイテムを取得したくても、
GetDropHilightItem()を使うとハイライト表示中のアイテムを取得できます。
> ・仮に右クリックがうまくいったとしても、リソースで作成したメニューが表示されません。
LoadMenu()が失敗するのでしょうか?
リビルドしてみるとか…。
> できれば、右クリックした時点でフォーカスを反転した場所に移動させたいので
すが、どうしたらよいのでしょうか?
CTreeViewから派生クラスをつくって、OnRButtonDown()をオーバーライドして、この関数の
中でフォーカスをセットすると良いかもしれません。
>(例: メニューIDは「IDR_MENU_TEST」です。
> CMenu menu;
> if( menu.LoadMenu(IDR_MENU_TEST) != TRUE )
> MessageBox(メニュー取得失敗, NULL, MB_OK);
この後で、次のように続けると表示できます。サンプルを書いておきます。
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT_VALID( pPopup );
pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON, point.x,
point.y, AfxGetMainWnd() );
dairygoodsさん、レス、ありがとうございます。
>GetDropHilightItem()
をつかって解決する事ができました。
HELPは見ていたのですが、まさか、これを使用するとは思いませんでした。
>LoadMenu()が失敗する
はリビルドをしたら解決したみたいです。
saraさん、レス、ありがとうございます。
記述はしていませんでしたが、saraさんが記述している通りにしていたのですが、
>ASSERT_VALID( pPopup );
で落ちてしまいます。
コメントにしたら、TrackPopupMenu(...)で落ちてしまいます。
とりあえず、「LoadMenu()が失敗する」が無くなったので、自分でも調査をしてみますが、
今後も、良きアドバイスをお願いします。
とりあえず、ソースを記述します。
// 引数
// int &GetLevel : 階層レベル
// HTREEITEM &hSI : アイテムのハンドル
void CXXXDlg::f_AddTree(int &GetLevel, HTREEITEM &hSI)
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
CMenu menu;
CMenu *pPopup;
POINT MousePos; //マウス座標用
// レベルに応じた、メニューをロード
switch( GetLevel ){
case 0 :
if( menu.LoadMenu(IDR_MENU_01) != TRUE)
return;
break;
case 1 :
if( menu.LoadMenu(IDR_MENU_02) != TRUE)
return;
break;
case 2 :
if( menu.LoadMenu(IDR_MENU_03) != TRUE)
return;
break;
default: // 何も処理しない
break;
}
if ( GetLevel <= 2 ){ // レベル2までを処理の対象とする
// ポップアップ メニューを取得
pPopup = menu.GetSubMenu(0);
//マウスのスクリーン座標取得
GetCursorPos( &MousePos );
// メニュー表示
ASSERT_VALID( pPopup );
pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
MousePos.x, MousePos.y, AfxGetMainWnd() ,NULL);
}
// アイテム追加処理
}
今のところ考えられるのは、次の2点くらいです。後は問題なさそうですけどね。
○ IDR_MENU_01などのID番号がどこかと衝突していないか
○ GetLevel < 0 は有り得ないか?
レスありがとうございます。
>○ IDR_MENU_01などのID番号がどこかと衝突していないか
>○ GetLevel < 0 は有り得ないか?
上記2点はどちらも問題はありません。
> pPopup = menu.GetSubMenu(0);
0番目の項目がポップアップメニューでないとか。
http://www.microsoft.com/JAPAN/developer/library/vccore/_core_creating_pop.2d.up
_menus.htm
できました。
ポップアップメニューの作成方法に間違いがありました。
正しい作成方法は、
http://www.alpha-net.ne.jp/users2/uk413/vc/VCT_MENUpopup.html
に掲載されていますので、参照してください。
みなさま、どうもありがとうございました。