Question

Dans mon application, je veux envoyer un message à une boîte de dialogue à partir d'un autre thread. Je veux passer un std :: exception référence de classe dérivée de la boîte de dialogue.

Quelque chose comme ceci:

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

Je souhaite recevoir le message dans ma boîte de dialogue et montrer l'erreur qui est dans the_exception.error_string()

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

passer le std::string the_exception.error_string() en utilisant PostMessage serait également ok, je suppose.

Était-ce utile?

La solution

Vous ne pouvez pas passer l'adresse de la chaîne dans PostMessage, puisque la chaîne est probablement thread local sur la pile. Au moment où l'autre fil, il ramasse, il aurait pu être détruit.

Au lieu de cela, vous devez créer une nouvelle chaîne ou objet exception par nouvelle et passer son adresse à l'autre fil (via le paramètre WPARAM ou lParam dans PostMessage.) L'autre thread possède alors l'objet et est responsable de la détruire.

Voici quelques exemples de code qui montre comment cela pourrait se faire:

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;
}

Autres conseils

Tant que vous êtes dans un processus tout simplement passer un pointeur vide * et des soins à vie d'objets suffisent.

Si est SendMessage vous pouvez passer dans lParam comme un vide * cast, et le client uncast revenir à votre type de chaîne. Parce que SendMessage est synchrone , vous êtes en sécurité:

  

Si la fenêtre spécifiée a été créé par   le thread appelant, la fenêtre   la procédure est appelée immédiatement comme   sous-programme. Si la fenêtre spécifiée   a été créé par un autre thread, la   Commutateurs à ce fil et   appelle la fenêtre appropriée   procédure. Les messages envoyés entre   fils sont traités uniquement lorsque le   fil de réception exécute un message   récupération de code. Le fil d'envoi est   bloqué jusqu'à ce que le fil de réception   traite le message

Si vous voulez utiliser PostMessage alors vous devrez faire une large part explicite parce que l'appel est asynchrone: faire une copie de la chaîne sur le tas et en appelant le PostMessage que vous avez passé la responsabilité à la suppression Calee ( la boîte de dialogue).

Si vous sortez du processus (MyhWnd appartient à un processus différent) est alors une toute autre histoire et vous devrez rassembler votre message dans quelque chose comme un atome global.

Tant que vous savez que votre fenêtre (ou instance de CMyDlg) seront encore là après avoir affiché le message que vous pouvez simplement stocker la chaîne d'erreur dans une variable membre et lire dans votre gestionnaire de messages.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top