Windows Programmierung: Ressourcen
Willemers Informatik-Ecke
Ressourcen enthalten unter anderem die Beschreibungen von Menüs, Dialogboxen und Stringtabellen. Sie werden in einer eigenen Sprache definiert. Um sich nicht mit der Sprache befassen zu müssen, gibt es grafische Werkzeuge, die die Erstellung der rc-Dateien übernehmen.

In den Entwicklungsumgebungen für Win32-Programme ist ein RC-Compiler enthalten, der die rc-Dateien in res-Dateien wandelt, die dann zum Projekt hinzugebunden werden.

Eine Ressouce-Datei bindet zu Anfang typischerweise die Datei windows.h ein, um deren Konstantendefinitionen nutzen zu können.

#include "windows.h"

Menüs

Ein Menü wird mit einer ID eingeleitet. Es folgt das Schlüsselwort MENU. In den BEGIN-END-Blöcken werden mit den POPUP-Einträgen Untermenüs und mit MENUITEM die Menüeinträge definiert. Beispiel:
ID_HAUPTMENUE MENU
BEGIN
    POPUP "&Datei"
    BEGIN
        MENUITEM "&Öffnen",         IDM_OPEN
        MENUITEM "&Beenden",        IDM_EXIT
    END
    POPUP "&Hilfe"
    BEGIN
        MENUITEM "&Info...",        IDM_ABOUT
    END
END

Dialoge

Für einen Dialog wird eine DIALOGEX-Ressouce angelegt. Sie beginnt mit einer Integer-Konstante, die durch ein #define auch benannt sein kann. Es folgt DIALOGEX und dann x, y, breite und hoehe in Dialog-Einheiten. Es folgen optionale Elemente:
CAPTION "titelzeile"
Der Text für die Titelzeile
FONT point, "schrift"
Die Schriftart der Dialogbox
STYLE stil
Hier werden die Stilelemente der Dialogbox eingetragen. Mehrere Stile werden durch einen senkrechten Strich getrennt.
WS_CAPTION
Dialogbox hat einen Titelbalken. Enthält auch WS_BORDER
WS_SYSMENU
Der Titelbalken enthält ein System-Menü.
WS_POPUP
Popup-Fensterstil
WS_SIZEBOX
Das Fenster kann vergrößert werden.
DS_CENTER
poitioniert die Dialogbox mittig zum Hauptfenster
DS_CENTERMOUSE
poitioniert die Dialogbox mittig zur Mausposition
DS_FIXEDSYS
verwendet einen nicht-proportionalen Systemfont
DS_MODALFRAME
verwendet einen modalen Dialograhmen
DS_SETFONT
erlaubt das Setzen eines eigenen Fonts
Schließlich werden zwischen BEGIN und END die Dialog-Elemente spezifiziert.

LTEXT, RTEXT oder CTEXT
Statischer Text. Linksbündig, rechtsbündig oder zentriert.
PUSHBOX, PUSHBUTTON, DEFPUSHBUTTON
Varianten eines Buttons
RADIOBUTTON
Radio-Button
CHECKBOX, AUTOCHECKBOX
Checkbutton
EDITTEXT
Eingabefeld
LISTBOX
Eine Listbox
COMBOBOX
Eine Combobox
Ihnen folgen x- und y-Position, Breite und Höhe sowie optional weitere Stile.

Beispiel für eine Dialogbox-Definition:

ID_MEINDIALOG DIALOGEX 100, 50, 170, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Name eingeben!"
FONT 8, "MS Shell Dlg"
BEGIN
    EDITTEXT        ED_WAHL,40,14,120,12
    LTEXT           "Wähle: ",IDC_STATIC,14,14,22,8,SS_NOPREFIX
    DEFPUSHBUTTON   "OK",IDOK,113,41,50,14,WS_GROUP
END
Mehr zur Definition einer DIALOGEX-Ressource steht im MSDN von Microsoft.

STRINGTABLE

Mit einem String-Table können Meldungen des Programms in die Ressourcen ausgelagert werden. Da hier auch Dialoge und Menüs liegen, ist es möglich, die sprachlichen Eigenheiten vom eigentlichen Quelltext fernzuhalten.

Das folgende Beispiel definiert Grußworte für den norddeutschen Raum.

STRINGTABLE
BEGIN
IDS_HELLO,   "Moin"
IDS_GOODBYE, "Tschüß"
END 

Im Süden Deutschlands und Österreich wäre wohl folgende Ressource angebrachter.

STRINGTABLE
BEGIN
IDS_HELLO,   "Grüß Gott"
IDS_GOODBYE, "Servus"
END 

Strings aus Ressourcen laden

Der String wird in einem Stringtable in der Ressource definiert. Der Zweck dieses Tuns liegt darin, daß internationale Versionen allein durch Änderung der Ressourcen erstellbar sind.

char Message[80];

  LoadString(GlobalInstance, ResNr, Message, sizeof(Message));

Bitmap aus Ressourcen laden

Mit der Funktion LoadBitmap kann eine Bitmap in der Ressource geladen werden. Als Ergebnis bekommt man das HBITMAP. Im Beispiel, das aus einer WM_PAINT-Bearbeitung stammt, wird der Hintergrund mit der Bitmap gekachelt.

	HBITMAP hBitmap;
	HBRUSH hbr, hbrPrevious;
	RECT rc;

	hBitmap = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP1));

	hbr = CreatePatternBrush(hBitmap);
	hbrPrevious = (HBRUSH)SelectObject(hdc, hbr);

	GetClientRect(hWnd, &rc);
	PatBlt(hdc, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, PATCOPY);

	SelectObject(hdc, hbrPrevious);
	DeleteObject(hbr);
	DeleteObject(hBitmap);

Die Bitmap muss anschliessend per DeleteObject freigegeben werden.