Is there a way I can iterate all labels (CStatic objects) in a dialog?
Thanks
Vaclav
Use EnumChildWindows, and check for the class name "STATIC" (use
GetClassName) of the window in the callback.
Dave
--
MVP VC++ FAQ: http://www.mvps.org/vcfaq
>Hello
>
>Is there a way I can iterate all labels (CStatic objects) in a dialog?
CWnd::GetWindow will let you iterate over all child windows. Less
conveniently, there's ::EnumChildWindows. As for iterating over just the
CStatics, you can filter them by using RTTI on the CWnd pointers returned by
CWnd::GetWindow, e.g.
// MFC style
if (pWnd->IsKindOf(RUNTIME_CLASS(CStatic)))
{
CStatic* p = static_cast<CStatic*>(pWnd);
}
// Standard C++ style
if (CStatic* p = dynamic_cast<CStatic*>(pWnd))
{
}
Note that this picks up only those labels you've bound to CStatic objects.
To find all the labels, including ones not bound to CStatics, use
::GetClassName and compare to "STATIC".
--
Doug Harrison
Microsoft MVP - Visual C++
>CWnd::GetWindow will let you iterate over all child windows. Less
>conveniently, there's ::EnumChildWindows.
To be clear, ::EnumChildWindows recursively enumerates the child windows,
while you have to perform the recursion yourself (if you want it) when using
CWnd::GetWindow.
joe
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
>CWnd * wnd;
>for(wnd = GetWindow(GW_CHILD); wnd != NULL; wnd = wnd->GetWindow(GW_HWNDNEXT))
> {
> TCHAR classname[SOMELIMIT];
> GetClassName(wnd->m_hWnd, classname, SOMELIMIT);
> if(lstrcmpi(classname, _T("STATIC")) != 0)
> continue;
CString s;
wnd->GetWIndowText(s);
if(s.IsEmpty())
continue; // not a label
... assume you have a label
Why I need it: I am putting together a solution that will change the
language of the UI at run time. I iterate thru the labels and buttons and
translate their texts with a small in-memory dictionary. It works well. The
last problem I need to resolve is how to iterate the dialogs. With the modal
ones it is easy, I will translate from the OnInitialilUpdate method. But
there may be some modeless dialogs open when the user is switching the
language and I will need to iterate the dialog. Or maybe it would be simpler
to "register' all dialogs to some collection when opening them and then the
translation routine could iterate the collection.
What might be the most solid and clean way?
Thank You
Vaclav
Note that OnInitialUpdate is a method called for a view or CFormView. For a dialog, modal
or modeless, you would do this in OnInitDialog.
To locate open dialogs, you can iterate over all the windows of the app, looking for
dialogs. Most dialogs have the unique class name #32770, at which point you could iterate
over its children and make the changes. This is true in all cases except where the
programmer has, for some reason, registered his or her own private class. It also doesn't
handle other registered classes that may contain controls.
joe
Joseph M. Newcomer [MVP]
I am having a dilemma where to put the code that iterates and translates the
controls in a CDialog. I should probably create an ancestor of all dialogs
and put it there, but I am not sure if it would work well due to the MFC
architecture.
Vaclav
"Joseph M. Newcomer" <newc...@flounder.com> píse v diskusním príspevku
news:1sdni05nglhhvg2pm...@4ax.com...
The resources exist; but the realization of the resources, e.g., a dialog, do not happen
until the dialog is instantiated. So you could in principle reach into the dialog template
and modify it (again, I've not looked at whether or not this can be done to a running
executable, so it might be a dead end).
Note that you could write a function completely independent of any CWnd class, and simply
call it from OnInitDialog. In addition, you could set a per-process window-creation hook,
e.g., by putting the hook handler in your executable instead of a DLL, intercept the
window creation, and if the window being created is a static label, change it at that
point. This would completely decouple your code from any dependence on modifications to
CFormView or CDialog.
There are commercial products that use BeginUpdateResource to reach into an executable
image and update the resources. I've not seen one in years, but one of our European
distributors is using one. So I know for a non-running .exe, it is doable.
joe