Discussion:
Display message on main dialog GUI
(too old to reply)
Me
2011-08-24 15:05:23 UTC
Permalink
I normally display messages in the following way on the main Dialog:
c_Info.SetWindowText("Processing, Please wait..");
How do I display a message on the main Dialog from within another class?
Thanks.
Mikel Luri
2011-08-24 15:33:25 UTC
Permalink
Post by Me
c_Info.SetWindowText("Processing, Please wait..");
How do I display a message on the main Dialog from within another class?
Thanks.
I would keep displaying it the same way and ask the question "how do I
tell the main dialog to display a message from another class?".

And the answer to that could be "by sending a message to it".

I would go for registered windows messages (check
http://www.flounder.com/messages.htm#Registered Window Messages)
Me
2011-08-24 16:01:06 UTC
Permalink
I canr make any sense out of your information.
What do I need to add to my Class to get the main dialog to display the
message?
What do I need to add to the main Dialog to display the message sent by
Class?
Post by Mikel Luri
Post by Me
c_Info.SetWindowText("Processing, Please wait..");
How do I display a message on the main Dialog from within another class?
Thanks.
I would keep displaying it the same way and ask the question "how do I
tell the main dialog to display a message from another class?".
And the answer to that could be "by sending a message to it".
I would go for registered windows messages (check
http://www.flounder.com/messages.htm#Registered Window Messages)
Mikel Luri
2011-08-25 08:28:17 UTC
Permalink
Post by Me
I canr make any sense out of your information.
What do I need to add to my Class to get the main dialog to display the
message?
What do I need to add to the main Dialog to display the message sent by
Class?
Post by Mikel Luri
Post by Me
c_Info.SetWindowText("Processing, Please wait..");
How do I display a message on the main Dialog from within another class?
Thanks.
I would keep displaying it the same way and ask the question "how do I
tell the main dialog to display a message from another class?".
And the answer to that could be "by sending a message to it".
I would go for registered windows messages (check
http://www.flounder.com/messages.htm#Registered Window Messages)
It depends on how you've got it implemented (i.e. what's your Class, how
it relates to the main dialog...), but basically:

- Define the message somewhere, probably in your class' .h file (see
"Defining messages in the link provided in my previous message)

#define UWM_SET_MESSAGE_MSG _T("UWM_COLOR_IT-<your_own_GUID_here>")

- Create the DECLARE_USER_MESSAGE macro and make it visible to your
class and the dialog (I would do a .h file for it and include it both
your class and the dialog, or directly add in stdafx.h)

- Add DECLARE_USER_MESSAGE(UWM_SET_MESSAGE) to your class and dialog's
cpp files.

- Add a handler for the message in the dialog and set the text there
- You need a function with a message handler signature LRESULT
MyHandler (WPARAM, LPARAM). In it, you set the text, passed as a
parameter, to the static control
- Add a message map entry ON_REGISTERED_MESSAGE(UWM_SET_MESSAGE,
MyHandler)

- In your class, when you want your text displayed, send a message to
the dialog. How you do that will depend on how is everything set.
If your class is a child window of the dialog, you would do:
GetParent()->SendMessage(UWM_SET_MESSAGE, 0, yourstring);
Or you could have a CWnd* member in your class, pointing to your dialog,
and you would do:
m_Dialog->SendMessage(UWM_SET_MESSAGE, 0, yourstring);


Not knowing exactly what you are doing, I can't give many details, or
maybe the solution would be different. For example, instead of sending
the string in the message, maybe it would be better to send a message
saying "X has happened" and have the dialog display a message for that
event.

There are many articles with code in Joe's site
(http://www.flounder.com/mvp_tips.htm) and in many of them he uses these
techniques. That's were I learned them
David Wilkinson
2011-08-25 10:33:39 UTC
Permalink
Post by Me
I canr make any sense out of your information.
What do I need to add to my Class to get the main dialog to display the
message?
What do I need to add to the main Dialog to display the message sent by
Class?
If your other class holds a pointer to the main dialog, it can use it to call
any public method of the dialog. So write a public method in your dialog that
displays the message:

void CMyDialog::DisplayMessage(LPCTSTR strMsg)
{
c_Info.SetWindowText(strMsg);
}

Using SendMessage() would enable you to do the same thing using a CWnd pointer
rather than a CMyDialog pointer, thereby reducing the dependency between
CMyDialog and your other class.
--
David Wilkinson
Me
2011-08-25 12:05:57 UTC
Permalink
Post by David Wilkinson
Post by Me
I canr make any sense out of your information.
What do I need to add to my Class to get the main dialog to display the
message?
What do I need to add to the main Dialog to display the message sent by
Class?
If your other class holds a pointer to the main dialog, it can use it to call
any public method of the dialog. So write a public method in your dialog that
void CMyDialog::DisplayMessage(LPCTSTR strMsg)
{
c_Info.SetWindowText(strMsg);
}
Using SendMessage() would enable you to do the same thing using a CWnd pointer
rather than a CMyDialog pointer, thereby reducing the dependency between
CMyDialog and your other class.
How do you add a pointer to the main Dialog?
David Wilkinson
2011-08-26 01:45:35 UTC
Permalink
Post by Me
How do you add a pointer to the main Dialog?
Your real problem is that you are trying to learn MFC without understanding how
object-oriented programming (OOP) works. Having objects hold pointers to other
objects is basic OOP.

If the object of the other class is created after the main dialog, then you
should pass the pointer in the constructor of the other class and store it in a
member variable.

Alternatively, if this is an MFC dialog-based application you can use
AfxGetMainWnd() and cast it. As Goran says, this is not a good OOP design,
because now your class will only work in a dialog-based application using
CMyDialog. But it is probably easiest if you just want to get it working.
--
David Wilkinson
Nobody
2011-08-25 09:54:14 UTC
Permalink
Post by Me
c_Info.SetWindowText("Processing, Please wait..");
How do I display a message on the main Dialog from within another class?
Is that other class in another file? Assuming that you have c_Info declared
like this:

CDialog c_Info;

Then in the other file, you need to add:

extern CDialog c_Info;

Then use "c_Info.SetWindowText" as usual in the other file. On the other
hand, there are drawbacks to this approach like others suggested, see this
article:

http://www.flounder.com/messaging.htm
Me
2011-08-25 11:44:07 UTC
Permalink
Post by Nobody
Post by Me
c_Info.SetWindowText("Processing, Please wait..");
How do I display a message on the main Dialog from within another class?
Is that other class in another file? Assuming that you have c_Info declared
CDialog c_Info;
extern CDialog c_Info;
Then use "c_Info.SetWindowText" as usual in the other file. On the other
hand, there are drawbacks to this approach like others suggested, see this
http://www.flounder.com/messaging.htm
c_Info is a control variable for a CStatic text

My main dialog MyDialog calls the class ReadData.cpp
=========================================================
if (!ReadData.CRead(OpenCFile, 0)){
//error is processed here and returns false with code
}
=========================================================
// it passes a filename and a code which tells what to do

I would like my ReadData class to be able to send status messages to the
screen at c_Info on MyDialog.
Goran
2011-08-25 12:43:12 UTC
Permalink
Post by Me
c_Info.SetWindowText("Processing, Please wait..");
How do I display a message on the main Dialog from within another class?
Thanks.
c_Info is a child window (e.g. CStatic) of your main dialog, right?

If so, AfxGetMainWnd() should return a pointer to your main dialog.
Presuming your main dialog class is called CMainDialog,

static_cast<CMainDialog&>(*AfxGetMainWnd()).c_Info.SetWindowText (...)
should do it for you.

But! But... Design-wise, the above is crap design. And sending windows
message is equally bad (IMHO). Your "another class" needs a way to
pass some status to another part of the code. So give it a way to do
it. Try this:

class IStatusDisplay
{
public:
virtual void SetStatusText(const CString& text) = 0;
};

class CYourClass
{
public:
CYourClass(IStatusDisplay& status) : m_status(status) {}
IStatusDisplay& m_status;
void Work()
{
m_status.SetStatusText("Processing, blahblah");
DoOtherWork();
}
};

class CMainDialog : public CDialog, IStatusDisplay
{
...
virtual void SetStatusText(const CString& text)
{
c_Info.SetWindowText(text);
}
};

void Work(CMainDialog& dlg)
{
CYourClass worker(dlg);
worker.Work();
}

The above gives you a good degree of separation (dialog knows not of
CYourClass and vice-versa), while keeping code +/- simple and type
safe (forget type safety with message-based solutions). It is a simple
application of a design principle called "interface segregation
principle" (http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod).

Goran.

P.S. You almost certainly need background processing. I don't know
whether you do have it, but if you do, note that accessing CWnd-
derived objects from thread they weren't created in, leads to
trouble. If you think you can do it, you were just lucky so far.
Loading...