visual stadio2005 VC++でコーディングしています。
モードレスダイアログの値を親ダイアログに受け渡すのがうまくいきません。
モーダルダイアログではうまくいきます。
やりたいことは子ダイアログにあるエディットボックス内の数値がスピンコントロール
で変更し、その値を親ダイアログで変動的に受け取るということです。
ご教授下さい。
*childDlg.cpp******
#include stdafx.h
#include Child.h
#include ParentDlg.h
IMPLEMENT_DYNAMIC(CChildDlg, CDialog)
CChildDlg::CChildDlg(CWnd* pParent /*=NULL*/)
: CDialog(CChildDlg::IDD, pParent)
, m_clor(0)
{
}
CChildDlg::~CChildDlg()
{
}
void CChildDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_SPIN1, m_xcRed);
DDX_Control(pDX, IDC_SPIN2, m_xcGreen);
DDX_Control(pDX, IDC_SPIN3, m_xcBlue);
}
BEGIN_MESSAGE_MAP(CClorDlg, CDialog)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN1, &CChildDlg::OnDeltaposSpin1)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN2, &CChildDlg::OnDeltaposSpin2)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN3, &CChildDlg::OnDeltaposSpin3)
ON_BN_CLICKED(IDOK, &CChildDlg::OnBnClickedOk)
ON_BN_CLICKED(IDCANCEL, &CChildDlg::OnBnClickedCancel)
END_MESSAGE_MAP()
//OnInitDialog()
// CCChildDlg メッセージ ハンドラ
BOOL CChildDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE); // 大きいアイコンの設定
SetIcon(m_hIcon, FALSE); // 小さいアイコンの設定
// TODO: 初期化をここに追加します。
{
m_xcRed.SetRange32(0,100);
m_xcRed.SetPos(20);
m_xcGreen.SetRange32(0,100);
m_xcGreen.SetPos(16);
m_xcBlue.SetRange32(0,100);
m_xcBlue.SetPos(22);
}
return TRUE;
}
void CChildDlg::OnDeltaposSpin1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: ここにコントロール通知ハンドラ コードを追加します。
BOOL bTranslated = FALSE;
int red = GetDlgItemInt(IDC_EDIT1, &bTranslated);
if ( bTranslated)
{
m_red = red;
}
*pResult = 0;
}
void CChildDlg::OnDeltaposSpin2(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: ここにコントロール通知ハンドラ コードを追加します。
BOOL bTranslated = FALSE;
int green = GetDlgItemInt(IDC_EDIT2, &bTranslated);
if(bTranslated)
{
m_green = green;
}
*pResult = 0;
}
void CChildDlg::OnDeltaposSpin3(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
// TODO: ここにコントロール通知ハンドラ コードを追加します。
BOOL bTranslated = FALSE;
int blue = GetDlgItemInt(IDC_EDIT3, &bTranslated);
if(bTranslated)
{
m_blue = blue;
}
*pResult = 0;
}
void CChildDlg::OnBnClickedOk()
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
OnOK();
}
void CChildDlg::OnBnClickedCancel()
{
// TODO: ここにコントロール通知ハンドラ コードを追加します。
OnCancel();
}
********CParent.cpp***********
//ChildDlgからの値受け取り
if(IDC_WB==FALSE){
m_cameraControl->SetColorTempUser
(COLORTEMPMODE_USER1,21,16,23);
}else{
CClorDlg dlg(this);
red = dlg.GetRed();
green = dlg.GetGreen();
blue = dlg.GetBlue();
m_cameraControl->SetColorTempUser
(COLORTEMPMODE_USER1,red,green,blue);
}
GetDlgItemText(IDC_RED,str);
int red=atoi(str);
GetDlgItemText(IDC_GREEN,str);
int green=atoi(str);
GetDlgItemText(IDC_BLUE,str);
int blue=atoi(str);
1:モードレスダイアログ作成時に、親を引き渡しておく
例:
CChildDlg::CChildDlg(CWnd* pParent /*=NULL*/)
{
m_pParent = (CParentDlg*)pParent;
// ↑これは、CParentDlg*型でメンバ変数に宣言
}
必要なとき、m_pParentをつかって親ウィンドウにアクセス。
2:GetParent()や、AfxGetMainWnd()などを使って親ウィンドウをつかんだら
それに対し、SendMessageやPostMessageを使い
自作のウィンドウメッセージを投げる。
#詳細は長くなるので「自作」「ウィンドウメッセージ」などで検索してください
#例がゴロゴロでてきます。覚えておくと便利かも
3:(おまけ)値を引き渡すだけで、すぐに処理をする必要がない場合
モードレスダイアログ作成時、親のメンバ変数のポインタだけを引き渡しておき
それを使って、直接親のメンバ変数を書き換える。
親側(ダイアログ作成時)
dlg = new CChildDlg(...);
dlg->m_pData = &this->Data;
子側
void CChildDlg::Onxxx(int value)
{
*m_pData = value;
}
モードレスダイアログってCreate関数で表示するもんじゃなかった?
その辺のコードがないんだけど。
それと、m_cameraControl、CClorDlg dlg(this);、CChildDlgの関係は?
モードレスなら、maruさんの意見どおりにCreate関数がないですね。
あと、Create関数に渡す親ウインドウのthisポインタは?
確か、構築するとき
CChildDlg::CChildDlg(CWnd* pParent /*=NULL*/)
: CDialog(CChildDlg::IDD, pParent)
, m_clor(0)
途中で送信してしまいました。
もう一度....
モードレスなら、maruさんの意見どおりにCreate関数がないですね。
あと、Create関数に渡す親ウインドウのthisポインタは?
構築するとき
> CChildDlg::CChildDlg(CWnd* pParent /*=NULL*/)
> : CDialog(CChildDlg::IDD, pParent)
> , m_clor(0)
pParentに親のthisポインタを渡すのがいいと思います。
こういった設計ケースの場合親には、子DLGで変更のあったデータを
独自メッセージIDで親に対してSendMessage()するのが普通です。
const int CHILD_DLG_EDITED = WM_APP+100;//てきとう
const int EDITED_BY_SPIN = 1000; // 同じくてきとう
// 子DLG SPIN HANDLLER
void On_SPIN(){
::SendMessage( 親DLGのHWND,
CHILD_DLG_EDIT_CHANGED, // 親分、おいらはユーザーにやられちま
いました
( WPARAM)EDITED_BY_SPIN,// 被害者はSPINのやろうですぜ
( LPARAM)value_of_spin)// こんな値になりました。しくしく
// 以上報告終わり(合掌)
}
// 親DLG メッセージハンドラ
void On_CHILD_DLG_EDIT_CHANGED(
WPARAM wpar, LPARAM lpar)
{
int cause_of_edit = int( wpar);// 被害者種別
int valu_of_edit = int( lpar);// 犯行結果
// なんかする
}
この仕組みの良い点は、親側の構成変わっても子に影響が無い点。