I have a property page application. In it, created a dialog called mydlg which is inherited from CDialog.
In the first property page, in its OnInitDialog i tried to launch the mydlg like this:
mydlg m;
m.DoModal();
but it crashes.
If I move the two lines to the Initinstace in mypropertysheet, it works, the dialog launches. What is the proper way of calling the DoModal in the both places?.
Seconly, how to read the content of edit box on the mydlg from inside the mypropertysheet initinstance using the ID of the edit box.
After DoModal returns the edit box has been destroyed, so you cannot read it using the ID of the edit box. The mydlg class should read the edit box (usually in OnOK) and put the text into a mydlg member variable. After DoModal returns you can still read the mydlg member variable.
Related
Using Visual Studio 2013, I created a dialog resource using the resource editor. It is a child control with no border and is just a collection of radio buttons, push buttons, and static text. I want to turn this into a custom control in order to place this in several different locations. Let's call this a "Panel".
I then created a regular dialog and using the Toolbox "Custom Control", defined an area for the Panel. The Panel registers itself and has a valid window handle.
I used the following example:
https://www.codeproject.com/Articles/521/Creating-Custom-Controls
The parent's DDX gets hit and the _panel is properly instantiated:
MyDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX)
DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)
}
I read that I need to override the OnPaint() and OnEraseBkgnd(CDC* pDC) methods so the Panel class has these but they are empty. I do not have any custom painting to do as the Panel contains nothing but regular buttons.
What do I have to include in OnPaint()?
I also noticed that none of the member buttons are instantiated in the Panel like would normally happen in a dialog's DoDataExchange method. Instead, I've had to resort to dynamically creating each of the control's inside the Panel's PreSubclassWindow() method:
void MyPanel:PreSubclassWindow()
{
_groupBox.Create(_T("Options"), WS_CHILD|WS_VISIBLE|BS_GROUPBOX, CRect(11, 11, 112, 231), this, IDC_STATIC_GROUPBOX);
//... do this for every dialog element??? seems like overkill...
CWnd::PreSubclassWindow()
}
Why do I need to do this when I've already defined/designed the Panel and each of its controls in the resource editor?
If I do not do this in the PreSubclassWindow method, nothing will appear on the dialog.
Any help is appreciated. Thanks.
The article says override OnPaint and OnEraseBkgnd if you want to change the functionality. It doesn't say you have to override always.
Just remove ON_WM_PAINT and ON_WM_ERASEBKGND, remove OnPaint and OnEraseBkgnd if you don't need them. Or call the base class implementations if you are not making any changes:
void MyPanel::OnPaint() { CWnd::OnPaint(); }
BOOL MyPanel::OnEraseBkgnd(CDC* pDC) { return CWnd::OnEraseBkgnd(pDC); }
This will show a blank control with nothing in it, unless you add a child window to _panel as you have done in MyPanel:PreSubclassWindow
You are adding _groupBox to _panel. And you are adding _panel to the MyDialog.
MyDialog::DoDataExchange(...){DDX_Control(pDX, IDC_CUSTOM_PANEL, _panel)} is needed to invoke SubclassWindow for _panel. That in turn calls _groupBox.Create.
If MyPanel::OnPaint and MyPanel::PreSubclassWindow are not doing anything MyPanel appears as a blank control.
... do this for every dialog element??? seems like overkill...
You can directly add _groupBox to the main dialog. But if you want to add specific controls within MyPanel then you have to do it manually.
You can also create a child dialog within a main dialog. For example that's how a tab control works.
I simply want to open a child dialog and have it print a result from the parent dialog in one of the child's static text controls. Using breakpoints I noticed that both DoDataExchange and my overloaded OnInitDialog are never called in the child so the static text control crashes any time i try to print something to it. The child dialog does display itself fine otherwise.
What could be the problem ?
//in parent.cpp
CResultsDlg childResultsDlg = this;
childResultsDlg.DoModal(15.7); //overloaded to pass value to a child member var
more information from my previous post
Child Dialog - SetWindowTextA or SendMessageA crashes program - MFC
All of the basics of MFC are covered in the SCRIBBLE tutorial.
http://msdn.microsoft.com/en-us/library/f35t8fts(v=vs.90).aspx
An example of passing data into a dialog and displaying that data in dialog controls is provided in the tutorial with the CPenWidthsDlg.
When using MFC, if i have a main dialog box, then I another dialog box is called from the main, what message is sent to the main dialogue box to let it know it has focus, is it WM_SETFOCUS()? If so, what paramaters are needed? The problem I have is, a value is selected in the child dialog and I want it copied to an edit control in the main dialog box once it (the child dialog) closes. Right now, I have it so the second dialog box copies its value to a global variable, but once the second dialog box closes, I wanted to the main dialog box to grab the global variable and display in the edit control.
You can also use a member variable in the child dialog box, like
CChildDialogBox dlg;
if (dlg.DoModal() == IDOK) // child dialog saves the value in a CString member variable m_str
{ GetDlgItem(IDC_EDIT1)->SetWindowText(dlg.m_str);
}
This MSDN article describes how you can set up member variables connected to controls in a dialog box.
I realized my problem, really a beginner's mistake, I though after a DoModal call a function would immediately exit. I didn't know I could perform additional code(assigning the edit control variable a new value and then SetWindowText) after the call, before the function ended.
I am trying to get some data from a dialog in an MFC C++ dialog-based application. I ahev made this image to help you understand better my situation:
When the user clicks the findWndBtn in the left-side window, the right-side dialog appears by dlg.DoModal() function. After the user completes the fields in the right-side the dialog, the following code is executed:
HWND WindowHandle = FindWindow( WindowClass, WindowName );
CDialogEx::OnOk();
After the dialog exits, I want the m_myWndHwnd field to pe filled with the handle found by that dialog.
How can I do that?
Tell me please, If didn't said enough, for me to complete with the detail that you need.
Two options:
Have the second dialog post a message back to the first dialog, passing the result you want to store as an argument.
Have the second dialog store the result in a class member variable, and have the caller retrieve it (via a member function or directly if you're OK with that) when the dialog returns.
I am trying to create a wizard like structure using dialog boxes...So I replaced the code in CDialog1App as below
CDialog1Dlg* dlg = new CDialog1Dlg;
m_pMainWnd = dlg;
dlg->Create(IDD_DIALOG1);
dlg->ShowWindow(SW_SHOW);
the above worked fine...its displying the dialog box.but I have added another dialog box...
So in the first dialog box if the user clicks Next it has to hide the first dialog box and display the second dialog..
//CDialog1 class
void CDialog1Dlg::OnBnClickedNext()
{
// TODO: Add your control notification handler code here
CDialog2* dialog2 = new CDialog2();
dialog2->Create(IDD_DIALOG2);
dialog2->ShowWindow(SW_SHOW);
this->ShowWindow(SW_HIDE);
}
in the above code am creating an object for the Dialog2 class and trying to show that....
Now the problem is,when I click next its hiding both the windows..What can I do..I tried several types but its still its not workin..Please dont suggest me to do with PropertySheet..It will work with that, i know ...but I want this using Dialog Box for some reason
You're creating the dialog2 with the default parent window (NULL):
dialog2->Create(IDD_DIALOG2);
But the default parent seems to be dialog1 in your case. And since you hide dialog1 which is the parent of dialog2, dialog2 is also hidden.
Find the window (CWnd) of either your main app dialog (if you have one visible apart from your wizard), or use the desktop window as the parent.
For example:
dialog2->Create(IDD_DIALOG2, GetDesktopWindow());