MFC - communication between two CDialog - visual-studio-2010

I have a MFC dialog based application.
The main dialog contain a child dialog (used in a CTabCtrl control).
CDialog mainDlgClass;
CMyChildDialog childDlgClass;
How I can be able to modify the controls of the child dialog from the main dialog or the possibility to send a message, eg: via PostMessage and using RegisterWindowMessage so I can modify the child dialog's controls?
I dont know howto retrieve a handle of the child dialog.
void mainDlgClass::check()
{
if(condition)
PostMessage_to_the_child_dialog(***);
OR
if(condition)
Modify_CStatic_text_on_the_child_dialog(***);
}
Edit:
Screenshot of the structure:
Resource editor
Main dialog + CTabCtrl containing the ChidlDialog
Child dialog have WS_CHILD property set.
Resolved.

Assuming that the second dialog is a child dialog of the main (it has WS_CHILD style), it must be created by the main dialog. Child dialog is confined to a client area of the parent window.
You can provide public member functions (accessors) in the child dialog class to be accessed by the main dialog and change whatever you need. Alternatively, you can access subclassed child’s dialog controls directly if they are declared public (led OOP-like).
The problem is that you may refer to a second dialog as child while it is not really a child (does not have WS_CHILD style). Nevertheless, you can use method described above if the second dialog is spawned as modeless.
If modal, the approach may differ, since the main dialog is disabled; therefore, user cannot access main dialog controls. If this is a case, could you please give us more information?
For example, under what circumstances, you want to alter controls.

Related

How do I handle a message from a user generated combobox in my main window?

I've created a combobox manually in my main window using CreateWindow(). Because of this it has no ID associated with it only the handle returned by CreateWindow(). When the user makes a selection from the combobox list and the combobox throws a message, how do I handle that in the WinProc WM_COMMAND code since there is no ID associated with the combobox? As far as I can tell, I must know the combobox ID to handle the message. This is especially problematic once I have more than one combobox in the main window. Surely there is something I am missing and there is a simple answer.
Okay. So what Igor Tandetnik stated is the answer.
It does have an ID - whatever you passed for hMenu parameter of CreateWindow...
This is also discussed in the following link.
What is winapi HMENU and how do i use it?
From the above link:
HMENU is a handle to a menu, e.g. as created by LoadMenu (which creates a menu from a specification in a resource).
But, the CreateWindow function re-uses the same argument for two different purposes. With a top-level window it's a menu handle, but with a child window it's the child window id, which should be in 16-bit integer range...
When creating a child window, just cast the id to HMENU.

Some quick questions about Windows API control IDs

I've got a few questions here about control IDs:
Can they be changed at runtime by setting GWL(P)_ID? Or will the dialog manager not be fooled? Since this is a framework, I need to generate them at runtime; initially they are 0.
What is the uniqueness scope of control IDs, the whole toplevel window or just the immediate parent of a control? Controls in my framework are stored in a custom container window, there are multiple such in each toplevel window.
Thanks.
Question 1
Control IDs can be changed by calling SetWindowLongPtr:
SetWindowLongPtr(hwndChild, DWL_ID, new_id);
Question 2
From the documentation for CreateWindow, with my emphasis:
hMenu [in, optional]
A handle to a menu, or specifies a child-window identifier depending
on the window style. For an overlapped or pop-up window, hMenu
identifies the menu to be used with the window; it can be NULL if the
class menu is to be used. For a child window, hMenu specifies the
child-window identifier, an integer value used by a dialog box control
to notify its parent about events. The application determines the
child-window identifier; it must be unique for all child windows with
the same parent window.
Or from the documentation of GetDlgItem:
You can use the GetDlgItem function with any parent-child window pair,
not just with dialog boxes. As long as the hDlg parameter specifies a
parent window and the child window has a unique identifier (as
specified by the hMenu parameter in the CreateWindow or CreateWindowEx
function that created the child window), GetDlgItem returns a valid
handle to the child window.
So the scope for IDs is the parent window. But this also tells you that you can specify the ID when you create the child window via the re-purposed hMenu parameter.

What difference between control's window handle and controlID

I'm learning Win32 assembly. Have some question I search but not suitable result.
Anyone can explain for me What difference between control's window handle and controlID.
They have nothing in common. Every window has a handle, returned by CreateWindowEx(). Such a window can have a few extra properties attached, like a menu handle. The hMenu argument in CreateWindowEx(). If the window doesn't have a menu, a child window won't have one, then you can use that argument to pass an arbitrary other bit of data. It will be assigned to the GWLP_ID property (see GetWindowLongPtr). Also note the GWLP_USERDATA, an extra property that's entirely yours to use as you see fit.
Dialogs take advantage of this, a dialog template that you create in the resource editor gives you a way to number the child controls. With a helper function like GetDlgItem() to get the handle back for a control with a specific number. Which is pretty necessary for dialogs since it is Windows that create the child controls from the dialog template so you don't know the window handles for them yourself.

