An manchen Tagen zeigt sich die magische Seite der Softwareentwicklung. Magisch ist alles, was dem Ungelernten verborgen ist. Manchmal aber glauben auch die Gelernten und die, die meinen etwas gelernt zu haben, an Magie.
An diesem Montag verhielt sich die Software anders als am Freitag. Von den schönen Bildern, die ich im letzten Beitrag schilderte, zeigte sich keines.
Magisch war an dieser Stelle noch nichts. Immerhin verwendete die Software Teile von anderen Projekten und bei einem neuerlichen Zusammenbau am Montag konnte es passieren, dass eben etwas nicht stimmte.
Obwohl? Unsere Oberfläche hat ihre eigenen Icons, die von unserem UX-Designer gemalt wurden. Warum nur wurden sie nicht gefunden?
Ich forschte den ganzen Tag. Am Ende zeigten sich die Bilder wieder. Die Ursache schien aber magisch zu sein!
Der erste Teil — Debuggen und so
Wenig später meldeten sich Kollegen, dass die Icons verschwunden waren. Am Montag schon so gefragt zu sein, erleichtert das Einfinden in die Arbeitswoche.
Ich baute die Software im Debug Modus und nun prüfte das System die Zusicherungen und meldete diverse „Assertion Errors”. Schnell verriet es die Stelle, die schieflief. Die Bilder wurden gesucht, aber dann doch nicht geladen.
Was war hier los? Stimmten die resource dlls? Enthielten diese die korrekten Icons?
Es gab in der letzten Woche Probleme mit der Versionsverwaltung. Sollte hier das Problem liegen? Musste das am Montag sein? Eine Kontrolle der Quellen zeigte nichts Auffälliges. Alles stimmte mit dem Stand von Freitag überein.
Wenn das am Freitag lud, musste das auch am Montag laden!
Nach dem Frühstück nahm ich mir vor, den Freitag zu vergessen und das Problem zu lösen. Ich setzte einen Breakpoint am Anfang der Ladesquenz und ließ die Software von API Aufruf zu API Aufruf laufen, bis etwas nicht mehr funktioniert.
Ich kam an diese Stelle:
int vsize = SizeofResource(NULL, hsrc);
Die Variable vsize gab die Größe des Bildes an, das vom Icon gelesen werden soll. Je nach Auflösung wären das 16×16 bis 48×48 Bits. Der Debugger zeigte einen Wert von 0.
Das war das Problem. Ein Blick in MSDN erklärte die Parameter. Der erste bestimmt den Ort der Resourcen. Waren diese im Hauptprogramm oder in einer dll? Der Wert NULL bedeutete Hauptprogramm. Das schien verkehrt zu sein, da die Software in Zeilen davor eine hInstance Variable verwendete.
Ich änderte NULL in hInstance:
int vsize = SizeofResource(hInstance, hsrc);
Nun hatte vsize den Wert von 96. Das sah besser als 0 aus, war aber immer noch verkehrt. Die schönen Bilder zeigten sich nicht. Bei 32 Bit Pixeln war ihre Bitmap einfach größer.
An dieser Stellte holte ich mir eine Flasche Mineralwasser aus der Ausgabe in der Mitte des Gebäudes. Mit Bewegung verändert sich immer der Blickwinkel und eine Idee musste her.
Das Umfeld der Funktion sah schon merkwürdig aus. Es waren mehrere HANDLEs deklariert. Mir fiel die Zeit von 1995 ein. Damals war alles ganz anders. Wie war das mit den Icons in der ganz alten Zeit? Im letzten Jahrtausend?
Das war noch eine 16-Bit Welt. Speicherplatz war ganz knapp. Die Resourcen waren kostbar. Icons mit ihrer Sammlung von Bilder in verschiedenen Auflösungen, von denen sowieso nur eines gebraucht wurde, kamen später dazu. Der Weg zum richtigen Bild erfolgte in zwei Schritten. Zunächst ein HANDLE für das Verzeichnis anlegen, dann dieses einlesen. Hier nach dem richtigen Bild fahnden, dann ein HANDLE für das Bild anlegen, damit zum Schluss die Pixel eingelesen werden können.
Sah doch ganz einfach aus. Warum klappte das nicht?
Nach einem Schluck Mineralwasser waren die Augen wieder klar. Das Handle hsrc, war das für das Verzeichnis der Bilder. Für das eigenliche Bild gab es das Handle hrSrc.
Das funktioniert dann:
int vsize = SizeofResource(hInstance, hrSrc);