Как отправить строку через PostMessage? - PullRequest
16 голосов
/ 25 августа 2009

Внутри моего приложения я хочу отправить сообщение в диалог из другого потока. Я хочу передать в диалог ссылку на производный класс 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 ]

13 голосов
/ 25 августа 2009

Вы не можете передать адрес строки в 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;
}
1 голос
/ 25 августа 2009

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

Если это SendMessage, вы можете передать его в LPARAM как приведение к пустому типу *, и клиент вернет его обратно в ваш строковый тип. Поскольку SendMessage синхронный , вы в безопасности:

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

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

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

0 голосов
/ 25 августа 2009

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

...