Dialog beenden
-
Guten Abend!
Gut zu wissen -> m_pMainDlg!
Vielleicht habe ich mich etwas blöd ausgedrückt, also diese Dialoge stecken in einer DLL und ich möchte sie momentan in einem MDI anzeigen. Da der Nutzen dieser Dialoge aber auch für andere Anwendungen interessant sein könnte möchte ich die Dialoge in einer DLL bereit stellen.
Wichtig ist jedoch dass ich auch eine Funktion hab die mir die Fenster auch wieder schließt, falls der Benutzer das nicht tut aber die Hauptanwendung beendet.
Die Dialoge werden mit der genannten ShowGui()-Funktion angezeigt. Ich möchte den Dialog nur irgendwie schließen. DestroyWindow() wird in OnCancel vorgenommmen und delete in OnPosNcDestroy(). Aber egal wie ich es anstelle stürzt mein Proggie immer ab wenn ich versuche den Dialog zu schließen.
Ich hab auch schon versucht eine WM_DESTROY Message an das Fenster zu schicken, aber immer das Gleiche
.Hilfe Hilfe

Schönes WE!
-
Hi!
Hat niemand einen Tipp für mich?
CChris :xmas1:
-
Was ist das für eine DLL? Standard, extension DLL?
Warm eine DLL?
Was ist das für eine EXE?
Soll die DLL eigenstöändig laufen oder läuft dieimmer im Paket und der gleichen Version wie die EXE?Rufst Du auch DestroyWindow aus der DLL heraus aus?
Was sagt der Stack Trace wenn es kracht?
-
Hallo,
Was ist das für eine DLL? Standard, extension DLL?
Eine reguläre MFC-DLL
Warm eine DLL?
Weil es später einmal ein Teil einer großen Anwendung werden soll
Was ist das für eine EXE?
Momentan eine Mfc-Dialogbasierende Anwendung -> später aber eine beliebige exe (mit graphischer oberfläche)
Ich habe das Problem gelöst, ich habe AFX_MANAGE_STATE(AfxGetStaticModuleState()); in der Close-Methode vergessen.
Aber jetzt kracht es immer noch wenn ich die ESC-Taste im Dialog drücke. Wenn ich die Anwendung normal schließe klappt alles einwandfrei... was passiert denn wenn ich die Esc-Taste in meinem Dialog drücke??
Danke
CChris :xmas2:
-
Bei einem nicht modalen Dialog gar nichts!
-
Also ich hatte mir ja nen Nicht-Modalen Dialog immmer so vorgestellt wie ein normales Fenster, außer dass da halt eine erweiterte Fensterprozedur implementiert ist, die Kinderfenster verwaltet. Warum sollte man den nicht wie ein ganz normales Fenster auch zumachen können? Oo
-
Bei einem nicht modalen Dialog gar nichts!
... so hab ich mir das auch vorgestellt, aber leider reagiert meine Anwendung trozdem auf die ESC-Taste.
Darum wollte ich ja wissen, was im CDialog passiert wenn man auf die ESC-Taste drückt, also was alles aufgerufen wird.
Also ich hatte mir ja nen Nicht-Modalen Dialog immmer so vorgestellt wie ein normales Fenster, außer dass da halt eine erweiterte Fensterprozedur implementiert ist, die Kinderfenster verwaltet. Warum sollte man den nicht wie ein ganz normales Fenster auch zumachen können? Oo
Sorry, aber ich versteh nicht ganz wie du das meinst

Danke
-
Also für mich sieht das gerade echt so aus, als hättest du irgendein anderes Problem, doktorst da jetzt irgendwie rum und traust dich nicht, mal zu schauen was der Debugger so sagt.
-
Hallo,
witzig... wieso soll ich mich nicht trauen zu schuaen was der debugger sagt
?Der Debugger hängt sich an folgender Stelle auf und durch die Methoden hindurch zu debuggen is nicht, weil ich irgendwann die Meldung bekomme dass der Quellcode nicht verfügbar ist:
void CWnd::AssertValid() const
{
...
ASSERT(::IsWindow(m_hWnd));
...
}Deshalb habe ich auch nicht die möglichkeit zu schauen welche Methoden aufgerufen werden wenn ich ESC-Taste drücke.
Ich verwende IsDialog-Message um Definierte Taste wie z. B. ESC, Pfeil-Tasten oder Tab an mein Dialog weiter zuleiten.
Viele Grüße!
-
Also ist das Problem, dass das Fenster-Handle Win32 gegenüber irgendwie schon freigegeben wurde, ohne dass das CWnd-Objekt (Also dein CDialog) was davon mitbekommen hat. Ist eventuell das Parent-Fenster von dem Dialog schon kaputtgemacht worden, bevor das CDialog-Objekt gelöscht wird?
Ich würd das ja hier mal durch den Debugger schicken, aber du brennst bestimmt nicht so darauf, deinen Code herzugeben

