MFC SendMessage() from Child to Parent

Hello! I've created a standard MFC dialog app using the VS C++ wizard. Basically, I have a button in the parent dialog that brings up a child dialog - the child dialog does some calculation - then I want the parent dialog to show the result in a custom 'status' control. I've found ppl with a similar problem and attempted to follow their solution to no avail so I'm asking here, please. Thank you :)

I do have a member variable 'm_hStatus' which is able to display the info I want but will only work within the TestSockDlg.cpp
m_hStatus.SendMessage(WM_SETTEXT, 0, (LPARAM)"My result is here.");


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// TestSockDlg.h : header file
class CTestSockDlg : public CDialogEx
{
// Construction
public:
	CTestSockDlg(CWnd* pParent = NULL);	// standard constructor

// Dialog Data
	enum { IDD = IDD_TESTSOCK_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support


// Implementation
protected:
	HICON m_hIcon;

	// Generated message map functions
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	afx_msg LRESULT OnSetText(WPARAM, LPARAM);
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedListen();
	afx_msg void OnBnClickedConnect();
	CEdit m_hStatus;
};



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// ListenDlg.h : header file

class CListenDlg : public CDialog
{
	DECLARE_DYNAMIC(CListenDlg)

public:
	CListenDlg();
	virtual ~CListenDlg();
	enum { IDD = IDD_LISTEN_PORT };

protected:

	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();

	DECLARE_MESSAGE_MAP()
public:

	void OnClickDlgListen();

	afx_msg void OnBnClickedOk();
	int m_listenToPort;

	//delete me - this is not the same m_hStatus from TestSockDlg
//	CEdit m_hStatus;
};



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// ListenDlg.cpp : implementation file
//

#include "stdafx.h"
#include "TestSock.h"
#include "ListenDlg.h"


HWND hwnd; // <---- i want the handle to the parent window...


// CListenDlg

IMPLEMENT_DYNAMIC(CListenDlg, CWnd)

//CListenDlg::CListenDlg()
//{
//}

//IDD is the resource which needs to be connected to the dialog box
CListenDlg::CListenDlg() : CDialog(CListenDlg::IDD)
{

	m_listenToPort = 0;
}

CListenDlg::~CListenDlg()
{
}


BEGIN_MESSAGE_MAP(CListenDlg, CWnd)

	ON_BN_CLICKED(IDOK, &CListenDlg::OnBnClickedOk)
END_MESSAGE_MAP()



// CListenDlg message handlers


void CListenDlg::OnBnClickedOk()
{
//...do some calculation/gather results...

//i want to use 'SendMessage()' here to display the result to the control at //m_hStatus from TestSockDlg

CDialog::OnOK();
}

Last edited on
Without checking your code because I barely know anything about MFC, the task should be simple enough.

You most likely have at least two classes: One per dialog box. The solution:

1. Add a public method to the class that represents the parent dialog box that accepts the result to be shown. Something like void SetResultMessage(const std::wstring &message);. You know best so you define the prototype of the method in a way that best suits you.
2. Go to the other class and add or modify the constructor. Make it accept an object pointer of the type that represents the parent dialog box. Save that pointer in a member variable.
3. Back into the parent dialog box, you say you show the child box on the press of a button. Well, during this button click, construct a new child dialog box object with the new constructor. Make sure you pass this as the value for the new constructor argument.
4. The box displays as usual. Let the user interact with it and I guess there is an OK button in this child dialog box or something equivalent.
5. During this OK event, take the pointer to the parent dialog box and call SetResultMessage().

Simple, right? This can also be varied to become a passive approach. Instead of the child dialog box receiving a parent pointer on which to act, you can make the child expose the data for anyone's taking. Basically you add a method to the child, not the parent, then the parent shows the child and verifies if the dialog was dismissed with OK or CANCEL. If it was with OK, it grabs the data from the child.
Hi, thanks for the reply. This is what I'm having trouble with:
Make it accept an object pointer of the type that represents the parent dialog box.


The parent dialog box type is CTestSockDlg
I'm getting errors when I try something like:
1
2
3
4
5
6
CListenDlg::CListenDlg() : CDialog(CListenDlg::IDD)
{
     CTestSockDlg Object;
     CTestSockDlg *pObject = &Object;

}


This is my first time I'm working with multiple dialog boxes

Please bear with me if this takes me a bit of time :) I really appreciate it.
Last edited on
My idea was something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//This would be a member variable inside the CListenDlg class:
CTestSockDlg *_parent;

//And this would be the constructor:
CListenDlg::CListenDlg(CTestSockDlg *parent) : CDialog(<whatever the base constructor is>), _parent(parent)
{
    ...
}

//And this is how you would start the child dialog from the OnClick of a button in the parent dialog box:
CListenDlg childDialog = this;
...
childDialog.ShowDialog();

//And this is how the child would pass along some string data to the parent from a function in
//the parent's class that I will call GimmeData():
_parent->GimmeData(L"This is the data I have for you, my parent!");
Wow ! Thank you so much !
I've tried doing something similar a year ago and became confused and frustrated...
I'll be studying each part of this for many hours to come...
At a glance I understand it but there's a lot of syntax that I'm not used to seeing working together.

I had to #include "TestSockDlg.h" in the 'ListenDlg.h' header so that this would work.

Honestly, I think one of those light bulbs just lit up above my head haha. Thanks again :)


PS: where/when do i delete the pointer to clear up the memory ? the parent dialog does not close until the app closes...
Last edited on
Don't worry about the pointer itself as it is only 4 bytes (8 bytes in 64-bit mode). You are probably thinking about the object pointed to by the pointer anyway. That object needs to live for as long as the window that it represents live and maybe just a bit more. So don't delete the parent!
Gotcha ;)
Topic archived. No new replies allowed.