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

[Visual C++ Q & A 掲示板] [過去ログの一覧]


まり尾 [E-Mail] 2008/01/28(月) 12:06:36 <初心者>
どうしても分からない事がありますのでどなたか教えてください。

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

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

YuO [E-Mail] 2008/01/28(月) 12:37:19
DialogX側だけではできません。
まぁ,スタックトレース覗いて頑張れば無理ではないかもしれませんが。

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

maru 2008/01/28(月) 12:58:50
「遷移」って、現在表示中のダイアログボックスを消去(終了)させて、
新しいダイアログボックスを表示するってこと?

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

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

まり尾 2008/01/28(月) 14:05:45 <初心者>
YuOさん、maruさん、早急なお返事ありがとうございます。

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

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

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

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

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

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

maru 2008/01/28(月) 14:48:01
> ダイアログ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/28(月) 15:40:47
[[解決]]

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

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

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

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

maru 2008/01/28(月) 17:12:39
おかしな方法を書いちゃったかな?

普通は、
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(火) 08:59:29 <初心者>
レスありがとうございます。

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

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

毎週金曜日はポイント最大3倍!さらに4倍のチャンスも!

Programming Library