2013-03-25 2 views
0

Я хочу иметь обработчик сообщений в MFC, который принимает любые параметры, которые я определяю на карте сообщений.mfc - sendmessage/postmessage с настраиваемыми параметрами

Например,

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); 
} 

ли такое возможно?

ответ

1

Подпись функций-членов, которые вызываются с помощью ON_MESSAGE или ON_REGISTERED_MESSAGE должны быть:

afx_msg LRESULT OnMyFunction (WPARAM р1, р2 LPARAM);

Вы должны иметь дело с этим с помощью операторов литья.

Поэтому вы должны написать следующее:

... 
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); 
} 

Если MyClass :: нить предназначена для вызова из нескольких потоков, вам придется иметь дело с результатом массивом в более compilcated образом, просто объявляя его static, например, выделяя массив в MyClass :: thread и удаляя его в OnCustomStringMessage, как это было предложено в ответе user2173190.

+0

Итак, нет способа обойти переменные 'WPARAM' и' LPARAM' в качестве аргументов? Я просто подумал, что все эти кастинги и дополнительные переменные будут лишними. Мне было интересно, есть ли другой метод обработки сообщений, который больше подходит для моей задачи. Отсюда вопрос. Спасибо за ваш ответ, хотя! –

+0

Кроме того, о 'result', да. Но это была лишь небольшая демонстрация того, что я хотел. Я буду заботиться обо всем этом. Спасибо :) –

+0

Нет, вы не можете передавать параметры других типов таким функциям-членам. Если вы беспокоитесь о дополнительных переменных, вы также можете написать «m_result.SetWindowText ((LPCTSTR) p1)». –

0

Попробуйте использовать сообщения WM_USER как свое собственное сообщение и обработайте его в методе OnMessage, переопределив его. Узнать о сообщениях WM_USER см. here

+0

ON_MESSAGE будет иметь такую ​​же проблему. Он ожидает, что обработчик сообщения примет аргументы типа WPARAM и 'LPARAM'. –

0

Если вы отправляете сообщение в диапазоне ниже WM_USER на функции асинхронного сообщения (PostMessage, SendNotifyMessage и SendMessageCallback), его параметры сообщения не могут содержать указатели. В противном случае операция завершится с ошибкой. Функции возвратятся до того, как получающий поток сможет обработать сообщение, и отправитель освободит память до ее использования.

Параметры сообщения PostMessage могут включать указатели Вы можете включить указатели в качестве параметров. Передайте их как целое число и не размещайте и не освобождайте их в потоке или функции, которая запускает PostMessage, а удаляет или освобождает их от принимающего потока или функции. Просто убедитесь, что при использовании указателя вы используете только один тип указателя для одного сообщения, не смешивайте указатель с разными объектами с тем же сообщением.

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

+0

Я могу передать указатели, правильно. Но что, если я хочу передать объекты или вообще ничего? Это невозможно. –

Смежные вопросы