-
Und was sagt der Callstack? Wer will in diesem Moment auf das Fensterzugreifen?
-
Halli Hallo,
Denn Callstack kann man sich im Normalfall mit dem CallBrowser anzeigen lassen?
Weil der zeigt mir nämlich garnichts an.Ich vermute, dass der Programmteil irgendwie nicht von meiner Anwendung aus aufgerufen wird weil im Callbrowser nichts drin steht.
Und zwar vermute ich dass, weil ich eine eigene Hook erzeugt habe die mir die Nachrichten abfängt und IsDialogMessage() aufruft damit die Pfeil-Tasten usw. Funktionieren. Darum reagiert meine Anwendung jetzt auch auf die Esc-Taste.
(Die Funktion habe ich nicht selber geschrieben, sondern von einem Bekannten bekommen)
LRESULT FAR PASCAL GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { LPMSG lpMsg = (LPMSG) lParam; AFX_MANAGE_STATE(AfxGetStaticModuleState()); if( (nCode >= 0 && PM_REMOVE == wParam) && (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) && (IsDialogMessage(hWnd, lpMsg) || IsDialogMessage(hWndExpertMode, lpMsg)) ) { lpMsg->message = WM_NULL; lpMsg->lParam = 0; lpMsg->wParam = 0; } return CallNextHookEx(hHook, nCode, wParam, lParam); }Auf jeden Fall ist das sehr komisch weil das normale Beenden meiner Anwendung macht überhaupt keine Probleme, nur eben wenn ich die ESC-Taste drücke

