Solved

using CRichEditCtrl->SetEventMask to send a EN_CHANGE message to edit box in parent dialog

Posted on 2011-09-25
20
2,346 Views
Last Modified: 2013-11-20
I'm trying to send a message from a dialog to the parent dialog to update one of its edit boxes. When I click on the edit box and go to the properties pane to add a message to the edit ctrl for EN_CHANGE it creates this function:
void IO_Input::OnEnChangeNorecords()
{
	// TODO:  If this is a RICHEDIT control, the control will not
	// send this notification unless you override the CDialog::OnInitDialog()
	// function and call CRichEditCtrl().SetEventMask()
	// with the ENM_CHANGE flag ORed into the mask.
	// TODO:  Add your control notification handler code here
}

Open in new window

So then I add what I think is correct in the initdialog override:
	CDialog::OnInitDialog();
	CRichEditCtrl *pRichEdit = (CRichEditCtrl*)GetDlgItem(IDC_NORECORDS);
	pRichEdit->SetEventMask (EN_MSGFILTER | ENM_CHANGE);

Open in new window

It crashes at the call to SetEventMask.
I was planning on sending the message on the OnOK function from the child dialog like this:
void InputOptions::OnBnClickedOk()
{
	::PostMessage(GetParent()->GetSafeHwnd(),IDC_NORECORDS,(WPARAM)ENM_CHANGE, (LPARAM)0);
	OnOK();
}

Open in new window

I hope this is enough info...
0
Comment
Question by:zliminator
  • 9
  • 8
  • 3
20 Comments
 
LVL 7

Assisted Solution

by:Slimfinger
Slimfinger earned 190 total points
ID: 36596376
Any debug or exception information?
Is the pRichEdit pointer valid?

Also, you may want to check the value of the current event mask

DWORD mask = pRichEdit->GetEventMask();

And preserve it like pRichEdit->SetEventMask(mask |  ENM_CHANGE | EN_MSGFILTER );

...though I doubt that would have been the cause of your crash.
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 60 total points
ID: 36597371
>>parent dialog to update one of its edit boxes

There you talk of an edit box but also ask about a rich edit control.  Is it a richedit control or a simple editbox ?
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 60 total points
ID: 36597376
ps.
CRichEditCtrl *pRichEdit = (CRichEditCtrl*)GetDlgItem(IDC_NORECORDS);
That will always compile and run - a cast like that is brutal and does NOT check if the window really is a richedit control.
0
 

Author Comment

by:zliminator
ID: 36600444
The problem is that there is no EMN_CHANGE message for the edit box I create on the parent dialog - its not a CRichEditCtrl. I tried the DWORD mask = pRichEdit... and it still crashes. I'll do some more research and let you know. I'll assign points accordingly soon, either way.
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 60 total points
ID: 36600953
If it is NOT a richedit control then it does NOT have any richedit functionality - hence your crash.  YOu must use a CEdit cast.
CEdit* pEdit = (CEdit*)GetDlgItem(IDC_NORECORDS);
0
 
LVL 7

Assisted Solution

by:Slimfinger
Slimfinger earned 190 total points
ID: 36600980
It looks like you haven't actually created a rich edit control.

I think to use it you need to include a particular library, e.g.:

HINSTANCE module = LoadLibrary("RichEd20.dll");

hRichEdit = CreateWindowEx(WS_EX_TRANSPARENT, "RichEdit20A", "", style, 0, 0, width, height, hParent, NULL, hInstance, NULL);
0
 
LVL 7

Assisted Solution

by:Slimfinger
Slimfinger earned 190 total points
ID: 36600997
Andy's response is more appropriate, if you don't need the control.
0
 

Author Comment

by:zliminator
ID: 36601032
I think I may be asking the wrong question. Can't I accomplish sending a message to the parent if the child is a modeless dialog?
modeless tutorial
0
 
LVL 7

Accepted Solution

by:
Slimfinger earned 190 total points
ID: 36601072
Can you just do a simple SendMessage(hWnd, etc., etc., etc.) to the base window:

HWND hWnd = GetDlgItem(IDC_NORECORDS);

0
 
LVL 7

Assisted Solution

by:Slimfinger
Slimfinger earned 190 total points
ID: 36601096
Also, you probably don't want to explicity send EN_CHANGE; I think that is done via windows when you change the control's contents.

