[GoCODE]SendMessage[GELÖST] Neues Topic: Perfektes Beenden



  • DestroyWindow



  • bool running
    

    ist quatsch
    dein programm wird schon merken, wenn es keine nachrichten mehr mit GetMessage bekommt - dann wurde nämlich bereits WM_QUIT gesendet 😉



  • oO schrieb:

    du bist irgendwie komisch 🙄

    Wieso? Warum? Weshalb?



  • hey schrieb:

    bool running
    

    ist quatsch
    dein programm wird schon merken, wenn es keine nachrichten mehr mit GetMessage bekommt - dann wurde nämlich bereits WM_QUIT gesendet 😉

    Und woher sollte WM_QUIT gesendet werden?

    P-Poss schrieb:

    DestroyWindow

    Wie wende ich das an? Welche Parameter? Ich habe zur Zeit keine GUI bzw. WinSDK da.



  • Ahoi, also falls *ich* Dir nicht antworten soll, kannst Du meinen Post ja einfach ignorieren (da ich Dich ja angeblich mobbe) :p , alle anderen können ihn einfach als Antwort auf seine Frage verstehen 😉 .

    Zu Deiner Frage: Deine 'Konstruktion' ist überflüssig, da ein Aufruf von PostQuitMessage (wie der Name auch schon sagt) eben ein WM_QUIT in Deine Nachrichtenschleife einreiht. Falls GetMessage auf ein WM_QUIT trifft, sorgt das für die Rückgabe des Wertes FALSE. Und da while(FALSE) { ... } nicht weiter bearbeitet wird (eben weil das Abbruchkriterium der Schleife erfüllt ist), beendet sich das Programm. DestroyWindow sollte ebenfalls aufgerufen werden, da es Aufräumarbeiten durchführt (z.B. das Löschen von Timern, die mit dem Fenster assoziiert sind).

    Das 'HWND hButton' am Ende Deiner WndProc stellt übrigens einen Fehler gegen die vorgeschriebene Syntax einer Fensterprozedur da. Das muss da weg 😉 - also hier:

    LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,HWND hButton)
    

    Dann vllt noch dazu:

    PostMessage(hWnd,WM_DESTROY,NULL,NULL) //oder so ähnlich
    

    Wenn Du an irgendeiner Stelle dafür sorgen willst, dass sich Dein Programm beendet, mache ich das immer mit:

    SendMessage(hWnd, WM_CLOSE, 0, 0);
    

    Unter WM_CLOSE führe ich dann Aufräumarbeiten durch, vorher ggfs. die Frage an den Benutzer, ob er das Programm wirklich beenden will, und schließlich folgt der Aufruf von DestroyWindow. Also beispielsweise so:

    // ...
    case WM_CLOSE:
       if(MessageBox(hWnd, TEXT("Wollten Sie das Programm wirklich beenden?"), TEXT("Wirklich beenden?"), MB_YESNO | MB_ICONINFORMATION) == IDNO)
          break;
       // Hier ggfs. Clean-Up: [...]
       DestroyWindow(hWnd);
       break;
    // ...
    

    Der Vorteil ist, dass Aktionen, die immer vor dem Beenden des Programms durchgeführt werden müssen/sollten (-> Clean-Up), immer zentral an einer Stelle codiert werden können (eben unter WM_CLOSE).

    PS: Es wäre sinnvoll, wenn Du zusätzlich noch posten könntest, was Du erreichen willst, dass muss man sich nämlich erstmal aus Deinem Code ableiten, was ja nicht zwangsläufig erfolgreich sein muss 😉 .


  • Mod

    Es ist eine Unsitte! 🕶 Wieder mal was für mein Blog.

    WM_DESTROY ist eine interne Nachricht, die durch DestroyWindow ausgelöst wird.
    Auch hier hast Du nichts mit zu tun...

    Wenn Du schon PostMessage verwendest und ein Handle hast, müsstest Du auch wissen, das man das Handle mit DestroyWindow benutzen könnte...

    Verwende die entsprechenden API-Funktionen und die Nachricht wird vom OS versendet.

    BTW:
    1. Es ist unüblich Personen in einem Forum direkt anzusprechen.
    2. Warum sollte ich mich besonders damit auskenne? Es gibt andere, dies es auch können?
    3. Wenn Du kein SDK da hast oder keine GUI, aber hier Posten kannst, dann kannst Du auch die Doku zu DestroyWindow ergoogeln, oder?



  • Martin Richter schrieb:

    Es ist eine Unsitte!

    <Loriot>Ach was?</Loriot>
    Es gibt also keine saubere Möglichkeit, Fenster aus anderen Threads zu schließen (DestroyWindow funktioniert hier bekannterweise nicht)? Und wenn die Microsofties das machen, dann machen sie was falsch (z.B. im Artikel How To Terminate an Application "Cleanly" in Win32)?


  • Mod

    Gästchen schrieb:

    Martin Richter schrieb:

    Es ist eine Unsitte!

    <Loriot>Ach was?</Loriot>
    Es gibt also keine saubere Möglichkeit, Fenster aus anderen Threads zu schließen (DestroyWindow funktioniert hier bekannterweise nicht)? Und wenn die Microsofties das machen, dann machen sie was falsch (z.B. im Artikel How To Terminate an Application "Cleanly" in Win32)?

    Rembrand? Bahnhof?
    In diesem Artikel wird WM_CLOSE versendet und nicht WM_DESTROY.

    Nein! Man kann nicht durch versenden von WM_DESTROY erreichen was WM_DESTROY tut.

    Es gibt sicherlich saubere Lösungen ein Fenster aus einem anderen Thread zu zerstören! Logo.
    Definiere eine eigene Nachricht. Sende diese an das Fenster. Baue einen Handler für dieses Fenster und diese Nachricht, oderdas Parent, der dann in dem Eigentümerthread des Fensters DestroyWindow aufruft...

    Die Doku ist eindeutig:
    http://msdn2.microsoft.com/en-us/library/ms632682.aspx

    A thread cannot use DestroyWindow to destroy a window created by a different thread.



  • Der "Default-Handler (DefWindowProc)" für WM_CLOSE ruft DestroyWindow () auf.
    Wenn man somit in der WM_CLOSE DestroyWindow () selbst aufruft, dann wird DestroyWindow () praktisch zweimal aufgerufen.


  • Mod

    draufleger schrieb:

    Der "Default-Handler (DefWindowProc)" für WM_CLOSE ruft DestroyWindow () auf.
    Wenn man somit in der WM_CLOSE DestroyWindow () selbst aufruft, dann wird DestroyWindow () praktisch zweimal aufgerufen.

    Nicht ganz richtig. Wenn man selber in WM_CLOSE DestroyWindow aufruft dann returniert man natürlich und ruft nicht DefWindowProc auf... oder?

    So sollte man sich verhalten, wenn man es gemäß Doku macht. :xmas1:



  • Martin Richter schrieb:

    In diesem Artikel wird WM_CLOSE versendet und nicht WM_DESTROY.

    Au weia, da hast Du natürlich recht, da habe ich mich aber mächtig verhauen. Ich würde jetzt gern noch etwas schlaues sagen, aber wenn man so daneben liegt...



  • 2. Warum sollte ich mich besonders damit auskenne? Es gibt andere, dies es auch können?

    Du bist doch der Don Quichotte.(dein Blog)
    Das beantwortet auch die Frage warum ich dich direkt angesprochen habe.

    Das 'HWND hButton' am Ende Deiner WndProc stellt übrigens einen Fehler gegen die vorgeschriebene Syntax einer Fensterprozedur da. Das muss da weg - also hier: C/C++ Code:
    LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam,HWND hButton)

    Keine Ahnung wie das da reingekommen ist.

    Es ist eine Unsitte! Wieder mal was für mein Blog.

    Das mit dem bool running auch? Das habe ich aus einem Tutorial.(Spieleprogrammierung) 😉

    Ahoi, also falls *ich* Dir nicht antworten soll, kannst Du meinen Post ja einfach ignorieren (da ich Dich ja angeblich mobbe) , alle anderen können ihn einfach als Antwort auf seine Frage verstehen .

    Zu Deiner Frage: Deine 'Konstruktion' ist überflüssig, da ein Aufruf von PostQuitMessage (wie der Name auch schon sagt) eben ein WM_QUIT in Deine Nachrichtenschleife einreiht. Falls GetMessage auf ein WM_QUIT trifft, sorgt das für die Rückgabe des Wertes FALSE. Und da while(FALSE) { ... } nicht weiter bearbeitet wird (eben weil das Abbruchkriterium der Schleife erfüllt ist), beendet sich das Programm. DestroyWindow sollte ebenfalls aufgerufen werden, da es Aufräumarbeiten durchführt (z.B. das Löschen von Timern, die mit dem Fenster assoziiert sind).

    Willst du mir damit sagen dass ich bei, ...

    case WM_KEYDOWN:
    if(wParam == 27) //Escape
    {
        PostQuitMessage(0)
    }
    break;
    

    ...das hier so machen könnte: (Doppelpunkt kein Punkt. *WICHTIG* )

    Wenn Du an irgendeiner Stelle dafür sorgen willst, dass sich Dein Programm beendet, mache ich das immer mit:

    SendMessage(hWnd, WM_CLOSE, 0, 0);
    

    @Martin Richter: Ist das auch sauber?(oder doch Unsitte 🙄 )

    Nicht ganz richtig. Wenn man selber in WM_CLOSE DestroyWindow aufruft dann returniert man natürlich und ruft nicht DefWindowProc auf... oder?

    So sollte man sich verhalten, wenn man es gemäß Doku macht.

    Besserwisser. 😃 (Ich will nicht bestreiten , das stimme nicht. Es stimmt.)
    @Draufleger: Danke das wird mir weiterhelfen. Das bestätigt auch warum man WM_CLOSE senden sollte.

    Erstmal *DANKE* an alle. Mir scheint es so als würde halb Windows nur aus Befehlen zum Beenden zu bestehen und zeim Aufrümen und zum zerstörem. 😉

    P.S.: GoCODE klingt mal derbst beschis*en.( Warum hat das keine gesagt? )



  • Martin Richter schrieb:

    Wenn man selber in WM_CLOSE DestroyWindow aufruft dann returniert man natürlich und ruft nicht DefWindowProc auf... oder?

    Wo bleibt dann das Zusammenspiel mit dem Betriebssystem ?



  • Man kann doch nicht einfach sein Fenster zerstören und dem OS mitteilen, daß WM_CLOSE abgebrochen wurde !



  • Auch wenn das in sehr vielen Dokus favorisiert wird. 🙂



  • Korrekt beendet wird mit der DefWindowProc der WM_CLOSE (mit einem PostQuitMessage () in der WM_DESTROY oder WM_NCDESTROY).



  • Sorry, Spamfilter ! 😞


  • Mod

    Wenn Du Dein Programm beenden möchtest, das ein fenster hat, dan:
    1. Zerstöre das Main Window mit DestroyWindow (oder sende WM_CLOSE wenn es sein muss).
    2. Im WM_DESTROY Handler platziere ein PostQuitMessage.

    PostQuitMessage sollte nur im Response auf die Zerstörung des Main Windows gesendet werden....

    Selbst wenn ich in manchen Fällen "Don Quichote" bin, gibt es genug andere die richtige Antworten geben können. Also stelle lieber allgemein eine Frage zur Diskussion...



  • Martin Richter schrieb:

    Selbst wenn ich in manchen Fällen "Don Quichote" bin, gibt es genug andere die richtige Antworten geben können. Also stelle lieber allgemein eine Frage zur Diskussion...

    Habe ich gemacht.
    Zusammenfassend ist zu sagen: Wenn ich mein Programm von einer beliebigen Stelle des Programmmes beenden möchte z.B.: Per Escapetastendruck dann schaut meine Window Procedure wie folgt aus:

    LRESULT CALLBACK WindowProcedure(HWND hWindow,HINSTANCE hInstance,WPARAM wParam,LPARAM lParam,unsigned int message)
    {
        switch(message)
        {
        case WM_KEYDOWN:
        DestroyWindow(hWindow)
        break;
    
        case WM_DESTROY:
        PostQuitMessage(wParam); // Das Programm wird mit der gedrückten Taste beendet
                                 // bzw um korrekt zu sein: Der virtuelle 
                                 // Tastencode der gedrückten Taste wird als
                                 // Exitcode verwendet. Zufrieden? 
        break;
        }
    }
    

    Richtig so?(Und ja ich weis das man jede andere Botschaft an Windows via DefWindowProc weiterleiten muss. 😉 )



  • Ja, kannst Du so machen (Dir ist aber schon klar, das bei dem Code, Dein Fenster bei jeder Taste beendet wird, oder? Nicht nur bei Escape 😉 .).

    Hoffe, Du hälst mich für kompetent genug 😃 ... falls nicht frag am besten nochmal Martin, oder er bescheinigt mir ausreichende Kompetenzen zur Beantwortung Deiner Fragen 😃 - dann kannst Du Dir auch ganz sicher sein *grinz*.

    PS: Das, im Aufruf von PostQuitMessage, angegebene 'wParam' als Parameter ist falsch, siehe: http://msdn2.microsoft.com/en-us/library/ms632620.aspx ➡

    MSDN zu WM_DESTROY schrieb:

    Parameters:

    • wParam: This parameter is not used. ⚠
    • lParam: This parameter is not used.

    EDIT: Das ist jawohl n Witz oder:

    C-Chris schrieb:

    LRESULT CALLBACK WindowProcedure(HWND hWindow,HINSTANCE hInstance,WPARAM wParam,LPARAM lParam,unsigned int message)
    

    Dazu sag ich jetzt mal nix... 🙄


Anmelden zum Antworten