2013-07-22 3 views
1

У меня есть приложение, настроенное с рабочим потоком, и я использую PostMessage() с настраиваемым сообщением WM_THREAD_FINISHED, чтобы сообщить основному потоку, что он завершил выполнение. Я обрабатываю настраиваемое сообщение в методе OnThreadFinish(). Похоже, этот метод называется запуском приложения, что вызывает у меня проблемы. Я получаю сбой, который, по моему мнению, обусловлен отсутствием данных в a, b, or c. Есть ли причина, по которой сообщение должно быть вызвано при инициализации приложения?Почему мое пользовательское сообщение отправляется при запуске приложения?

#define WM_THREAD_HAS_FINISHED WM_USER +0 

struct DataItem { 
    int a; 
    int b; 
    double c; 
}; 

.... 
BEGIN_MESSAGE_MAP(CProject1Dlg, CDialogEx) 
    .... 
    .... 
    ON_MESSAGE(WM_THREAD_HAS_FINISHED, &CProject1Dlg::OnThreadFinish) 
END_MESSAGE_MAP() 
.... 

UINT WorkThread(LPVOID pParam) { 

    // Do stuff 

    DataItem* m_CurrentData; 
    m_CurrentData->a = a; 
    m_CurrentData->b = b; 
    m_CurrentData->c = c; 

    // End thread, notify main thread of completion 
    PostMessage(hwnd, WM_THREAD_HAS_FINISHED, (WPARAM) m_CurrentData, 0); 
    AfxEndThread(0); 

    return 0; 
    } 



LRESULT CProject1Dlg::OnThreadFinish(WPARAM wParam, LPARAM lParam) { 

    // Retrieve data from thread 
    std::auto_ptr<DataItem> currentData(reinterpret_cast<DataItem*>(wParam)); 

    int a = currentData.a; 
    int b = currentData.b; 
    double c = currentData.c; 

    // Do stuff 

    return 0; 
    } 

ответ

4

Вы должны использовать:

#define WM_THREAD_HAS_FINISHED (WM_APP+0) 

WM_USER+X является диапазон зарезервирован для конкретного класса окна, а не приложения. Таким образом, вы можете определить этот диапазон только в том случае, если вы создаете новый класс Window

Кажется, что вы используете Dialog, который является стандартным, хотя и недокументированным, классом окон. Таким образом, ваше конкретное сообщение сталкивается с этим, скопированным из winuser.h:

#define DM_GETDEFID (WM_USER+0) 

И как вы можете легко проверить, это сообщение посылается много.

В любом случае, если вы хотите играть на безопасной стороне, вы также можете использовать RegisterWindowMessage().

+1

Хороший ответ. Дополнительное объяснение: http://blogs.msdn.com/b/oldnewthing/archive/2012/10/24/10362204.aspx –

+0

Спасибо за ваш четкий ответ! –

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