Вопрос

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

Это было полезно?

Решение

Вы не можете передать адрес строки в 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* и позаботиться о времени жизни объекта.

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top