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.
Related
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.
Currently there are several ways to get a ChildWindow handle; FindWindowEx (uses parent handle, plus window caption), GetWindow (uses parent handle, and Z-Order), and EnumChildWindows. None are satisfactory for my application.
Would like to use something like FindWindowEx, but this requires knowledge of the contents of the TextBox (caption) that's used by FindWindowsEx. This works if the TextBox contents is static, but in most cases the contents change and and would be unknown to the Application trying to find the TextBox handle.
Does anyone know of a Win32 API that would function like FindWindowEX, using the Parent Handle, but instead of the ChildWindow caption, looks for a user specified TAG property for the ChildWindow that would remain static?
The GetDlgItem function accepts the parent window handle and child item ID.
It is not limited to dialog boxes despite the name.
You can use the GetDlgItem function with any parent-child window pair, not just with dialog boxes.
So I am creating an button with the CreateWindowEx() function with it's parent(some value) in the parent WM_CREATE message handler part with it's own user data i.e the very last parameter of CreateWindowEx() is an pointer to some arbitrary data.
When an root/main window is created we receive an
WM_CREATE or WM_NCCREATE message which allows us to Access this date with an CREATESTRUCT via the LPARAM value and assign it to the window via the SetWindowPtr(user data)
But when an child control is created and attached to this parent the parent window procedure doesn't receive the WM_CREATE message and the creation data for this button
Passed into the CreateWindowEx () is lost
Is there a way to know when an child control has been successfully created(or ready to be displayed) in this parent in the parent window procedure so I can fulfill the above task?
Basically I want to create an heirarchy of controls (like in Java with panels and panes) with the parent creating it's children when it receives it's WM_CREATE(or some other message just to know when I can start assigning children to it)and those children in turn creating their own children when it receives their WM_CREATE messages and so own.
A parent window receives a WM_PARENTNOTIFY for child window creation (and a few other events). Be sure not to set the WS_EX_NOPARENTNOTIFY extended style (which is set by default for controls created by the dialog window class).
The data received as part of the WM_PARENTNOTIFY upon window creation includes the LPCREATESTRUCT that was sent to the window during WM_NCCREATE/WM_CREATE (WM_PARENTNOTIFY occurs only if the window was successfully created).
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.
I'd like to obtain the same values via code. However I'd like to obtain the top-most or root windows in the hierarchy
I seem to have got the Root Parent with
HWND rootWinHandle = GetAncestor(activatedWinHandle, GA_PARENT);
However I can't get the owner window correctly. Tried
HWND rootOwnerWinHandle = GetAncestor(activatedWinHandle, GA_ROOTOWNER);
For a particular modeless dialog, Spy++ returns the Main Exe window whereas the above line returns the input i.e. activatedWinHandle. Am I looking at the wrong api ?
I'd like to obtain this without MFC if possible... coz nothing else in my project requires it.
See the GW_OWNER flag for GetWindow.
The GetParent documentation states:
If the window is a child window, the return value is a handle to the parent window. If the window is a top-level window, the return value is a handle to the owner window.
Try GetParent(). I believe this will return the owner window of a window without the WS_CHILD style, and the parent window of a window with WS_CHILD.
Only bit of insight i can add it from Raymond Chen:
Remember that owner and parent are two
different things.
Modal dialogs disable their OWNERs.
All top-level windows have the desktop
as their PARENT.
From: What's so special about the desktop window?
Special demo (+src):
http://files.rsdn.ru/42164/parentowner.zip
screenshot: http://files.rsdn.ru/42164/parentowner.png
kero