Danke!
CChris :xmas1:
-
Hat denn der MFC-App-MessageLoop nicht automatisch ein IsDialogMessage eingebaut? Kenne den Code dafür gerade nicht.
-
Hi,
im Normalfall schon, aber wenn man einen nicht modalen Dialog in einer DLL definiert, dann nicht.
CChriss :xmas2:
-
Guten Morgen,
jetzt hab ich doch schon so viel geschrieben, dass irgendjemand eine Antwort haben muss :D.
Ich komm einfach nicht weiter. Ich habe an dieser Stelle auch überhaupt keinen Anhaltspunkt woran der Fehler liegen könnte oder wonach ich suchen sollte.
Folgendes habe ich probiert, funktioniert auch nicht, weil ich nicht einmal in die PreTranslateMessage rein komme.
BOOL CMainDlg::PreTranslateMessage(MSG* pMsg) { if (pMsg->wParam == VK_ESCAPE) return 1; return CDialog::PreTranslateMessage(pMsg); }Jetzt kann ich mir nur noch vorstellen dass das Problem an meiner Message-Hook (siehe vorheriger Beitrag) liegt.
Ich Prüfe die IsDialogMessage dort für zwei Dialoge (hab ich auch schon aus dem code herausgenommen und ich bekomme immer noch den fehler).
Die hWnd's die ich für die IsDialogMessage verwende definiere ich mir wie folgt:
Im Main-Dlg:
BOOL CMainDlg::OnInitDialog() { CDialog::OnInitDialog(); hWnd = m_hWnd; hHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, NULL, GetCurrentThreadId()); return TRUE; } BOOL ShowExpertMode() { ... m_pExpertMode->Create(); hWndExpertMode = m_pExpertMode->m_hWnd; m_pExpertMode->ShowWindow(SW_SHOW); }Bin um jede Hilfe dankbar, weil ich wirklich nicht weiss wie ich das Problem lösen soll.
Danke!
CChris
-
Dann Debugge bitte, sende mehr Code, Sag uns genauer was auf dem Stack bei einem Crash zu seen ist.
Wie soll man Dir sonst helfen?EDIT:
http://blog.m-ri.de/index.php/2008/07/04/mfc-fenster-in-anderen-applikationen-verwenden/
-
Hallo,
ich würde ja debuggen oder schauen was auf dem Stack steht, aber es wird mir ja nichts angezeigt.
Ich habe das Problem inzwischen zwar immer noch nicht gelöst, aber es zumindest unterbunden indem ich folgendes in meine GetMsgProc eingebaut habe:
if( (nCode >= 0 && PM_REMOVE == wParam) &&
(lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) &&
(lpMsg->wParam!= VK_ESCAPE) &&
(IsDialogMessage(hWnd, lpMsg) || IsDialogMessage(hWndExpertMode, lpMsg))
)Aber unterbinden ist nicht die beste Lösung und darum fasse ich, das was ich mache nocheinmal kurz zusammen. Evtl. mache ich ja schon einen grundlegenden Fehler, denn ich habe sowie so noch ein kleines Auffassungsproblem was meine DLL betrifft:
Wenn ich ein nicht modales Fenster als Hauptdialog in einer DLL verwende, muss ich dann einen eigenen Prozess/Thread starten?
Wenn ja, macht dass die Hauptklasse meiner DLL automatisch wenn diese ist von CWinApp abgeleitet ist?Es folgt das Grundgerüst meiner DLL, ich habe das wichtigste zusammengefasst da ich keine debugging infos habe.
Hautpklasse
class CModelessDlgApp : public CWinApp { public: CMainDlg* m_pMainDlg; public: CModelessDlgApp(); virtual BOOL InitInstance(); void ShowGui(); void CleanUp(); DECLARE_MESSAGE_MAP() }; //Dialog anzeigen void CModelessDlgApp::ShowGui() { if(NULL == m_pMainDlg) { m_pMainDlg = new CMainDlg(); m_pMainWnd = m_pMainDlg; m_pMainDlg->Create(CMainDlg::IDD, NULL); m_pMainDlg->ShowWindow(SW_SHOW); } else m_pMainDlg->SetActiveWindow(); } //Dialog schließen void CModelessDlgApp::CleanUp() { if(NULL != m_pMainDlg) { m_pMainDlg->DestroyWindow(); m_pMainDlg = NULL; } }Globaler Teil der DLL
CModelessDlgApp theApp; __declspec(dllexport) void ShowGui(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); theApp.ShowGui(); } __declspec(dllexport) void ::CleanUp(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); theApp.CleanUp(); }Dialog-Klasse
//Message-Hook LRESULT FAR PASCAL GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) { LPMSG lpMsg = (LPMSG) lParam; AFX_MANAGE_STATE(AfxGetStaticModuleState()); if( (nCode >= 0 && PM_REMOVE == wParam) && (lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST) && (lpMsg->wParam!= VK_ESCAPE) && (IsDialogMessage(hWnd, lpMsg) || IsDialogMessage(hWndExpertMode, lpMsg)) ) { lpMsg->message = WM_NULL; lpMsg->lParam = 0; lpMsg->wParam = 0; } return CallNextHookEx(hHook, nCode, wParam, lParam); } //Message-Hook starten in OnInitDialog BOOL CMainDlg::OnInitDialog() { CDialog::OnInitDialog(); hWnd = m_hWnd; hHook = ::SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, NULL, GetCurrentThreadId()); return TRUE; } //Message-Hook beenden void CMainDlg::OnDestroy() { UnhookWindowsHookEx(hHook); CDialog::OnDestroy(); } //Dialog zerstören void CMainDlg::OnCancel() { DestroyWindow(); } //Speicherplatz freigeben void CMainDlg::PostNcDestroy() { CDialog::PostNcDestroy(); delete this; }So das war jetzt viel zu lesen, aber vllt. kann mir jemand weiter helfen oder ein paar hilfreiche tipps geben.
Zu diesem Thema findet man auch nicht allzuviel hilfreiches im Internet.
Viele Grüße!
CChris :xmas1:
-
Jetzt hab ich alles so schön zusammengefasst, ist das jetzt immer noch nicht das was ich hätte posten sollen

Mir würde es ja schon reichen, wenn jemand sagt:
- "Ja, so wie du deinen nicht modalen Dialog in einer DLL startest ist ok"
- "Nein, so würde ich es nicht machen weil, das zu fehlern füren kann. Ich würde es so machen..."Viele Grüße
CChris
-
Ist es eine gute Idee, eine weitere App-Instanz durch die Dll zugeschoben zu bekommen?
-
Hi!
Zunächst einmal Danke für deine Antwort!
Aber ich versteh Deine Frage nicht ganz. Wieso eine weitere App-Instanz, es wird doch für jeden Aufrfer der DLL nur eine Instanz erzeugt (das globale theApp Objekt).
Viele Grüße
CChris