Die Unsitte dialogbasierende Anwendungen zu bauen statt SDI mit CFormView zu verwenden

Es scheint mir meistens ein Anfängerfehler zu sein, dass viele MFC Entwickler (oder solche die es werden wollen) zuerst mal zu einer dialogbasierenden Anwendung greifen.
Ist ja auch nett. Man kümmert sich nur um die paar Dialogfelder und hat kein Doc/View zu verwalten.

Am Ende kommen aber dann noch weitere Wünsche:

  • Ich hätte gerne ein Menü
  • Ich hätte gernenoch einen Toolbar
  • Ich hätte gerne einen Status Bar
  • Schön wäre ein Accelerator

Triviales und nicht triviales schließt sich an:

  • Warum kann ich kein Command/Routing für meinen Toolbar und mein Menü verwenden?
  • Warum schließt mein Dialog bei Nutzung Eingabe-Taste?
  • Kann ich meinen Dialog auch resizen?
  • Die Daten sollen auch gespeichert werden, wie geht das?
  • Ich hätte gerne so einen schönen MFCNext Toolbar in meinem Dialog, oder ein Ribbon, geht das?
  • … (die Liste ist bestimmt nicht vollständig)

Gibt man dann die Antwort, dass man x Klimmzüge machen muss um so etwas in eine dialogbasierende Anwendung einzubauen (wenn es überhaupt geht), dann erntet man noch noch die stöhnende Klage: „Ohhh Mann! Ist das kompliziert!“

Und all das geht nur mit Mühe in einen CDialog einzubauen. Der Grund ist einfach: Das Commandrouting für all diese Elemente ist in CFrameWnd integriert. Aber ein CDialog leitet sich von CWnd ab und ist von Grunde auf für keine dieser Funktionen vorbereitet.

Dabei könnte alles so einfach sein!
Man muss nur einfach eine SDI Applikation mit einem CFormView erzeugen und alle die Wünsche die mancher später hat, kann man sofort erfüllen und wenn man es wirklich nicht will auch weglassen.

Die Frage stellt sich für mich also:
Warum nicht einfach immer gleich eine SDI/CFormView Anwendung bauen ❓
Das Potential dieser Anwendungsform ist einfach unerreichbar verglichen mit einer dialogbasierenden Anwendung.

Also sollte man sich mal die Liste der Wünsche, die ich hier aufgestellt habe ansehen und als Checkliste betrachten. Sollte einer dieser oben aufgeführten Punkte für die Applikation wichtig sein, würde ich dringend anraten zum SDI/CFormView zu greifen.
Das ist auch der Fall, wenn diese Anforderungen erst später integriert werden soll. Oft genug ist ja die dialogbasierende Anwendung schon fertig und es heißt dann: Ich möchte doch nur noch…

PS: Ich persönlich benutze nicht mal mehr zu Testzwecken dialogbasierende Anwendungen 😉

