Как отправить строку через PostMessage?

внутри моего приложения я хочу отправить сообщение в диалог из другого потока. Я хочу передать ссылку на производный класс std::exception в диалоговое окно.

что-то вроде этого:

try {
       //do stuff
}
catch (MyException& the_exception) {
    PostMessage(MyhWnd, CWM_SOME_ERROR, 0, 0); //send the_exception or the_exception.error_string() here
}

Я хочу получить сообщение в моем диалоговом окне и показать ошибку, которая находится в the_exception.error_string()

LPARAM CMyDlg::SomeError(WPARAM, LPARAM)
{
    show_error( ?????
    return 0;
}

мимо std::string the_exception.error_string() использование PostMessage также будет в порядке, я думаю.

3 ответов


вы не можете передать адрес строки в PostMessage, так как строка, вероятно, является потоковой локальной в стеке. К тому времени, когда другая нить поднимет его, он мог быть уничтожен.

вместо этого вы должны создать новую строку или объект исключения через new и передать его адрес другому потоку (через параметр Wparam или LPARAM в PostMessage.) Другой поток затем владеет объектом и отвечает за его уничтожение.

вот пример кода, который показывает, как это можно сделать:

try
{
    //do stuff
}
catch (MyException& the_exception)
{
    PostMessage(MyhWnd, CWM_SOME_ERROR, 0, new string(the_exception.error_string));
}


LPARAM CMyDlg::SomeError(WPARAM, LPARAM lParam)
{
    // Put in shared_ptr so it is automatically destroyed.
    shared_ptr<string> msg = reinterpret_cast<string*>(lParam);

    // Do stuff with message

    return 0;
}

пока вы находитесь в процессе, просто передавая указатель void* и некоторую заботу о времени жизни объекта достаточно.

If is SendMessage вы можете передать его в LPARAM как Void * cast, и клиент открепит его обратно к вашему строковому типу. Потому что SendMessage синхронно вы:

Если заданное окно было создано вызывающий поток, окно процедура вызывается немедленно как подпрограмма. Если указанное окно был создан другим потоком, система переключается на этот поток и вызывает соответствующее окно процедура. Сообщения, отправленные между потоки обрабатываются только тогда, когда получив сообщение потоке код поиска. Поток отправки заблокировано до получения потока обрабатывает сообщение

Если вы хотите использовать PostMessage, вам придется сделать явную передачу, потому что вызов асинхронен: сделайте копию строки в куче и вызов PostMessage вы передали ответственность за удаление в calee (диалоговое окно).

Если вы выходите из процесса (MyhWnd принадлежит другому процессу), то это совершенно другая история, и вам придется маршалировать свое сообщение в нечто вроде глобального атома.


пока вы знаете, что ваше окно (или экземпляр CMyDlg) по-прежнему будет вокруг после публикации сообщения Вы можете просто сохранить строку ошибки в переменной-члене и прочитать из этого в обработчике сообщений.