{"id":484,"date":"2010-06-18T19:58:56","date_gmt":"2010-06-18T18:58:56","guid":{"rendered":"http:\/\/blog.m-ri.de\/?p=484"},"modified":"2010-06-13T20:30:01","modified_gmt":"2010-06-13T19:30:01","slug":"exitinstance-gibt-fuer-dialogbasierende-mfc-anwendungen-unfug-zurueck","status":"publish","type":"post","link":"http:\/\/blog.m-ri.de\/index.php\/2010\/06\/18\/exitinstance-gibt-fuer-dialogbasierende-mfc-anwendungen-unfug-zurueck\/","title":{"rendered":"ExitInstance gibt f\u00fcr dialogbasierende MFC Anwendungen Unfug zur\u00fcck"},"content":{"rendered":"<p>Wer eine dialogbasierende Anwendung mal mit etwas mehr Aufmerksamkeit debuggt oder analysiert wird feststellen, dass der Returncode der Anwendung irgendwie ziemlich zuf\u00e4llig ist. Beobachtet man dies genauer dann stellt man folgendes fest:<\/p>\n<ul>\n<li>Beendet man die Anwendung mit der Maus (Klick auf X) oder OK\/Cancel so ist der Returncode 0<\/li>\n<li>H\u00e4lt man die <em>Strg<\/em>-Taste beim Klick fest ist der Returncode 8<\/li>\n<li>Beendet man die Anwendung mit <em>Alt+F4 <\/em>bekommen wir 2.<\/li>\n<li>Und jedermann kann jetzt schon mal raten was passiert, wenn wir die Umschalttaste festhalten. Genau dann bekommen wir 4 als Returncode.<\/li>\n<\/ul>\n<p>Die Mystik hinter dem Ganzen ist die Behandlung von (<em>Afx)PostQuitMessage<\/em>. Eigentlich sollte mit dieser Nachricht auch der Exitcode gesetzt werden, der mit <em>WM_QUIT<\/em> versendet wird. Und wenn eben bei einer <em>MDI\/SDI <\/em>Anwendung alles normal l\u00e4uft, dann ist diese Nachricht die letzte, die aus der Messsagequeue gezogen wird. Und was passiert in <em>CWinApp::ExitInstance<\/em>? Genau&#8230; aus dem statischen Thread Puffer f\u00fcr die Windowsnachrichten wird mit\u00a0 AfxGetCurrentMessage die letzte Windowsnachricht (normalerweise <em>WM_QUIT<\/em>) geholt und der <em>wParam<\/em> Wert bestimmt. Dieser wird dann zur\u00fcckgegeben.<\/p>\n<p>Leider ist aber <em>WM_QUIT <\/em>in manchen F\u00e4llen aber nicht die letzte Nachricht, die zum Beenden eines Programms f\u00fchrt. Ganz besonders eben nicht bei einer dialogbasierenden <em>MFC<\/em>-Anwendung. Da ist die letzte Nachricht ist dann eben ein <em>WM_COMMAND <\/em>oder ein <em>WM_LBUTTONUP <\/em>der das Schlie\u00dfen der Anwendung ausl\u00f6st \u2757 Und der <em>wParam<\/em> Wert ist eben entsprechend dieser Nachricht belegt!<\/p>\n<p>Gleiches passiert nat\u00fcrlich, wenn man nach dem Beenden der Messageloop noch andere interne Fenster zerst\u00f6rt. Auch in diesem Fall kann noch mal die interne <em>AfxWndProc<\/em> durchlaufen werden und dann wird der Returncode auch wieder ver\u00e4ndert.<\/p>\n<p>Wer also wirklich Wert auf den Returncode legt (im wahrsten Sinne des Wortes), der sollte sich nie auf den Wert verlassen, der durch <em>CWinApp::ExitInstance<\/em> zur\u00fcckgegeben wird oder den Wert, den man selbst mit <em>AfxPostQuitMessage <\/em>evtl. versucht zu setzen. Eine Variable in <em>CWinApp <\/em>tut hier einen besseren Dienst. Ebenfalls sollte man ExitInstance \u00fcberschreiben und immer 0 zur\u00fcckgeben, wenn man sowieso keine Verwendung f\u00fcr den Returncode des Prozesses hat oder haben m\u00f6chte.<\/p>\n<p>BTW:<br \/>\nDie Geschichte, wie ich darauf gekommen bin ist schon eigent\u00fcmlich genug.<br \/>\nIch habe komplexere Batch-Dateien, die die gesamte Erstellung einer produktiv-Version regelt. Darin kommen im Problemfall auch ein paar Userinteraktionen vor. Diese werden durch Windows Anwendungen ausgel\u00f6st, die evtl. einen Dialog anzeigen. Jedem ist klar, dass ohne Dialog und ohne Fenster keine Nachricht abgearbeitet wird. Der Returncode ist also 0! Der Batch verwendet <a href=\"http:\/\/www.jpsoft.com\/\">4NT<\/a> Syntax und dort kann man <em>ON ERROR <\/em>definieren und somit sofort eine Fehlerbehandlung ausl\u00f6sen, wenn der Returncode eines Programms nicht 0 ist.<br \/>\nNun kann sich jeder schon denken was passiert ist. Die Userinteraktion wurde ausgel\u00f6st. Der Benutzer machte eine Angabe und&#8230; der Batch terminierte erstaunlicherweise mit einem Fehler&#8230; (s.o.)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Wer eine dialogbasierende Anwendung mal mit etwas mehr Aufmerksamkeit debuggt oder analysiert wird feststellen, dass der Returncode der Anwendung irgendwie ziemlich zuf\u00e4llig ist. Beobachtet man dies genauer dann stellt man folgendes fest: Beendet man die Anwendung mit der Maus (Klick auf X) oder OK\/Cancel so ist der Returncode 0 H\u00e4lt man die Strg-Taste beim Klick &hellip; <a href=\"http:\/\/blog.m-ri.de\/index.php\/2010\/06\/18\/exitinstance-gibt-fuer-dialogbasierende-mfc-anwendungen-unfug-zurueck\/\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eExitInstance gibt f\u00fcr dialogbasierende MFC Anwendungen Unfug zur\u00fcck\u201c <\/span>weiterlesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[30,4,3,2],"tags":[125,242,370,81,38,241,352],"class_list":["post-484","post","type-post","status-publish","format-standard","hentry","category-c","category-mfc","category-programmieren","category-windows-api","tag-4nt","tag-batch","tag-c","tag-cmdexe","tag-debuggen","tag-dialog","tag-mfc"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/484","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/comments?post=484"}],"version-history":[{"count":0,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/484\/revisions"}],"wp:attachment":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/media?parent=484"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/categories?post=484"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/tags?post=484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}