You can just use the default for that (simply edit the OnEnChange function you added), or create a custom message and handler.
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:zliminator
ID: 36601166
I tried this:
	HWND hWnd = GetDlgItem(IDC_TESTEDIT);
	::SendMessage(hWnd, IDC_TESTEDIT,(WPARAM)EN_CHANGE, (LPARAM)0);

Open in new window

and got this:
Error	2	error C2440: 'initializing' : cannot convert from 'CWnd *' to 'HWND'

Open in new window

IDC_TESTEDIT is the edit box in the parent window and I have a function to handle the EN_CHANGE msg
0
 

Author Comment

by:zliminator
ID: 36601180
the error was for line 1: HWND hWnd = GetDlgItem(IDC_TESTEDIT);
0
 
LVL 7

Assisted Solution

by:Slimfinger
Slimfinger earned 190 total points
ID: 36601184
You're using the wrong version of the function.

Use GetDlgItem(HWND, int)

...where HWND is the parent of the control you want
0
 
LVL 7

Assisted Solution

by:Slimfinger
Slimfinger earned 190 total points
ID: 36601195
BUT, since you aren't using a rich edit control, why not just get rid of everything except the OnEnChange handler that you already have?
0
 

Author Comment

by:zliminator
ID: 36601267
I can do a cast to HWND but it comes up as "      0x00000000 {unused=??? } in the debugger.
It works if I call it from the parent dlg which is where the IDC_EDITTEST control is.
0
 
LVL 7

Assisted Solution

by:Slimfinger
Slimfinger earned 190 total points
ID: 36601328
I think you should read each of the above comments a little closer.  Several of them seem to solve your problem.
0
 

Author Comment

by:zliminator
ID: 36602272
You can use either version of GetDlgItem - just 1 returns the handle and the other you pass the pointer to it as a param. I'm getting the right HWND for the parent, I checked it going into the parent (as this) and in the child as returned by GetParent(). I also checked the handle of the controls going in the parent using:
	HWND hWnd2;
	HWND *phWnd = &hWnd2;
	GetDlgItem(IDC_TESTEDIT, (HWND*)phWnd);
	GetDlgItem(IDC_TESTBUTTON, (HWND*)phWnd);

Open in new window

and in the child I did this:
	HWND hWnd2;
	HWND *phWnd = &hWnd2;
	GetParent()->GetDlgItem(IDC_TESTEDIT, (HWND*)phWnd);
	::SendMessage(hWnd,EN_CHANGE,(WPARAM)0, (LPARAM)0);
	GetParent()->GetDlgItem(IDC_TESTBUTTON, (HWND*)phWnd);
	::SendMessage(hWnd,BN_CLICKED,(WPARAM)0, (LPARAM)0);

Open in new window

I had breakpoints set at each of the message handlers in the parent. I tried it with both modal and modeless. I'll try the custom message thing.
0
 

Author Comment

by:zliminator
ID: 36602303
That's wrong it should be:
	HWND hWnd2;
	HWND *phWnd = &hWnd2;
	GetParent()->GetDlgItem(IDC_TESTEDIT, (HWND*)phWnd);
	::SendMessage(hWnd2,EN_CHANGE,(WPARAM)0, (LPARAM)0);
	GetParent()->GetDlgItem(IDC_TESTBUTTON, (HWND*)phWnd);
	::SendMessage(hWnd2,BN_CLICKED,(WPARAM)0, (LPARAM)0);

Open in new window

It still doesn't work.
0
 

Assisted Solution

by:zliminator
zliminator earned 0 total points
ID: 36678483
Here's how I did it:
Child::Child(CWnd* pParent /*=NULL*/)
	: CDialog(Child::IDD, pParent)
{
	m_Parent = (CDialog*)pParent;
}
...
void Child::OnBnClickUpdate()
{
	((Parent*)m_Parent)->DoTest(1);
	((Parent*)m_Parent)->m_y = 1;
}
...
void Parent::DoTest(int param)
{
	int j = param;
}

Open in new window

There's some other things that went with it.
This article explains it.
0
 

Author Closing Comment

by:zliminator
ID: 36895922
I found so much stuff on this site just searching I really didn't need to post the question.
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now