Como enviar uma cadeia via PostMessage?
-
19-09-2019 - |
Pergunta
Dentro do meu aplicativo, eu quero enviar uma mensagem para um diálogo a partir de um segmento diferente. Eu quero passar um std :: exceção derivada de referência de classe para o diálogo.
Algo parecido com isto:
try {
//do stuff
}
catch (MyException& the_exception) {
PostMessage(MyhWnd, CWM_SOME_ERROR, 0, 0); //send the_exception or the_exception.error_string() here
}
Eu quero receber a mensagem na minha caixa de diálogo e mostrar o erro que está em the_exception.error_string()
LPARAM CMyDlg::SomeError(WPARAM, LPARAM)
{
show_error( ?????
return 0;
}
passando o std::string the_exception.error_string()
usando PostMessage também seria ok, eu acho.
Solução
Você não pode passar o endereço da string em PostMessage, a string é provavelmente de segmento local na pilha. Até o momento os outros picaretas fio-lo, ele poderia ter sido destruído.
Em vez disso, você deve criar uma nova string ou exceção objeto via new e passar o endereço para o outro thread (através do parâmetro WPARAM ou LPARAM em PostMessage.) O outro segmento, em seguida, possui o objeto e é responsável por destruí-lo.
Aqui está um código de exemplo que mostra como isso poderia ser feito:
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;
}
Outras dicas
Enquanto você está dentro de um processo de simplesmente passando a * ponteiro nulo e alguns cuidados na vida útil do objeto são suficientes.
Se é SendMessage você pode passá-lo em LPARAM como um elenco void *, eo cliente uncast-lo de volta para o seu tipo de cadeia. Porque SendMessage é síncrona , você está seguro:
Se a janela especificada foi criado por o segmento de chamada, a janela procedimento é chamado imediatamente como um sub-rotina. Se a janela especificada foi criado por um segmento diferente, o sistema muda para esse segmento e chama a janela apropriada procedimento. Mensagens enviadas entre tópicos somente quando o são processados receber a mensagem thread executa código de recuperação. O fio de envio é bloqueada até que o segmento de recepção processa a mensagem
Se você quiser usar PostMessage, então você vai ter que fazer uma mão explícita fora porque a chamada é assíncrona: fazer uma cópia da string na pilha e chamando o PostMessage de ter passado a responsabilidade de exclusão para o calee ( de diálogo).
Se você sair do processo (MyhWnd pertence a um processo diferente), então, é uma história totalmente diferente e você tem que organizar a sua mensagem em algo parecido com um átomo global.
Enquanto você sabe que a sua janela (ou instância de CMyDlg
) ainda estará por aí depois de postar a mensagem que você poderia simplesmente armazenar a string de erro em uma variável de membro e ler a partir deste no seu manipulador de mensagem.