Imperator Katarn
2006-01-24, 10:17:35
Hallo,
ich möchte in einem Programm (VC++/MFC) einen Worker-Thread (also kein GUI-Thread) darauf warten lassen, daß ein Dialogfenster geschlossen wird. Gibt es eine Möglichkeit, das elegant zu lösen? Ginge es z.B. mit WaitForSingleObject (aufzurufen im Thread)?
Meine bisherige Idee war, in dem Thread eine Schleife laufen zu lassen, in der fortwährend abgefragt wird, ob die CWnd-Instanz des Dialogfensters noch existiert, und die Schleife zu beenden sobald die Instanz nicht mehr existiert. Allerdings keine sehr schöne Lösung, wie ich finde.
Der Hintergrund ist folgender: ich habe ein Dialogfenster CParentDlg, sowie ein zweites, nicht-modales Dialogfenster CChildDlg, das ein Child von CParentDlg ist. CChildDlg läßt während seiner gesamten Lebensdauer einen Worker-Thread CChildDlg::ThreadDoWork laufen.
Nun soll es möglich sein, durch Klick auf den Exit-Button von CParentDlg die folgende Ereigniskette auszulösen: der Thread CChildDlg::ThreadDoWork wird beendet, dann wird der Dialog CChildDlg geschlossen, und dann CParentDlg geschlossen.
Das Beenden von CChildDlg::ThreadDoWork und das darauffolgende Schließen von CChildDlg habe ich durch einen Cleanup-Thread CChildDlg::ThreadCleanup realisiert, der auf eine Nachricht vom Parent-Dialog hin gestartet wird und dann dem Thread CChildDlg::ThreadDoWork signalisiert, daß der sich beenden soll, darauf wartet (mittels WaitForSingleObject) daß dies geschieht (was länger dauern kann) und anschließend das Schließen des Child-Dialoges auslöst.
Analog wollte ich in CParentDlg einen Thread CParentDlg::ThreadCleanup einbauen, der den Cleanup-Thread von CChildDlg auslöst und dann wartet bis CChildDlg geschlossen wird.
Und genau um diesen Thread CParentDlg::ThreadCleanup geht es in meiner Frage: wie kann ich das elegant realisieren, daß dort auf das Schließen des Child-Dialoges (respektive die Destruktion der CChildDlg-Instanz) gewartet wird?
Hier ein Sourcecode-Beispiel:
class CChildDlg : public CDialog
{
//...
static UINT ThreadDoWork(LPVOID pParam);
static UINT ThreadCleanup(LPVOID pParam);
};
class CParentDlg : public CDialog
{
//...
CChildDlg* m_pChildDlg;
static UINT ThreadCleanup(LPVOID pParam);
};
static UINT CParentDlg::ThreadCleanup(LPVOID pParam)
{
// pParam konvertieren
CParentDlg* pThisDlg = (CParentDlg*) pParam;
// Nachricht an CChild-Instanz senden
pThisDlg->m_pChildDlg->SendMessage(/* bitte beende dich */);
// warten bis Child-Dialog geschlossen ist
// bisherige (unschöne) Lösung:
// alle 50 ms abfragen ob CChildDlg-Instanz noch existiert:
while (pThisDlg->m_pChildDlg)
{
Sleep(50);
}
//...
}
Thx for your help :)
ich möchte in einem Programm (VC++/MFC) einen Worker-Thread (also kein GUI-Thread) darauf warten lassen, daß ein Dialogfenster geschlossen wird. Gibt es eine Möglichkeit, das elegant zu lösen? Ginge es z.B. mit WaitForSingleObject (aufzurufen im Thread)?
Meine bisherige Idee war, in dem Thread eine Schleife laufen zu lassen, in der fortwährend abgefragt wird, ob die CWnd-Instanz des Dialogfensters noch existiert, und die Schleife zu beenden sobald die Instanz nicht mehr existiert. Allerdings keine sehr schöne Lösung, wie ich finde.
Der Hintergrund ist folgender: ich habe ein Dialogfenster CParentDlg, sowie ein zweites, nicht-modales Dialogfenster CChildDlg, das ein Child von CParentDlg ist. CChildDlg läßt während seiner gesamten Lebensdauer einen Worker-Thread CChildDlg::ThreadDoWork laufen.
Nun soll es möglich sein, durch Klick auf den Exit-Button von CParentDlg die folgende Ereigniskette auszulösen: der Thread CChildDlg::ThreadDoWork wird beendet, dann wird der Dialog CChildDlg geschlossen, und dann CParentDlg geschlossen.
Das Beenden von CChildDlg::ThreadDoWork und das darauffolgende Schließen von CChildDlg habe ich durch einen Cleanup-Thread CChildDlg::ThreadCleanup realisiert, der auf eine Nachricht vom Parent-Dialog hin gestartet wird und dann dem Thread CChildDlg::ThreadDoWork signalisiert, daß der sich beenden soll, darauf wartet (mittels WaitForSingleObject) daß dies geschieht (was länger dauern kann) und anschließend das Schließen des Child-Dialoges auslöst.
Analog wollte ich in CParentDlg einen Thread CParentDlg::ThreadCleanup einbauen, der den Cleanup-Thread von CChildDlg auslöst und dann wartet bis CChildDlg geschlossen wird.
Und genau um diesen Thread CParentDlg::ThreadCleanup geht es in meiner Frage: wie kann ich das elegant realisieren, daß dort auf das Schließen des Child-Dialoges (respektive die Destruktion der CChildDlg-Instanz) gewartet wird?
Hier ein Sourcecode-Beispiel:
class CChildDlg : public CDialog
{
//...
static UINT ThreadDoWork(LPVOID pParam);
static UINT ThreadCleanup(LPVOID pParam);
};
class CParentDlg : public CDialog
{
//...
CChildDlg* m_pChildDlg;
static UINT ThreadCleanup(LPVOID pParam);
};
static UINT CParentDlg::ThreadCleanup(LPVOID pParam)
{
// pParam konvertieren
CParentDlg* pThisDlg = (CParentDlg*) pParam;
// Nachricht an CChild-Instanz senden
pThisDlg->m_pChildDlg->SendMessage(/* bitte beende dich */);
// warten bis Child-Dialog geschlossen ist
// bisherige (unschöne) Lösung:
// alle 50 ms abfragen ob CChildDlg-Instanz noch existiert:
while (pThisDlg->m_pChildDlg)
{
Sleep(50);
}
//...
}
Thx for your help :)