2016-04-04 3 views
0

Использование Visual Studio 2015 (Community Edition) & Проект MFC C++. У меня есть рабочий поток , где я хочу использовать функцию PostMessage() для отправки данных из этого потока в основной поток пользовательского интерфейса (где находится мой CDialog) еще в том же классе, что я хочу получить это сообщение.mfc C++ отправить пользовательское сообщение пользователя с postmessage из рабочего потока в основной поток ui

В файле MyComm.h я следующее:

#define WM_USERRESPONSE WM_APP + 2000 

class MyComm: public CDialog 
{ 
    ... 
    CWnd* m_pParent; 
    static BOOL m_bThreadKill; 
    static CWinThread* pThread; 
    static CEvent* pEvent; 
    static CEvent m_ThreadKillEvent; 
    ... 
    static UINT MyThreadProc(LPVOID pParam); 
    ... 
    afx_msg LRESULT OnResponse(WPARAM wParam, LPARAM lParam); 
    ... 
}; 

В моем файле MyComm.cpp я следующее:

MyComm::MyComm(CWnd* pParent /*=NULL*/) 
    : CDialog(IDD_PPAGE_COMMAND, pParent) 
{ 
    m_pParent = pParent; 

    pEvent = new CEvent(FALSE, FALSE); 

    if ((pThread = AfxBeginThread(MyThreadProc, this)) == NULL) 
    AfxMessageBox("Could not Create Read Thread!"); 

    pThread->m_bAutoDelete = FALSE; 
    m_ThreadKillEvent.ResetEvent(); 
    m_ReadThreadDead.ResetEvent(); 
    running = 1; 
} 

UINT MyComm::MyThreadProc(LPVOID pParam) 
{ 
    MyComm *pMyHndl = ((MyComm*)pParam); 
    string s = "I would like this string posted"; 
    BOOL b = false; 

    b = ::PostMessage(pMyHndl->GetSafeHwnd(), WM_USBRDRESPONSE, 0, 
     (LPARAM)&s); 
} 

BEGIN_MESSAGE_MAP(MyComm, CDialog) 
    ON_MESSAGE(WM_USERRESPONSE, &MyComm::OnResponse) 
END_MESSAGE_MAP() 

afx_msg LRESULT MyComm::OnResponse(WPARAM wParam, LPARAM lParam) 
{ 
    MyStruct* p = (MyStruct*)lParam; 
    ... 
} 

Примечание I сокращенная часть этого, чтобы остаться по теме.

В отладке этого (есть гораздо больше кода, чем это), я проверяю, что поток запускается, я выполняю функцию PostMessage(), которая возвращает true. Я никогда не получаю функцию OnResponse(), которая предназначена для получателя. Я не уверен почему .. (??) ..

Некоторые мысли. Это правда, что класс MyComm находится в том же классе, но не является диалоговой нитью, но порождается им и происходит из CDialog. Возможно, этого недостаточно ? Я признаю, что я до сих пор несколько новичок в потоках через MFC парадигму программирования. Любая помощь приветствуется.

Maddog

+0

Не вызывает ли проблема с доставкой, сохранится ли строка, когда сообщение будет доставлено? Не будет ли RAII'd удален, когда MyThreadProc() вернется? –

+0

Извините, в реальном коде нить никогда не возвращается (например, (1) ...) или до тех пор, пока не будет убита. –

+0

В моем случае эта строка является буфером, созданным при создании нити. –

ответ

0
  • Переменная string s не будет существовать после того, как нить заканчивается. Функция потока, которую вы показали, слишком мала и скоро выйдет.
  • В идеале вы должны начать новую тему с OnInitDialog не в конструкторе. Цикл сообщений не создается в конструкторе, а в то время как в OnInitDialog.
  • Проверьте правильность кода сообщения. Ваш код имеет: WM_USBRDRESPONSE и WM_USBRDRESPONSE
+0

Как я уже говорил, нить в моем коде никогда не заканчивается до тех пор, пока не будет убита. Я обнаружил, что SendMessage() также не получает. Во-вторых, мне нужно дождаться сообщения, прежде чем продолжить. Что-то, что я обнаружил в другом вопросе здесь [ссылка] (http://stackoverflow.com/questions/18271229/mfc-send-message-to-main-thread-rather-than-a-window) рекомендует, чтобы мой PostMessage() отправьте его в окно. Мой текущий класс здесь без окон, кроме того, что он порожден в классе диалога. –

+0

Итак, это объясняет, почему класс MyComm не выполняет метод OnInitDialog(). Поэтому мне может понадобиться создать скрытое окно здесь. Извиняется за сам сигнал. В моем коде сообщение WM_USBRDRESPONSE. Я переименовал его здесь WM_RESPONSE только для упрощения. Я не хотел вводить весь код здесь, потому что он имеет более 100 страниц, и есть вопросы, связанные с интеллектуальной собственностью. –

+0

Как отображается диалог? DoModal, ShowWindow? – Ajay

0

Сегодня я нашел ответ на эту проблему.

Это потому, что класс, в котором запущен поток, не является классом, привязанным к окну , но порождается одним с окном. Так что тонкий нюанс на pMyHndl необходим. Если в POSTMESSAGE() я вместо этого использую pMyHndl->m_pParent вместо m_pParent указывает на класс родителя (один с окном). Этот код получил сообщение, что код для получения сообщения был перемещен. Спасибо всем за помощь.

maddog

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