Die Optik von Common Controls
« | 17 Jan 2021 | »Raymond Chen hat einige schöne Artikel zum Thema Common Controls verfasst.
Doch wie nutzt man die Windows Common Controls nun am Besten?
Manifest
Am Anfang hat man uns beigebracht, man müsse einfach eine
MYPROGRAM.EXE.manifest
Datei mit folgendem Inhalt erstellen
1<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 2<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 3 <assemblyIdentity 4 version="1.0.0.0" 5 processorArchitecture="*" 6 name="CompanyName.ProductName.YourApplication" 7 type="win32" 8 /> 9 <description>Your application description here.</description> 10 <dependency> 11 <dependentAssembly> 12 <assemblyIdentity 13 type="win32" 14 name="Microsoft.Windows.Common-Controls" 15 version="6.0.0.0" 16 processorArchitecture="*" 17 publicKeyToken="6595b64144ccf1df" 18 language="*" 19 /> 20 </dependentAssembly> 21 </dependency> 22</assembly>
und neben die EXE legen. Windows macht den Rest. Das war zu Zeiten von Windows XP auch die einzige Möglichkeit, weil Programme noch mit dem klassischen VB6 oder VC6 geschrieben wurden und es keine Tools gab um “Manifest” Dateien für Programme zu erstellen.
Erst Visual Studio 2002
brachte Werkzeuge für das Erstellen von Programmen mit, in denen das Manifest
in der EXE selbst untergebracht war.
Nun erstellt man .manifest
Dateien und lässt sie vom Ressourcen Compiler
in die EXE mitaufnehmen. Und wenn wir uns so an die Common-Controls 6.0 binden,
erhalten wir neben “smootheren” Listviews und Treeviews auch neue Features
wie z.B. die Tile-Ansicht (Mehrzeilige Listeneinträge in einem Block).
Statische Bibliotheken
Was mich bei der .manifest
Datei ein bisschen “ankotzt”, ist die Tatsache,
dass ich UI-Special-Features in einer Bibliothek habe und das EXE-Projekt
dann wegen der UI-Lib “angepasst” werden muss, damit es das manifest
in sich aufnimmt. Ist die UI eine dynamische Bibliothek, könnte man das
Manifest dort anbringen, aber bei statischen Bibliotheken geht das nicht.
Außer …
Man kann jedoch ein klassisches Microsoft-C Features nutzen, nämlich
#pragma comment(linker, "...")
und dort dem Linker ein paar Zusatzanweisungen
geben. Statische Bibliotheken geben diese Info auf diese Weise an das
EXE-Projekt weiter und wir können so einen Manifestinhalt per Linker-Option
anfügen.
Das sieht dann etwa so aus:
#pragma comment(linker, "\"/manifestdependency:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
Fazit
Treeview und Listview
sind neben Tabs und Toolbars nach wie vor die häufigsten UI Elemente aus den
“Common Controls”, ohne die ich keine UI bauen könnte.
(Buttons und Textfelder sind eben nicht genug.)
Dass die Elemente aus Kompatibilitätsgründen nur dann das “aktuelle” Windows
Design erhalten, wenn sie per Manifest dafür freigeschaltet sind, ist
ärgerlich. Das liegt vor allem an jenen Entwicklern, die sich unsauber an
nicht dokumentierte Features geheftet haben und Microsoft dann deren
Versagen auszugleichen versuchte.
Wie auch immer … mit der pragma
Lösung kann ich leben. Natürlich steht
dieses Feature nicht unter anderen Compilern zur Verfügung, aber ich erstelle
offizielle Windows Programme nur mit MSVC
. Den MinGW nutze ich nur zur
Verifizierung, dass alles portabel implementiert ist und da kann man mal auf
Manifeste verzichten.
Von daher: Ein Hoch auf pragma
!Aber nur hier in diesem Sondernfall, ansonsten ist pragma
meist böse!