{"id":313,"date":"2008-09-14T17:24:48","date_gmt":"2008-09-14T15:24:48","guid":{"rendered":"http:\/\/blog.m-ri.de\/?p=313"},"modified":"2008-09-13T21:15:21","modified_gmt":"2008-09-13T19:15:21","slug":"dialog-basierende-mfc-anwendungen-einmal-anders","status":"publish","type":"post","link":"http:\/\/blog.m-ri.de\/index.php\/2008\/09\/14\/dialog-basierende-mfc-anwendungen-einmal-anders\/","title":{"rendered":"Dialog basierende MFC-Anwendungen einmal anders"},"content":{"rendered":"<p>Ich habe mich zwar gerade erst dar\u00fcber ausgelassen, dass man dialog basierende Anwendungen gar nicht braucht (<a href=\"http:\/\/blog.m-ri.de\/index.php\/2008\/09\/07\/die-unsitte-dialogbasierende-anwendungen-zu-bauen-statt-sdi-mit-cformview-zu-verwenden\/\">sieh hier<\/a>), aber ganz und gar unsinnig sind sie ja nicht.<\/p>\n<p>Bei mir ist der h\u00e4ufigste Anwendungsfall eine simpler Dialog, der nur zum Steuern eines Programmes dient, das ein Icon in der Taskleiste abablegt.<\/p>\n<p>\u00c4rgerlich ist dann nur, dass man nicht vermeiden kann, dass beim Start der Anwendung der Dialog kurz aufflackert, bevor man ihn mit einem Timer oder mit <em>PostMessage <\/em>und einer benutzerdefinierten Nachricht wieder versteckt.<\/p>\n<p>Aber es geht viel einfacher und dazu noch in einer Form, die der <em>MFC<\/em>-Konstruktion besser entspricht, als das Ger\u00fcst, das der Applikations-Wizard erzeugt.<br \/>\nIch m\u00f6chte das hier einfach kurz erl\u00e4utern:<\/p>\n<p>1. Erzeuge ich eine normale dialog basierende Anwendung mit dem Wizard.<\/p>\n<p>2. Dann lege ich ein Objekt der Dialog Klasse mit dem Namen m_dlg in der <em>CWinApp <\/em>Klasse an. Ich m\u00f6chte damit erreichen, dass die Dialogklasse so lange existiert wie die Applikation und nicht mehr nur als lokale Variable in InitInstance auftaucht.<\/p>\n<p>3. Der gesamte Code, den der Wizard erzeugt hat:<\/p>\n<pre lang=\"cpp\">CTestDLGDlg dlg;\r\nm_pMainWnd = &amp;dlg;\r\nINT_PTR nResponse = dlg.DoModal();\r\nif (nResponse == IDOK)\r\n{\r\n    \/\/ TODO: Place code here to handle when the dialog is\r\n    \/\/ dismissed with OK\r\n}\r\nelse if (nResponse == IDCANCEL)\r\n{\r\n    \/\/ TODO: Place code here to handle when the dialog is\r\n    \/\/ dismissed with Cancel\r\n}<\/pre>\n<p>wird ersetzt durch:<\/p>\n<pre lang=\"cpp\">\/\/ Create the Dialog\r\nif (m_dlg.Create(CMyDlg::IDD))\r\n{\r\n    m_pMainWnd = &amp;m_dlg;\r\n    return TRUE;\r\n}\r\nelse\r\n    return FALSE;<\/pre>\n<p>4. Kleine Sch\u00f6nheitskorrektur nun. Man verlagert das Laden des Applikations-Icons aus dem Konstruktor des Dialogs nach OnInitDialog.<\/p>\n<pre lang=\"cpp\">m_hIcon = AfxGetApp()-&gt;LoadIcon(IDR_MAINFRAME);<\/pre>\n<p>Fertig \u2757<\/p>\n<p>Kurz erkl\u00e4rt: Aus dem modalen Dialog der durch <em>DoModal <\/em>gestartet wird wird nun ein modaler Dialog, der durch die Messageloop der CWinApp::Run gesteuert wird. Von der sonstigen Funktionsweise \u00e4ndert sich nichts.<br \/>\nDieser Konstrukt h\u00e4lt sich nach meiner Meinung weit mehr an das <em>MFC <\/em>Ger\u00fcst, als die Anwendung, die der Wizard erzeugt.<br \/>\nDie Vorteile sind schnell aufgez\u00e4hlt:<\/p>\n<ol>\n<li>InitInstance wird durchlaufen und <em>CWinApp:Run <\/em>wird verwendet.<br \/>\nDies hat z.B. zur Folge, dass auch <em>CWinApp::OnIdle<\/em> durchlaufen wird und tempor\u00e4re Map Objekte entsorgt werden. (siehe Kommentar unten)<\/li>\n<li>Man kann die Applikation ohne Flackern zu dem Moment sichtbar machen an dem man es m\u00f6chte. Dazu muss man nur das <em>WS_VISIBLE <\/em>Flag im Dialogtemplate entfernen und <em>ShowWindow <\/em>aufrufen, wenn es einem passt.<\/li>\n<\/ol>\n<p>Vielleicht sehen ja andere Leser noch mehr Vorteile&#8230; die Diskussion ist er\u00f6ffnet \ud83d\ude09<\/p>\n<p>PS: Noch ein kleiner Nachtrag zu den oben erw\u00e4hnten tempor\u00e4ren Handle Maps in einer dialog basierenden Applikation. Diese tempor\u00e4ren Handlemaps werden automatisch aufger\u00e4umt und gel\u00f6scht wenn <em>CWinApp::OnIdle <\/em>ausge\u00fchrt wird. Das ist normalerweise der Fall wenn in <em>CWinApp::Run <\/em>keine Nachricht in der\u00a0Messagequeue liegt, die abgearbeitet werden muss (<em>PeekMessage<\/em> gibt <em>FALSE<\/em> zur\u00fcck). Im Gegensatz dazu werden Handlemaps nicht gel\u00f6scht wenn die\u00a0Nachrichtenschleife mit <em>CWnd::RunModalLoop <\/em>f\u00fcr einen modalen Dialog ausgef\u00fchrt wird. So also auch niemals in einer dialog basierenden Anwendung, oder wenn ein modaler Dialog in einer MFC-Applikation ausgef\u00fchrt wird!<br \/>\nDas fast noch mal einen Artikel wert&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ich habe mich zwar gerade erst dar\u00fcber ausgelassen, dass man dialog basierende Anwendungen gar nicht braucht (sieh hier), aber ganz und gar unsinnig sind sie ja nicht. Bei mir ist der h\u00e4ufigste Anwendungsfall eine simpler Dialog, der nur zum Steuern eines Programmes dient, das ein Icon in der Taskleiste abablegt. \u00c4rgerlich ist dann nur, dass &hellip; <a href=\"http:\/\/blog.m-ri.de\/index.php\/2008\/09\/14\/dialog-basierende-mfc-anwendungen-einmal-anders\/\" class=\"more-link\"><span class=\"screen-reader-text\">\u201eDialog basierende MFC-Anwendungen einmal anders\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],"tags":[370,352,61],"class_list":["post-313","post","type-post","status-publish","format-standard","hentry","category-c","category-mfc","category-programmieren","tag-c","tag-mfc","tag-winapi"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/313","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=313"}],"version-history":[{"count":1,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/313\/revisions"}],"predecessor-version":[{"id":323,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/posts\/313\/revisions\/323"}],"wp:attachment":[{"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/media?parent=313"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/categories?post=313"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.m-ri.de\/index.php\/wp-json\/wp\/v2\/tags?post=313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}