Group dialog items to a single "Group" (Visual Studio)

I want to create a dialog window for change settings of an application. Below is a screenshot of Adobe Reader. After using Spy++, I guess that:
On the right side, all the control (buttons, combo boxes...ect) are belonged to a GroupBox.
For each category in the TreeView Control on the left side, there is a corresponding GroupBox which groups all the controls related to this category.
When users choose between different categories, it hides one GroupBox and shows another one GroupBox.
But in the source code (xxx.rc, resource file) below, I didn't see anywhere where I can specify the "parent" of a dialog item.
Even I open xxx.rc with "Resource View" (not viewed as codes), I can't find any option to specify the parent of a dialog item in its property page.
I would like to know how to assign a parent (which is a GroupBox in my case) to a dialog item, or group dialog items to a single group,in the .rc file, i.e when one create the dialog items. (I guess one can do so by modifying the .rc file.)
GROUPBOX "View",IDC_SECTION_VIEW,101,6,228,88
LTEXT "Default &Layout:",IDC_DEFAULT_LAYOUT_LABEL,107,19,108,9
COMBOBOX IDC_DEFAULT_LAYOUT,215,17,108,64,CBS_DROPDOWNLIST | WS_TABSTOP
LTEXT "Default &Zoom:",IDC_DEFAULT_ZOOM_LABEL,107,36,108,9
COMBOBOX IDC_DEFAULT_ZOOM,215,34,108,149,CBS_DROPDOWN | WS_TABSTOP
CONTROL "Show the &bookmarks sidebar when available",IDC_DEFAULT_SHOW_TOC,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,107,53,216,9
...
...
...
I would like to know how to assign a parent...
SetParent Windows API. You supply HWND of your control and the handle of the supposed new parent.
In resource script, the controls will be children of the dialog itself, but on runtime you are free to change this and group them into a hierarchy of your interest.
You might also want to consider putting the supposed child groups into separate dialog template and have it as "composite control" - to be instantiated separately and be a child of a higher level dialog.
UPD. Have a look at this simple project (C++/ATL): AtlChildDialog. In particular, at main dialog's WM_INITIDIALOG handler:
ATLVERIFY(m_ChildDialog.Create(m_hWnd, (LPARAM) this));
ATLVERIFY(m_ChildDialog.MoveWindow(50, 50, 200, 150));
m_ChildDialog.m_EditWindow.SetWindowText(_T("Some Text"));
m_ChildDialog.ShowWindow(SW_SHOWNORMAL);
m_ChildDialog.SetFocus();
All together on runtime:

Is it possible to design Dialogs within a Dialog, both created with ressource editor?

Is it possible to create a dialog ressource with a resource editor and then put this dialog (possibly multiple times) into another dialog?
Here's some background. I need to create a C++ program (Windows). The user needs to input a set of similar data on a dialog. Say, for simplicity's sake, an element of this data-set consist of an edit control and a scrollbar. Since this combination (edit + scrollbar) needs to be put onto the dialog for each element for the data-set, I thought I could create a simple dialog with just one edit control and one scrollbar, and then put this dialog mutliple times onto its "parent" dialog.
So, is this possible at all. Any pointers will be greatly appreciated.
Yes, you can do this.
In the dialog editor, set the "Control Parent" flag on the parent dialog. (This will ensure the tab key works to cycle through items in the child dialogs as if they were part of the parent dialog.)
Make sure the child dialog(s) have the "Child" flag set in the dialog editor. Visually, they'll look like dialogs without any border at all in the editor.
At runtime, create the child dialogs as children of the parent dialog using CreateDialog (or CreateDialogParam, etc.). When calling CreateDialog you specify the dialogproc for each window.
I often make the child dialog procs do little more than forward messages to the main window's dialog proc (calling it directly; not via SendMessage), but you have to be careful, obviously. You have to be especially careful if you are creating multiple copies of the same dialog in a single parent, since obviously the control IDs within that dialog will all be the same and you need to differentiate them (perhaps by the parent's hWnd).
You don't have to forward messages to the parent, though. I just do usually do that so that most of the dialog's logic is in one place instead of spread out.
EDIT: Corrected statements about creating the child dialogs, window classes etc. I was mixing up dialogs and normal windows, making things more complex than they are in this case. Sorry about that!

Resources