共通画面の遷移元を認識するには?

解決


まり尾  2008-01-28 21:06:36  No: 67371

どうしても分からない事がありますのでどなたか教えてください。

例えば、
ボタン1とボタン2があり、共にDialogXに遷移します。
このときDialogXは、
どちらのボタンから遷移してきたか認識できないのでしょうか?

ボタン別に、DialogXのリスト内の内容を変更したく困ってます。
よろしくお願いします。


YuO  2008-01-28 21:37:19  No: 67372

DialogX側だけではできません。
まぁ,スタックトレース覗いて頑張れば無理ではないかもしれませんが。

DialogBoxのかわりにDialogBoxParamを使ったり,CreateDialogのかわりにCreateDialogParamを使うなりして,呼び出し元から「どちらのボタンから遷移したのか」という情報を渡してやれば,WM_INITDIALOGで判断可能です。


maru  2008-01-28 21:58:50  No: 67373

「遷移」って、現在表示中のダイアログボックスを消去(終了)させて、
新しいダイアログボックスを表示するってこと?

プラットフォーム SDKなら、YuOさんが書いた通りDialogBoxParamやCreateDialogParamを使う。
MFCならCDialogの派生クラスを使うはずだから、そのクラスに変数を追加してそれを使うといった方法だろうね。
いずれにせよ呼び出し元から情報を渡すのが簡単。

MFCならば、CDialog派生クラスのコンストラクタに呼び出し元の(CWndから派生した)クラスのポインタを渡すことができるから、
そのポインタ経由で呼び出し元のクラスの情報を取得することが可能。


まり尾  2008-01-28 23:05:45  No: 67374

YuOさん、maruさん、早急なお返事ありがとうございます。

説明不足ですみません。。。
遷移というのは、

>「遷移」って、現在表示中のダイアログボックスを消去(終了)させて、
ではなく、上に乗せる事です。
(ボタン押下でCDialogクラスを継承したダイアログをDoModal()します)
因みにMFCです。

maruの意見を確認させてください。
例)
呼び出し元画面:ダイアログA
呼び出し先画面:ダイアログZ

ダイアログAからダイアログZの呼び出し方法:ボタンAまたはボタンB押下

以上の条件下でしたら、
ダイアログAのクラスに変数Mを追加する。(ボタン押下時にフラグの様に使う事を考えてます)
ダイアログZのクラスはダイアログAのクラスを継承。
ダイアログZはダイアログAの変数Mを参照し、どちらのボタンが押下されたかを認識する。

という考えで大丈夫でしょうか?
ご意見お待ちしてます。


maru  2008-01-28 23:48:01  No: 67375

> ダイアログZのクラスはダイアログAのクラスを継承。
は不用。(継承->参照の間違い?)

例:
class CDialogZ : public CDialog
{
public:
  CDialogZ(CWnd* pParent = NULL);  // 標準コンストラクタ
  enum { IDD = IDD_DIALOG_Z };
  virtual BOOL OnInitDialog();
};

class CDialogA : public CDialog
{
public:
  CDialogA(CWnd* pParent = NULL);  // 標準コンストラクタ
  enum { IDD = IDD_DIALOG_A };

  afx_msg void OnBnClickedButtonA();
  afx_msg void OnBnClickedButtonB();

  bool  isButtonA(void)  {return m_bButtonA;}
private:
  bool  m_bButtonA;
};

CDialogA::CDialogA(CWnd* pParent /*=NULL*/)
  : CDialog(CDlgCallDlg::IDD, pParent)
{}

void CDialogA::OnBnClickedButtonA()
{  m_bButtonA = true;
  CDialogZ  dlg(this);
  dlg.DoModal();
}

void CDialogA::OnBnClickedButtonB()
{  m_bButtonA = false;
  CDialogZ  dlg(this);
  dlg.DoModal();
}

CDialogZ::CDialogZ(CWnd* pParent /*=NULL*/)
  : CDialog(CDlgCallDlg::IDD, pParent)
{}

BOOL CDialogZ::OnInitDialog()
{  CDialog::OnInitDialog();
  CDialogA*  pParent = (CDialogA*)GetParent();
  if (pParent->isButtonA())
  {  // ボタンAから呼び出された
  } else
  {  // ボタンBから呼び出された
  }  
  return TRUE;
}

別の方法:
bool  m_bButtonA;
をCDialogZに持っていき、CDailogAから操作する。


まり尾  2008-01-29 00:40:47  No: 67376

お返事ありがとうございます。
maruさんの助言によって解決しました。

序盤での
>MFCならば、CDialog派生クラスのコンストラクタに呼び出し元の(CWndから派生した)クラスのポインタを渡すことができるから、
>そのポインタ経由で呼び出し元のクラスの情報を取得することが可能。
というコメントも、参考書片手にようやく理解できました。

今回始めて投稿しました。
また、どうしようも無い時は質問させてもらいます。

ありがとうございました。


maru  2008-01-29 02:12:39  No: 67377

おかしな方法を書いちゃったかな?

普通は、
CDialogA* pParent = (CDialogA*)GetParent();
のキャストが危険なので、「別の方法」で書いたようにフラグをCDailogZに
持っていき、DoModal()をやる前にdlgに設定します。
void CDialogA::OnBnClickedButtonA()
{   CDialogZ dlg;
    dlg.m_bButtonA = true;
    dlg.DoModal();
}
BOOL CDialogZ::OnInitDialog()
{   CDialog::OnInitDialog();
    if (bButtonA)
    { // ボタンAから呼び出された
    } else
    { // ボタンBから呼び出された
    }
}


まり尾  2008-01-29 17:59:29  No: 67378

レスありがとうございます。

今回は、上位画面(DialogZ)での表示項目を判断するために、
CDialogZの内部フラグを判定する様に組み込みました。
今後、システムによっては逆のパターンも必要になってくるかと思います。

maruさんの御助言で、クラスの使い方に幅が広がりました。
初心者質問ですみませんがありがとうございました。


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

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






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