...someplace, where there isn't any trouble? Do you suppose there is such a place, Toto?

Die Antwort auf die Frage "Warum hat CWnd keine virtual functions für Windows Messages?"

Um auf die Antwort auf diese Frage zu kommen, muß man historisch schon etwas bewandert sein. So muß man wissen, daß die ersten Versionen der MFC natürlich nicht für Win32 geschrieben waren sondern für Win16, also für dasjenige Programmiermodell, das die Ausführung von kooperativen Anwendungen unter Windows 3.1++ gestattete. Solcherlei Binaries hatten denselben Aufbau wie die Ende der Achtziger und Anfang bis Mitte der Neunziger stark verbreiteten MS-DOS Binaries. MS-DOS war ein OS, das den Intel 8086/80286 benötigte und in dessen "Real Mode" lief, weshalb der Speicher in sogenannten Segmenten verwaltet wurde, von denen ein jedes 64 kByte groß war. Geringer Speicherbedarf war Trumpf, denn wenn eine Anwendung wenig Speicher benötigte, konnte sie selber mehr Daten verwalten und ließ auch zu, daß so Goodies wie TSR-Programme oder Netzwerkstacks (gasp!) nebenherliefen. Eine andere Eigenheit des Real Mode war, daß Adressen entweder 16 bit breit (NEAR Pointer) sein konnten oder 32 bit breit (FAR Pointer), und die Adressarithmetik, die für FAR Pointer notwendig war, etwas Performance kostete. Also wollte a jeda seine Programme so schreiben, daß möglichst NEAR Pointer verwendet wurden und daß die logischen Segmente für Code, Daten und Stack möglichst klein sein konnten und am Besten in ein- und daselbe physikalische Segment passten.

Durch die damals vorherrschenden Entwicklungswerkzeuge Microsoft C, Microsoft Quick C, Borland Turbo Pascal und Borland Turbo C, später dann MS Visual C 1.0/1.5/1.51/1.52 und Borland C in verschiedenen Versionen, wurde diese segmentierte Architektur durch sogenannte Speichermodelle unterstützt. Durch die Wahl des Speichermodells legte man fest, wie die logischen Segmente auf die physikalischen Segmente verteilt wurden und wie deswegen für die einzelnen Zugriffe die Pointer aussahen, NEAR oder FAR. Dabei gab es folgende Auswahl:

  • Tiny: Code und Daten werden über NEAR Pointer adddressiert und sind in einem einzigen physikalischen Segment kombiniert. Mit dem exe2bin-Programm kann man eine .com Datei aus der exe erstellen, das Binary ist kleiner als 64kByte und läuft nur unter DOS, nicht unter Windows.
  • Small: Code und Daten werden über NEAR Pointer adddressiert und sind in je einem physikalischen Segment. Das Binary läuft unter DOS und Windows.
  • Medium: Code wird über FAR Pointer und Daten werden über NEAR Pointer adddressiert. Das Binary läuft unter DOS und Windows.
  • Compact: Code wird über NEAR Pointer und Daten werden über FAR Pointer adddressiert. Das Binary läuft unter DOS und Windows.
  • Large: Code und Daten werden über FAR Pointer adddressiert. Das Binary läuft unter DOS und Windows.
  • Huge: Code und Daten werden über FAR Pointer adddressiert. Zusätzlich können Large Pointer verwendet werden, die auf einen zusammenhängenden Speicherbereich > 64kByte zeigen, aber sehr teure Zeigerarithmetik bedingen. Das Binary läuft unter DOS und Windows.

Und was hat das jetzt mit den virtuellen Methoden von MFCs CWnd-Klasse zu tun? Ganz einfach: Jede Klasse, die virtuelle Methoden definiert oder redefiniert, impliziert damit eine Tabelle von Funktionszeigern, die sogenannte vtable, die irgendwo im Adressraum des Prozesses zugänglich sein muß. Wenn nun die Basisklasse aller Fenster Hunderte von virtuellen Methoden hätte, hätte das für alle abgeleitete Klassen natürlich auch riesenhafte vtables zur Folge, wenn diese eine virtuelle Methode definieren oder redefinieren. In letzter Konsequenz bedeutet das dann, daß man mit der Wahl des Speichermodells auf Large beschränkt ist, und das wollte man bei MS offensichtlich nicht, weshalb man die platzsparenderen Message Maps statt virtueller Methoden für Messagehandler einführte. Und so kam es, daß eine vom damaligen "App Wizard" erzeugte Standardapplikation mit full-blown Document View-Model die Speichermodelle Medium und Large verwenden konnte. Frameworks, die Message-Handler mit virtuellen Methoden abbildeten, waren auf Large beschränkt.

So, und nun braucht es auch nimmer viel, um die Frage nach den virtuellen Methoden für Property Sheets und Property Pages zu beantworten: Sie wurden eigentlich erst so richtig in Win32 etabliert und kamen erst mit der letzten Version der MFC, der Version 2.52b, als Backport in die Win16-Version der MFC. Und viele virtuellen Methoden sind außerdem ohnehin nur für den Wizard-Mode von Property Sheets erforderlich, der für die Win16-Version nie angeboten oder portiert wurde.

Trackback address for this post

This is a captcha-picture. It is used to prevent mass-access by robots.
Please enter the characters from the image above. (case insensitive)

No feedback yet

Comments are closed for this post.