PopUpMenuを経由したDialogの呼び出し – プログラミング – Home

PopUpMenuを経由したDialo...
 
通知
すべてクリア

[解決済] PopUpMenuを経由したDialogの呼び出し


Chikun
 Chikun
(@Chikun)
ゲスト
結合: 21年前
投稿: 18
Topic starter  

明けましておめでとうございます。
毎度お世話になります、Chikunです。

環境 Windows2000SP4 VC++6.0SP6 MFC SDI

スプリッタウィンドウからPopUpMenuを経由してDialogを呼び出した時(Dialog.DoModal)、
表示されたDialogが無反応になってしまいます。
別プロセスのWindowを1度アクティブ(クリック)にすると、正常なDialog表示になります。
Dialogの代わりMessageBox等を表示すると問題無くなります。

プロジェクト A にて MFC SDI(デフォルト設定)を作成し、CTreeViewクラス B を追加しま
す。
CSplitterWndを使用して2分割スプリッタウィンドウにします。
リソースにPopUp用Menu(PopUpMenu01)とDialog(CDlg01)を用意します。
TreeView側ペインからPopUpMenuを表示させます。
PopUpMenuからCTreeViewクラスへメッセージコマンドを送りDialogを呼び出します。

TreeView側ペインからPopUpMenuの呼び出しソース。
void CB::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: この位置にメッセージ ハンドラ用のコードを追加するかまたはデフォルトの処
理を呼び出してください
CTreeCtrl& tree = GetTreeCtrl();
TVHITTESTINFO TVHit;

CPoint pt;
GetCursorPos(&pt);
ScreenToClient(&pt);

TVHit.pt = pt;
tree.HitTest(&TVHit);
tree.SelectItem(TVHit.hItem);

CMenu menu;
CMenu* pPopup;
CFrameWnd* pFrmWnd = (CMainFrame*)AfxGetMainWnd();

VERIFY(menu.LoadMenu(IDR_PopUpMenu01));
pPopup = menu.GetSubMenu(0);
ClientToScreen(&point);
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, point.x, point.y,
pFrmWnd);

CTreeView::OnRButtonDown(nFlags, point);
}

Dialogの呼び出しソース。
void CB::OnPopUpMenu01()
{
CDlg01 dlg;
dlg.DoModal();
}

何か注意点等ありましたら、よろしくご教授下さい。


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

OnPopUpMenu01のなかで、一時停止状態になるのがダメなのかも。

> CDlg01 dlg;
> dlg.DoModal();
の処理を別関数(ユーザメッセージかなんか)にして、PostMessageで呼び出してみてはど
うでしょうか?


返信引用
Chikun
 Chikun
(@Chikun)
ゲスト
結合: 21年前
投稿: 18
Topic starter  

Blueさん、毎度ありがとうございます。

void CB:OnPop0101()
{
this->PostMessage(WM_01);
}

LRESULT CB::On01(WPARAM wp, LPARAM lp)
{
CDlg01 dlg;
dlg.DoModal();

return(1);
}

Postしてみましたが、症状はかわりませんでした。

CDlg01のリソース設定はデフォルトですが、ストイル等の変更が必要なのでしょうか?


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

明示的にそのダイアログの親を指定してみてはどうでしょう?
CBを親にしていいのであれば、CDlg01 dlg(this);とすれば良いと思います。
本来はこのようにダイアログのインスタンス生成時に親を明示的に指定した方が
CDialogクラスの中で涙ぐましい努力をして親ウインドウを捜さなくて良いので
効率が良いはずです。
CDialogクラスのコンストラクタでは、リソースIDと親ウインドウのポインタになって
いますが、派生クラス側では、リソースIDは内部に定義した物を引き渡すようになって
いるので、派生側のコンストラクタでは親ウインドウのポインタのみの指定になって
いると思います。


返信引用
Chikun
 Chikun
(@Chikun)
ゲスト
結合: 21年前
投稿: 18
Topic starter  

PATIOさん、お世話になります。

void CB:OnPop0101()
{
CDlg01 dlg(this);
dlg.DoModal();
}

症状はかわりませんでした。
色々な所で this を指定して試したのですが、思うようにいきませんでした。

PopUpMenuの親ウインドウをスプリッタウィンドウにしていること自体が間違えなので
しょうか。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

スプリッタウインドウを親にしているのではなくて
ペインに表示しているViewを親にしているのではないでしょうか?
スプリッタウインドウコントロールがメインフレームのViewにはまって
スプリッタウインドウコントロールのペインにTreeViewがはまって
いるのではないでしょうか。
この辺の用語は分けて考えた方が良いとおもいますよ。
もし、ダイアログの親にフレームウインドウを指定したとしたらどうなるでしょう?
ちょっと考えて思いつくのはそれぐらいでしょうか。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 23年前
投稿: 1235
 

ダイアログは、モーダルでないとだめですか?
モードレスなら、親ウインドウの「thisポインター」を引き継げられると思います。


返信引用
r
 r
(@r)
ゲスト
結合: 22年前
投稿: 48
 

これ、ダイアログが無応答になった時点でキャプチャーウィンドウを確認して
みたら、ツリービューがマウスキャプチャーしちゃってますね。
で、ダイアログにマウスメッセージが届かない。(キーボード操作は可能)
たぶん、ツリーコントロールでは WM_RBUTTONDOWN のデフォルト処理が
マウスキャプチャーを開始するので、こういうことになるのだろうと...

pPopup->TrackPopupMenu(...);
の後にある、
CTreeView::OnRButtonDown(nFlags, point);

を削除すれば意図通りに動くと思います。

でも、WM_RBUTTONDOWN でやらなければならないというような
特別な理由がなければ、
http://support.microsoft.com/?scid=kb%3Ben-us%3B222905&x=12&y=17
の方法でコンテキストメニューを表示したほうがいいと思います。
#ツリーコントロールでの WM_CONTEXTMENU ってちょっと特殊みたいね


返信引用
Chikun
 Chikun
(@Chikun)
ゲスト
結合: 21年前
投稿: 18
Topic starter  

PATIOさん、ITOさん、rさん、ありがとうございます。

CTreeView::OnRButtonDown(nFlags, point); の削除で直りました。
Dialogベースで使用した時は問題無かったのですが、TreeCtrl 使用時に注意が必要と言う
ことですか。

やりたいことは、一般によく見られるツリーの各項目をクリックするとポップアップの
メニューがでて、プロパティやその他の処理を行うものです。
コンテキストメニューは知らなかったので、WM_RBUTTONDOWN や TVHITTESTINFO を使いなが

ゴニョゴニョやってました。
「How To Display a Context Menu for CTreeCtrl」参考にさせて頂きます。

皆さん、ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました