0
votes

I want to have a message handler in MFC which accepts whatever parameters I define in the message-map.

For example,

static UINT UWM_STATUS_MSG = RegisterWindowMessage("Status message");
static UINT UWM_GOT_RESULT= RegisterWindowMessage("Result has been obtained");

//{{AFX_MSG(MyClass)
    afx_msg void OnCustomStringMessage(LPCTSTR);
    afx_msg void OnStatusMessage();
//}}AFX_MSG


BEGIN_MESSAGE_MAP(MyClass, CDialog)
    //{{AFX_MSG_MAP(MyClass)
        ON_REGISTERED_MESSAGE(UWM_STATUS_MSG, OnStatusMessage)
        ON_REGISTERED_MESSAGE(UWM_GOT_RESULT, OnCustomStringMessage)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void MyClass::OnCustomStringMessage(LPCTSTR result)
{
    m_result.SetWindowText(result);
}

void MyClass::OnStatusMessage()
{
    // Do something
}

DWORD WINAPI MyClass::thread(LPVOID lParam)
{
    char result[256] = { 0 };
    SendMessage(UWM_STATUS_MSG);

    // Do some stuff and store the result

    PostMessage(UWM_GOT_RESULT, result);
}

Is such a thing possible?

3

3 Answers

1
votes

The signature of member functions that are invoked via ON_MESSAGE or ON_REGISTERED_MESSAGE must be:

afx_msg LRESULT OnMyFunction(WPARAM p1, LPARAM p2);

You have to deal with that using cast operators.

Therefore you should write this:

...
afx_msg LRESULT OnCustomStringMessage(WPARAM p1, LPARAM p2);
...

LRESULT MyClass::OnCustomStringMessage(WPARAM p1, LPARAM p2)
{
  LPCTSTR result = (LPCTSTR)p1 ;
   m_result.SetWindowText(result);
}

DWORD WINAPI MyClass::thread(LPVOID lParam)
{
    static char result[256] = { 0 };   // we need a static here
                                       // (see explanations from previous answers)
    SendMessage(UWM_STATUS_MSG);

    // Do some stuff and store the result

    PostMessage(UWM_GOT_RESULT, (WPARAM)result);
}

If MyClass::thread is meant to be invoked from several different threads you need to deal with the result array in a more compilcated manner that just declaring it static, for example allocating the array in MyClass::thread ands deleting it in OnCustomStringMessage as suggested by user2173190's answer.

0
votes

Try using WM_USER messages as your custom message and handle it in OnMessage method by overriding it. To know about WM_USER messages refer here

0
votes

If you send a message in the range below WM_USER to the asynchronous message functions (PostMessage, SendNotifyMessage, and SendMessageCallback), its message parameters cannot include pointers. Otherwise, the operation will fail. The functions will return before the receiving thread has had a chance to process the message and the sender will free the memory before it is used.

PostMessageā€˜s message parameters can include pointers You can include pointers as parameters. Cast them as an integer and do not dispose or free them on the thread or function that fires the PostMessage, but dispose or free them on the receiving thread or function. Just make sure that when using a pointer, that you only use one pointer type for one message, don't mix pointer to different objects with the same message.

http://msdn.microsoft.com/zh-cn/library/windows/desktop/ms644944(v=vs.85).aspx