Как отправить строку через 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 также будет в порядке, я думаю.

Ответы

Ответ 1

Вы не можете передать адрес строки в 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;
}

Ответ 2

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

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

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

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

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

Ответ 3

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