manuelles Beenden des Programms



  • Ich hab in der von CWinApp abgeleiteten Klasse schon eine Funktion

    OnAppExit()

    verwendet, was auch ohne Probleme funktioniert.
    Nur habe ich jetzt beim Nachschauen in der MSDN hierzu überhaupt nichts gefunden 😮

    Woc ich diese Funktion mal herhatte, weiß ich auch nicht mehr, aber wie gesagt, es funktioniert 😉



  • Danke bei return FALSE gehts. Allerdings funktioniert auch SendMessage(m_pMainWnd->m_hWnd,WM_CLOSE,0,0);
    Warum weiß ich allerdings nicht. Zmindest geht WM_QUIT nicht. Was mich aber noch interessiert: wenn ich FALSE zurückgebe killt das Prog auch alle seine Instanzen im Speicher selbst oder muss man da noch etwas machen?



  • unregistered schrieb:

    Wieso ist das sinnlos? 😕

    Grob gesagt, die SendMessage() wartet ab, bis die Nachricht bearbeitet wurde. Aber das Fenster kann die Nachricht erst bearbeiten, wenn es die Kontrolle wiederbekommen hat (und das geschieht erst, nachdem SendMessage() fertig ist).

    (und eine MessageBox gibt auch zurück, welche Taste der User gedrückt hat - darauf aufbauend kannst du in der InitInstance weiterarbeiten)



  • OnAppExit() funzt auch, ist von CWinApp abgeleitet und auch in der MSDN zu finden. Allerdings kommt in der Debugversion eine Warnung:
    Warning: m_pMainWnd is NULL in CWinApp::Run - quitting application.
    Was hat die zu bedeuten?
    Ja was du da sagst mit dem Abarbeiten und widerbekommen von SendMessage klingt einleuchtend; aber warum funzt es dann mit WM_Close?



  • MSDN schrieb:

    Do not post the WM_QUIT message using the PostMessage function; use PostQuitMessage.



  • ok, aber nur wenn man PostMessage nimmt. Hir wird ja SendMessage verwendet. Im übrigen hat man wie schon gesagt bei der Verwendung von PostQuitMessage wahnsinnig viele Speicherlecks



  • OnAppExit() funzt auch, ist von CWinApp abgeleitet und auch in der MSDN zu finden.

    Und wo ist das zu finden? Weder auf meiner CD-MSDN (ist schon uralt) noch online (Link) kann ich das finden...



  • Hm wenn ich raten soll, würd ich sagen das WM_QUIT die Anwendung schließt, ohne den Fenstern die Möglichkeit zu geben ihre Ressourcen freizugeben. Weil für WM_CLOSE gibts ja einen Nachrichtenhandler in CWnd.

    Würd mich aber auch mal genauer interessieren, falls da jemand genaueere Kentnisse zu hat.



  • hm jo WM_CLOSE ruft irgendwann WM_QUIT. Zumindest muss man das bei reiner WinAPI machen, aslo wirds auch in der MFC irgendwie verankert sein.



  • Folgendes hab ich in meiner MSDN-CD-Version gefunden:

    ID_APP_EXIT Exit the application.
    CWinApp::OnAppExit handles this command by sending a WM_CLOSE message to the application's main window. The standard shutting down of the application (prompting for dirty files and so on) is handled by the CFrameWnd implementation.

    Customization of this command handler is not recommended. Overriding CWinApp::SaveAllModified or the CFrameWnd closing logic is recommended.

    If you choose to implement this command, we recommend you use this command ID.

    Somit müsste der Ansatz mit WM_CLOSE der richtige sein, da das Anwendungsgerüst alles dann selbst erledigt.



  • Im übrigen hat man wie schon gesagt bei der Verwendung von PostQuitMessage wahnsinnig viele Speicherlecks

    Kannst du das mal erklären? Was meinst du mit "hat man Speicherlecks?".

    PostQuitMessage postet einfach eine WM_QUIT an den aktuellen Thread. Der kann dann selber schauen, wie er damit umgeht.

    Wenn dus hart haben willst, geht auch ::ExitInstance(). Schön ist es nicht, evtl. wurden vorher nicht alle Ressourcen freigegeben. Weil die Applikation aber ziemlich sicher beendet wird macht das ja nichts, Windows kümmert sich dann darum.

    In einer MFC Dialoganwendung wäre EndDialog() ok.

    WM_CHEERS



  • Warning: destroying CSingleDocTemplate with live document.
    Detected memory leaks!
    Dumping objects ->
    {270} normal block at 0x002F6658, 23 bytes long.
    Data: < 2| > D8 9C 32 7C 06 00 00 00 06 00 00 00 01 00 00 00
    {229} normal block at 0x002F5370, 26 bytes long.
    Data: < 2| > D8 9C 32 7C 09 00 00 00 09 00 00 00 01 00 00 00
    array_p.cpp(112) : {223} normal block at 0x002F6050, 20 bytes long.
    Data: < $R/ > 00 00 00 00 24 52 2F 00 00 00 00 00 CD CD CD CD
    array_p.cpp(69) : {222} normal block at 0x002F6010, 4 bytes long.
    Data: < > 00 00 00 00
    winfrm2.cpp(62) : {221} client block at 0x002F5F10, subtype c0, 192 bytes long.
    a CDockBar object at $002F5F10, 192 bytes long
    array_p.cpp(69) : {220} normal block at 0x002F5ED0, 4 bytes long.
    Data: < > 00 00 00 00
    winfrm2.cpp(62) : {219} client block at 0x002F5DD0, subtype c0, 192 bytes long.
    a CDockBar object at $002F5DD0, 192 bytes long
    array_p.cpp(69) : {218} normal block at 0x002F5D90, 4 bytes long.
    Data: < > 00 00 00 00
    winfrm2.cpp(62) : {217} client block at 0x002F5C90, subtype c0, 192 bytes long.
    a CDockBar object at $002F5C90, 192 bytes long
    winfrm2.cpp(62) : {215} client block at 0x002F5B90, subtype c0, 192 bytes long.
    a CDockBar object at $002F5B90, 192 bytes long
    bardock.cpp(735) : {214} normal block at 0x002F5968, 176 bytes long.
    Data: < } | > C4 7D 14 7C CD CD CD CD CD CD CD CD CD CD CD CD
    {213} normal block at 0x002F5B40, 19 bytes long.
    Data: < 2| > D8 9C 32 7C 02 00 00 00 02 00 00 00 01 00 00 00
    {212} normal block at 0x002F5AF0, 20 bytes long.
    Data: < 2| > D8 9C 32 7C 03 00 00 00 03 00 00 00 01 00 00 00
    {211} normal block at 0x002F5AA0, 19 bytes long.
    Data: < 2| > D8 9C 32 7C 02 00 00 00 02 00 00 00 01 00 00 00
    {207} normal block at 0x002F5840, 80 bytes long.
    Data: < @ > 00 00 00 00 40 01 00 00 00 01 00 08 00 00 00 00
    plex.cpp(32) : {204} normal block at 0x002F5788, 124 bytes long.
    Data: < W/ $R/ > 00 00 00 00 98 57 2F 00 00 00 00 00 24 52 2F 00
    plex.cpp(32) : {203} normal block at 0x002F56D0, 124 bytes long.
    Data: < 8V/ > 00 00 00 00 00 00 00 00 00 00 00 00 38 56 2F 00
    d:\programmierung\temp\testview.cpp(20) : {202} client block at 0x002F5638, subtype c0, 88 bytes long.
    a CWickelView object at $002F5638, 88 bytes long
    {198} normal block at 0x002F5410, 23 bytes long.
    Data: < 2| > D8 9C 32 7C 06 00 00 00 06 00 00 00 01 00 00 00
    d:\programmierung\temp\mainfrm.cpp(16) : {195} client block at 0x002F50B8, subtype c0, 548 bytes long.
    a CMainFrame object at $002F50B8, 548 bytes long
    {186} normal block at 0x002F5058, 34 bytes long.
    Data: < 2| > D8 9C 32 7C 11 00 00 00 11 00 00 00 01 00 00 00
    {114} normal block at 0x002F4FE8, 45 bytes long.
    Data: < 2| > D8 9C 32 7C 0E 00 00 00 1C 00 00 00 01 00 00 00
    {111} normal block at 0x002F2EE0, 28 bytes long.
    Data: < 2| > D8 9C 32 7C 0B 00 00 00 0B 00 00 00 01 00 00 00
    {110} normal block at 0x002F29D8, 20 bytes long.
    Data: < 2| > D8 9C 32 7C 03 00 00 00 03 00 00 00 01 00 00 00
    d:\programmierung\temp\testdoc.cpp(54) : {109} client block at 0x002F2DA8, subtype c0, 248 bytes long.
    a CTestDoc object at $002F2DA8, 248 bytes long
    Object dump complete.

    Soviel erst mal zu den Speicherlecks. Warum das so ist: keine Ahnung.... mach das ja noch nicht so lange. Offensichtlich wird da nich alles freigegeben. Wenn man SendMessage mit WM_CLOSE macht ist das nicht so.
    EndDialog schließt doch ein Dialogfenster aus der Klasse CDialog soweit ich weiß. Das würde beim Mainframe nicht ganz funktionieren.



  • wie schon oben angedeutet: WM_CLOSE ruft WM_QUIT auf, tut aber wohl vorher noch ein paar andere Sachen machen, wie z.B. anscheindend ads Fenster freigeben. Wers genau wissen will: ➡ mit dem Debugger durchgehen



  • Das WM_CLOSE wird in der Regel an alle Clients durchgereicht, sprich alle Dokumente werden ordnungsgemäß geschlossen. WM_QUIT dagegen ist eher mit dem bereits erwähnet ExitInstance zu vergleichen. 🙂

    Zumal bei WM_CLOSE das Standardverfahren für ungesicherte Dokumente etc. durchlaufen wird. Sollte aber in diesem speziellen Fall nicht von Belang sein. Wenn man bereits in InitInstance die Entscheidung trifft, die Applikation garnicht weiter auszuführen, reicht auch ein return FALSE;

    Speicherleaks sind an dieser Stelle eh irrelevant, wenn die App abgeschossen wird. Und was die Dokumente angeht, was soll da schon groß drinne stehen, wenn man noch in InitInstance steckt.


Anmelden zum Antworten