15 Gedanken zu „Die Unsitte dialogbasierende Anwendungen zu bauen statt SDI mit CFormView zu verwenden“

  1. Naja, auch wenn ich Dir wieder einmal nur 100% Recht geben kann… ich halte das für normal. Dialogbasierte Anwednungen sind halt am Anfang am einfachsten zu verstehen und werden im Wizard halt auch relativ früh angeboten. Außerdem bekommt man bei Dialog halt viele Sachen direkt, die bei SDI/MDI später und schlechter dokumentiert daherkommen. Zumal der Wizard früher wohl immer „dialog based“ voreingestellt hatte, IIRC. Heute bietet er mir MDI an, kann aber auch sein, daß er sich nur an meine letzeten Wünsche hält. Und dann muß man noch lernen, welche Macht die ComboBox „Base Class“ wirklich hat. Wurde „damals“ FormView überhaupt angeboten oder mußte man sich da hinhacken?

    Alles in allem: die Gravitation zieht den Entwickler wahrscheinlich Richtung Dialog. Ich glaube auch, daß ca. 80% aller Beispiel irgendwie auf dialigbasierte Tester/Demos zurückgreifen, wenn sie nicht gerade ein CMainFrm-Thema direkt addressieren müssen.

    Aber egal, ich programmiert ja eh nur noch mit Word und PowerPoint. 😉

  2. Um ganz ehrlich zu sein, wollte ich einfach mal eine Checkliste zusammenstellen, was eben eine dialog basierende Anwendung nicht kann…

    Mir kommen dialog basierende Anwendungen nicht mal unbedingt zum Testen ideal vor. Oft genug musste ich grafische Sachen machen und da habe ich eher mit einem plain-CView vorlieb genommen, ehe ich auf dem Dialog anfange rumzupinseln.

    Und selbst in den Buch-Klassiker wie Kruglinski & Proise sind (so weit mich mein löchriges Gedächtnis nicht im Stich lässt auch dialog basierende Samples die Ausnahme.

    Und selbst bei den MFC Samples ist kaum eine dialog basierende Anwendung dabei. Ich frage mich woher die „Gravitation“ in diese Richtung kommt.

  3. Der Grund ist ganz einfach. Wenn ich keine genaue Vorstellung davon habe, was der Unterschied ist, dann ist das kleine Bildchen oben links sehr beeinflussend. Bei „Einfaches Dokument“ sehe ich ein leeres Fenster mit einer Menüleiste, bei „Auf Dialogfeldern basierend“ sehe ich Labels, Textfelder und Buttons. Welches von beidem macht wohl den besseren Eindruck? 😉

  4. Hallo Martin,

    da auch ich der Unsitte in meinen Anfängerjahren verfallen war, habe ich deinen Artikel mit Interesse gelesen. Bei mir hat damals in meinen ersten autodidaktischen Programmierversuchen das Doc/View-Zeugs mehr Fragen aufgeworfen als beantwortet. Daher füllte ich mich bei dialogbasierenden Anwendungen eher heimisch.

    Mit den Jahren sah die Programmierwelt dann etwas klarer aus, jedoch frage ich mich aktuell, ob es möglich ist, eine SDI-Anwendung ohne Menü (Datei, Bearbeiten, etc.) zu erstellen? Toolbar, Statusbar kann man ja alles wegprogrammieren/wegselektieren, aber die Menüleiste? Selbst beim SDI (ohne Doc/View) muss ich beim LoadFrame die ID der Menüleistenresource angeben.

    Ist das ein Grund auf eine dialogbasierende Anwendung zurückgreifen zu müssen?

    PS: Ich nutze noch VS2003 (also 7.1). Evtl. generieren die neueren Wizards anderen Code,

  5. Hi Dirk!
    Also ein Menü wird intern von der MFC verlangt. Sonst bekommt man in den Innereien der MFC einen ASSERT. Also kann man nur verhindern, dass das ausgewählte Menü angezeigt wird.
    Du könntest PreCreateWindow von CMainFRame überschreiben. Dann einfach dort den hMenu Parameter der CREATESTRUCT auf NULL setzen.
    Sollte gehen. (Ungetestet).

    BTW: An dem Wizard erzeugten Code hat sich dies bzgl. nichts geändert.

    Mfg Martin

  6. Hallo Martin,

    ja den internen MFC-ASSERT habe ich diesbezüglich auch schon kennengelernt 😉

    Das mit dem hMenu-Parameter auf NULL setzen, funktioniert wunderbar (getestet!). Da steht der SDI-Verwendung nun nichts mehr im Wege.

    Danke vielmals für den Tipp!
    Dirk

  7. Also ich entwickle seit vielen Jahren u.a. mit der MFC. Ich habe „riesige“ MDI-basierende (>250k Lines) enwickelt – aber auch eine große Menge kleiner Tools sind entstanden. Diese entwickle ich seit jeher als Dlg.-basierte Apps. Dafür habe ich mir eine Basisklasse (v. CDialog abgeleitet) geschrieben die mir das komplette Cmd-Routing nachbildet. So kann ich mit wenig Zeilen Tool- und Statusbar aktivieren, Menüs machen eh‘ kein Problem, sogar ToolTips (ToolBar) gehen, OnEnterIdle ist implementiert. Dass das „Resizing“ angesprochen wurde wundert mich ein wenig, da es ja lediglich eine Border-Property ist. Ich könnte noch eine Weile so fortfahren …
    Was mich dazu getrieben hat diese Variante zu wählen ist, dass die entstehenden Tools extrem schlanke, sehr übersichtliche Apps sind. Um z.B. mal eben ein paar Oracle-Instanzen in einem ListCtrl zu listen brauche ich den Overhead der SDI nicht – auch wenn ich in der ToolBar einen Connect/Disconnect Button und in der StatusBar den Connect-Status haben möchte. Am Ende denke ich, ist dies ganz sicher eine Frage des persönlichen Geschmackes – es gibt weitaus schlimmere „Verfehlungen“!

    1. Du hast all das erst schreiben müssen was im SDI frei Haus geliefert wird.
      Wenn Du es dünn und einfach willst ignoriere das Doc und bau alles in den View… und dann?
      Dann ist alles so wie bei Dir. Nur das man eben keinerlei Umbiegen des Command-Routings benötigt etc.
      Und wenn man mehr braucht ist man gewappnet!

      Sorry, aber was Du schreibst überzeugt mich in keiner Weise.

  8. Hallo Martin,
    ich beschäftige mich erstmals mit SDI und finde es ist für jemanden,
    der nicht 100% vom Fach ist schwer zu durchschauen. Ich habe eben im C++ Forum schon einen Beitrag geschrieben um zu erfahren, ob man irgendwie alle Controls mit resizen kann. In meinem Fall liegt ein TabControl mit entsprechenden Dialogen auf dem CFormView, dessen Inhalt (CDialog und dessen Controls) nicht so einfach mitresized wird ;-(

    Jetzt werde ich wohl doch erstmal wieder zu dialogbasierenden Anwendungen über gehen müssen, um weiter zu kommen.
    Mich wundert, dass offenbar sonst niemand solche Fragen bzgl. Resizen
    stellt. Ist doch bei den ganzen Auflösungen etc. echt wichtig das im
    Griff zu haben, damit die Anwender nicht zu eingeschränkt bei der
    Darstellung auf dem Monitor sind, oder?

    In jedem Fall hat das auch was positives. Ich bin auf diesen sehr
    interessanten Blog aufmerksam geworden!!

  9. Gern hätte ich hier kommentiert, aber nicht, wenn Sie alles über US Server schicken. Das zwingt mich, eine falsche eMail-Adresse anzugeben. So langsam sollte auch dem Letzten klar sein, daß es idiotisch ist, wenn alle Welt jegliche Kommunikation via USA führt, sei es nun per Google, Facebook, Apple-App oder was weiß ich. Einfach traurig. Überall diese Paranoia jemand könnte irgendwas Schlimmes schreiben. Weiß nicht, wie oft ich schon davon abgehalten wurde, Leuten in Foren zu helfen, nur weil man immer erst ein Login etc. braucht. Dabei hab‘ ich nie vor, jemanden zu beleidigen (der Ton dieser Frust-Mitteilung ist eine Ausnahme, sorry).

    Überhaupt – die echte eMail angeben ??? Nur weil man mal kurz was kommentieren will ??? Wer würde sowas wollen ?

    1. Was sol der Quatsch?
      1. Steht mein Provider in Deutschland!
      2. Niemand zwingt Dich etwas vernünftiges zu schreiben (und nicht diesen Schrott) und ein Pseudonym anzugeben, was Du ja auch getan hast…

  10. Hallo, ich höre immer davon Dialoge durch SDI/CFormView zu ersetzen.
    Was aber wenn man ein MDI Anwendung hat und dort einen modalen Dialog mit einer Toolbar, Menü etc. braucht?
    SNMP

    1. Das ist weitaus schwieriger, aber auch hier greife ich zu einem Trick und erzeuge einen neues CFrameWnd. Damit die Anwendung wirklich Modal wird wird das MainWnd disabled.

      Das ganze kann man sogar prima isolieren, wenn, mam einen zweiten UI Thread startet und das Main window disables und warten lässt in einer extra Messageloop, bis das andere Fenster sauber schließt.
      Dadurch kann man in dem zweiten Thread schalten und walten wie in einer eigenen Anwendung…

      Just my 2 Cents,

  11. Wow, das hört sich ja richtig gut an; ich bin gerade zu begeistert!
    Ich schlage mich schon seit geraumer Zeit damit herum die Messages umzubiegen oder selber zu verschicken (Timer, der worst case).
    Kannst du das vielleicht etwas detaillierter beschreiben, oder hast du dafür vielleicht ein kleines how to Projekt für mich?
    Gruß SNMP

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

I accept that my given data and my IP address is sent to a server in the USA only for the purpose of spam prevention through the Akismet program.More information on Akismet and GDPR.

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.