ダイアログ画面の表示位置を動的に変更したい

解決


うーん  2007-11-05 19:30:07  No: 66751

お世話になります.

マウスを右クリックすると,マウスポインタの位置を左上隅とする
ダイアログ画面が表示されるよう,メッセージハンドラ内に次のよう
なコードを記述しました.

しかし,ダイアログ画面がビュー画面の中央に表示されるだけでマウス
ポインタの位置が反映されません.

右クリックしたときのマウスポインタの位置に応じてダイアログ画面の
表示位置を動的に変更するにはどうしたらよいでしょうか?
あるいはどういったことを調べればよいでしょうか?
環境はVC++2005,MFCです.

void CmyView::OnRButtonDown(UINT nFlags, CPoint point)
{
//   TODO: ここにメッセージ ハンドラ コードを追加するか、
//   既定の処理を呼び出します。
  
     CWnd* pWnd =AfxGetApp()->m_pMainWnd;
     pWnd->SetWindowText("New Title");    // ダイアログ画面の
                                          // タイトルの変更
  
     CmyDlg m_myDlg;
     INT_PTR ret;
//   ダイアログ表示位置の変更
     m_myDlg.SetWindowPos(&wndTop,point.x, point.y, 0, 0,
                                              SWP_NOSIZE);

     ret = m_myDlg.DoModal();
     if(ret==IDOK) {
//      処理1
     }
  
     if(ret==IDCANCEL){
//      処理2  
     }
      
     CView::OnRButtonDown(nFlags, point);
}


Blue  2007-11-05 20:06:56  No: 66752

ダイアログを表示する前に位置を決めても意味ないです。
表示座標をメンバ変数か何かで渡して、OnInitDialog関数で位置を変えるのが
一番簡単な方法でしょう。


tetrapod  2007-11-05 20:12:28  No: 66753

調べてないので記憶だけで書く

CDialog::DoModal を使う場合 MFC が DoModal 中で勝手に
親ウィンドウに対してダイアログを中央あわせしてる、はず。
# そもそも DoModal 前には HWND が無いので SetWindowPos なんぞできんはず

CmyDlg::OnInitDialog でサイズ変更できるかどうかを試して味噌
できなきゃ MFC の奥のほうまで手を突っ込んでごにょごにょする必要がある。
単に、そーなりゃいいなー、程度なら開発コストと成果が見合わないのでやめとけ。

そもそもの話として Modal Dialog って親ウィンドウの中央に出るべきだと思うのだが、
その辺 Microsoft Windows UI Guideline にどう書いてあったっけ?
「ポインタを自動的に既定のボタン上に移動する」設定はこの前提条件の上で存在する。
操作するユーザの混乱を招きかねないので「そんな普通でないダイアログはやめとけ」と提案しとくよ。


うーん  2007-11-05 21:00:09  No: 66754

Blueさん、tetrapodさん、レスありがとうございます。

そうですか・・・  簡単にはできないですか。
OnInitDialog関数の方は試してみます。それでできなければ諦めます。


うーん  2007-11-05 23:33:21  No: 66755

ダイアログオブジェクトにマウス座標をメンバ変数m_x,m_yにセットする
ようにダイアログクラスのコンストラクタを書き直し、OnInitDialog関数
をオーバーライドしてこの関数内からSetWindowPos関数を呼び出すと、
マウスを右クリックするたびに一応、ダイアログ画面の位置が変更される
ようになりました。

ありがとうございました。
最も、tetrapodさんが言うようにこれを使うかどうかは要検討ですが...

// myDlg.h内
class CmyDlg : public CDialog
{
    DECLARE_DYNAMIC(CmyDlg)
public:
    CmyDlg(int x, int y, CWnd* pParent = NULL);  
    virtual ~CmyDlg();
    ・・・
protected:
    ・・・
    int m_x, m_y;
public:
    ・・・
};

// myDlg.cpp内

CmyDlg::CmyDlg(int x, int y, CWnd* pParent /*=NULL*/)
: CDialog(CmyDlg::IDD, pParent), m_x(x), m_y(y)
{
}
  
BOOL CmyDlg::OnInitDialog()
{
   CDialog::OnInitDialog();
   // TODO:  ここに初期化を追加してください
   CmyDlg::SetWindowPos(&wndTop, m_x, m_y, 0, 0, SWP_NOSIZE);
   return TRUE; 
}

// myView.cpp内の右ボタン押しに対応したメッセージハンドラ
void CmyView::OnRButtonDown(UINT nFlags, CPoint point)
{
    ・・・
   CmyDlg m_myDlg(point.x, point.y);
    INT_PTR ret;
    ret = m_myDlg.DoModal();

    if(ret==IDOK) {
//   処理1
    }
   ・・・
}


うーん  2007-11-05 23:34:35  No: 66756

訂正

ダイアログオブジェクトにマウス座標をメンバ変数m_x,m_yにセットする
      ↓
マウス座標をメンバ変数m_x,m_yにセットする


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加