Re: AfxGetAppEx() ?
See below, as Joe says:
On 19 jul, 11:56, Timothy Madden <terminato...@gmail.com> wrote:
Joseph M. Newcomer wrote:
Why do you need the CWinApp? Certainly, not because you need any met=
hods or variables in
it, because that would be incorrect programming style. Nothing outsi=
de the CWinApp[Ex]
needs to know about what is in the CWinApp[Ex].
=
joe
I just want to save some most-recently-used folder name, from a dialog,
to the registry, and I want the GetString() or GetProfileString() method
from CWinApp[Ex]. Would that be ok ?
Of course I could manually use CRegKey class and try to read/write the
data, but I just do not see the danger of
AfxGetApp()->GetProfileString(). I mean I do not use members from /my/
application class (CWinAppEx-derived), only a standard registry-access
function for a framework-provided class, so I should be fine, right ?
******
Sounds like the kind of valid thing to do with the CWinApp object to
me.
Regarding the original question, how to access the CWinAppEx object, I
don't know if there's another way, but you can get it with AfxGetApp
and then cast it to CWinAppEx. Something like this:
CWinApp* app = AfxGetApp();
CWinAppEx* appEx = dynamic_cast<CWinAppEx*>(app);
if(appEx != NULL)
{ // It is actually a CWinAppEx*, so do your stuff here
}
*****
Indeed I would avoid include-ing "CPageBuilderApp.h" if it is by any
means possible. Simply because I imagine a model where CPageBuilderApp.h
might be the one that needs to include my dialog header (and not the
other way around).
I am interested about that design approach that considers the practice
of including as many header files as possible, so I can do whatever I
want anywhere I want, as incorrect design. Can you please provide some
more details and some references ?
*****
Well, I can't provide any references right now, except Joe's essays at
http://www.flounder.com/mvp_tips.htm, but it's how object oriented
design should work. Objects should know nothing about the objects that
surround them but the way to interface with them. This allows for
modularity, reusability and those things.
An example:
Imagine you have a dialog where you want to show, say, the color for
some item.
You have many ways to do it:
- A list of radio buttons with the color you want selected.
- A combobox, with name colors, and the one you want selected
- A list of colors
- A set of edit controls where you write R, G, B values, or H, S, L,
or H, S, V.
- A rectangle painted with the color
- A set of sliders
- ...
There are many ways. So how do you set the color from outside the
dialog? By selecting the correct radio button? By writing in the edit
controls the approppriate numbers? No, you call dlg.SetColor(RGB(r, g,
b)) or something like that, and then you translate it to whatever
controls are to display it. If you ever want to change the way to show
the color selected, you just have to change your dialog, not all the
classes that use it.
And how does the dialog notify its parent that the selected color has
changed?
The "include anything you need" approach would be:
((CMyView*)GetParent())->SetItemColor(newColor);
Quick and easy, but wrong. What if you want to reuse your dialog in
CHisView instead of CMyView? Or if the parent is now a dialog, or a
property page?
The proper way would be to send, or post, a message to the parent:
GetParent()->PostMessage(UWM_ITEMCOLORCHANGED, newColor);
Thus, your dialog can have any parent derived from CWnd. It just has
to implement a handler for UWM_ITEMCOLORCHANGED message.
So, classes should expose an interface, which can be made of messages,
function calls or even public variables, but they should not show
their internal implementation. And they should not try to access other
classes' internal implementation, either.
By the way, it is much easier said than done correctly.
*****
Thank you,
Timothy Madden