I've got a Dialog-based Application.
By default Visual Studio created an App and a Dlg class.
In the App's InitInstance, to show the dialog box, there is a declaration CMyDlg dlg, then a dlg.DoModal().
My question is, how do I access dlg members from my other classes? For instance, I created an edit box with a control variable associated with it. I want one of my other classes to set the text of the edit box and display it.
Help much appreciated.
Related
I came across a tutorial showing how to embed a child dialog within a parent dialog using MFC. I am using Visual Studio 2015. My setup is as follows. Using the Visual Studio MFC Application Wizard to create a new MFC Visual C++ Project called MFCApplication3, I select a Dialog based application where MFC is used in a Shared DLL. Using boilerplate code, I have a simple Thick Frame Dialog, no maximize or minimize box.
In my resource view, I go to my Dialog editor to edit the main dialog. I add a picture control with a blank area in the center and name it IDC_STATIC. This will simply be used as a placeholder for my child dialog that I wish to embed. It looks like:
Still in the resource view, I create a new Dialog. I call it IDD_CHILD. I add some components. It looks like this:
Now back in the Solution Explorer, I add a class using the Add Class wizard, selecting to add an MFC Class. The class name is CChildDialog, with a base class of CDialog, and I use the already generated IDD_CHILD as the Dialog ID. It generates the .cpp and associated .h file. In the constructor of CChildDialog, I add a call to the Create function so the constructor becomes:
CChildDialog::CChildDialog(CWnd* pParent /*=NULL*/)
: CDialog(IDD_CHILD, pParent)
{
Create(IDD_CHILD, pParent);
}
Now I modify the dialog code generated automatically when I created the project. In CMFCApplication3Dlg.h, I add a private member of type CChildDialog* called m_childDlg, and #include the associated header file. In CMFCApplication3Dlg.cpp, I add this to the OnInitDialog function prior to the return statement:
CRect rc;
GetDlgItem(IDC_STATIC)->GetWindowRect(rc);
ScreenToClient(&rc);
m_childDlg = new CChildDialog(this);
m_childDlg->MoveWindow(rc);
Now I build the solution, run it, but it looks like it does in the first picture. A blank placeholder spot for a child dialog, but no child dialog. What could I be doing wrong?
It turns out (while composing this question) that the answer to my problem was two properties I need to set while in the resource view. When I have the child dialog open (IDD_CHILD), within the properties pane, I need to set the following properties:
Style: Child
Visible: TRUE
(I am not sure why Visible defaults to FALSE in this case). Making those two changes, voila! I get my embedded dialog:
Background
I am woefully inexperienced with MFC and C++.
I have a set of dialogs that all have a small section with the same set of controls and extremely similar code.
I would like to separate that small section of controls from all dialogs move the code from all the dialog classes into a single class.
Problem
I'm not sure how to go about it. All my ideas all seem to have their own problems because I am so inexperienced.
Could I make a super class these dialogs inherit from that creates the controls dynamically given an (x, y) and that hooks up all the connections and communicates the few specifics through virtual methods?
The problem is I don't know the specifics:
Where would the super class inherit from? (CWnd? CDialog?)
Where would I create the controls in the super class? (OnInit? Constructor?)
Where would I initialize the super class in its subclasses? (OnInit? Constructor?)
Would I just have two message maps? One for the super class and one for the sub class?
Are there any other pitfalls I should watch out for?
The small section that you want to reuse can be an ordinary modeless dialog, derived from CDialog. You can create its controls with the resource editor - just like any other dialog - so they won't have to be created dynamically. The trick is to turn off the dialog's titlebar style (in the resource editor) so it will not be visually apparent that this section is a separate dialog. It will blend right in with the parent dialog.
For each place you want to reuse this dialog just create it and place it on the parent dialog with (x, y) coordinates using SetWindowPos.
I'm turning mad with a little problem with Visual Studio 2008 and MFC. I'm working on a project actually and I'm trying to create an SDI Application. Right, now I want to add a dockable DialogBar. Well, the first time I added it with the resource view, I could create the bar without problems.
But... I want to add some controls like a couple of ListBox, buttons and so on. The program doesn't allows me to create member variables for these controls. The option appears in grey.
Searching a little, I found that it's mandatory to create a new class derived from CDialogBar and "enhance" it with the Message handler and so on. I've been reading some tutorials and it didn't work for me.
Can you please help me? I'm starting to get nervous, the use of dialogbars is mandatory in my design and I've never implemented them before.
Thank you very much, and sorry for my poor english.
You can add a control member variable by hand instead of using the wizard. All it takes is a call to DDX_Control in the dialog bar's DoDataExchange function.
But CDialogBar-derived classes do not handle control clicks. The CDialogBar class forwards all of those messages to the dialog bar's parent window. So be prepared to add the message handlers to the parent (usually CMainFrame).
For learning purposes you might try creating your dialog bar as a CDialog first, to see the proper code lines and message map entries supplied by the wizard. Then you can copy/move these details as appropriate into your actual code project.
I am writing a Dialog Based C++ application with MFC for the GUI. After the creation of the project, Visual Studio also created two classes ProjectNameApp and ProjectNameDlg. When adding a Menu to my application the menu item handlers (for the menu buttons) are added as methods to the ProjectNameApp class. In one of these handlers I want to access a variable of the ProjectNameDlg class, more specific, a CComboBox. But that, of course, is not possible. So I have two questions:
is there a way to acces that CComboBox variable from the Dlg class?
if not, how can I move the Menu handlers to the Dlg class to directly use the CComboBox variable?
Also, my application has to be dialog based, and it has to have a menu.
The last I dealt with any of this was in VS-2008, but if memory serves the CDialog object is probably allocated on the stack in CProjectNameApp::InitInstance(). There is probably some code there that looks kind of like:
CProjectNameDlg dlg;
int nResponse = dlg.DoModal();
One thing you could do is to add a pointer to the dialog as a member of the ProgramNameApp class. So in ProgramNameApp.h add a data element like:
std::tr1::unique_ptr<CProjectNameDlg> m_pDlg;
Then change the code in CProjectNameApp::InitInstance() to be:
m_pDlg = std::tr1::unique_ptr<CProjectNameDlg>(new CProjectNameDlg());
int nResponse = m_pDlg->DoModal();
Naturally you'd have to be on the lookout for any other uses of dlg and change them accordingly.
I'd like some help on using MFC without the document/view architecture.
I created a project without doc/view support, Visual C++ created a CFrameWnd and a view that inherits from CWnd. I replaced the view inheriting from CWnd with a new view that inherits from CFormView.
However, when I run my program, after I close the window I get a heap corruption error.
If inside where the frame window handles WM_CREATE, you change the code to create the instance of CFormView with the "magic" id of AFX_IDW_PANE_FIRST, you'll find it becomes the view for the frame window. This is due to the behaviour of CFrameWnd::InitialUpdateFrame(), which will be called from within MFC. The MSDN page comments on this helpful little feature:
http://msdn.microsoft.com/en-us/library/ch3t7308.aspx
Since you want to use the dialog editor and you don't want the document/view architecture, then maybe a "Dialog based" application is what you need.
The problem is MFC's lifecycle management. The view declaration (created by Visual C++ wizard) is:
CChildView m_wndView;
I replaced the above code with:
CChildFormView m_wndView;
CChildView inherits from CWnd, CChildFormView inherits from CFormView. Both views were created by the wizard, but only CChildFormView uses the DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE macros.
Since m_wndView is being created in the stack, when MFC automagically calls delete I get the error.