Anwenderdefinierte Ressourcen

Bisher haben wir nur vom System vorgegebene Ressource-Typen eingesetzt. WINDOWS bietet jedoch auch die Möglichkeit, eigene Daten als Ressourcen abzulegen.

Fangen wir mit einem einfachen Beispiel an, dem Ablegen einer Klang-Datei (WAV-File) innerhalb einer Ressource. Um eine Klang-Datei als Ressource zur Anwendung hinzuzufügen, gehen Sie zunächst in die Ressource-Ansicht. Klicken Sie dann mit der rechten Maustaste eine beliebige Ressource an und wählen Sie aus dem Kontext-Menü den Eintrag Importieren..... Im Import-Dialog wählen Sie als Dateityp Wave-Dateien (.wav) aus und dann die zu importierende Klang-Datei.

Importieren eine WAV-Datei

Danach wird die Klang-Datei als Ressource-Typ "WAVE" mit der ID IDR_WAVE1 zur Ressource hinzugefügt und im Editorfenster binär dargestellt.

Die WAV-Ressource

Als nächstes gilt es, diese neue Ressource in der Anwendung zu laden. Dazu muss zuerst das Handle auf die Ressource geholt werden. Dies Handle liefert die API-Funktion FindResource(...). Die Funktion erhält u.a. den Namen und Typ der gesuchten Ressource als String. Da der Ressource-Editor in der Regel aber mit IDs arbeitet, müssen Sie die Ressourcen-ID mit dem Makro MAKEINTRESOURCE(...) in einen LPCTSTR-Datentyp konvertierten. Im obigen Beispiel übergeben Sie an die Funktion für den Namen MAKEINTRESOURCE( IDR_WAVE1) und für den Typ "WAVE".

Ist das Ressourcen-Handle bestimmt, kann die Ressource in den Speicher geladen werden. Dazu wird die API-Funktion LoadResource(...) aufgerufen, der Sie das vorhin erhaltene Ressourcen-Handle als Parameter übergeben. Als Returnwert liefert die Funktion, bei erfolgreichem Aufruf, die Speicher-Adresse, ab der die Ressource abgelegt ist.

Sehen wir uns jetzt das komplette Laden der Ressource im Konstruktor eines Ansichtsobjekts an.

CUserResView::CUserResView()
{
    // ZU ERLEDIGEN: Hier Code zur Konstruktion einfügen,
    // WAV-Ressource suchen
    HRSRC hRes = ::FindResource(NULL,MAKEINTRESOURCE(IDR_WAVE1),"WAVE");
    ASSERT(hRes);
    // Ressource laden
    m_pszWave = (LPCSTR)::LoadResource(NULL,hRes);
    ASSERT(m_pszWave);
}

So, damit fehlt uns nur noch die Funktion zum Abspielen der geladenen Klang-Ressource. Rufen Sie dazu die API-Funktion sndPlaySound(...) auf. Um eine geladene Klang-Ressource abzuspielen, geben Sie im ersten Parameter der Funktion den Zeiger auf den Speicherbereich an, in den die Klang-Ressource geladen wurde. Dieser Zeiger wurde durch die Funktion LoadResource(...) zurückgeliefert. Der zweite Parameter enthält verschiedene Flags zum Abspielen des Klangs. Hier müssen Sie bei einer Speicher-Ressource unbedingt das Flag SND_MEMORY angeben. Ferner können Sie noch über die Flags SND_ASYNC bzw. SND_SYNC bestimmen, ob der Abspielvorgang asynchron oder synchron erfolgen soll. Beim synchronen Abspielen einer Klang-Ressource kehrt die Funktion erst dann wieder zurück, wenn der gesamte Klang abgespielt wurde.

Wenn Sie die Funktion sndPlaySound(...) einsetzen, müssen Sie explizit die Header-Datei mmsystem.h einbinden. Ferner muss dem Linker noch die Library winmm.lib hinzugefügt werden (Projekt-Einstellungen-Linker).

Im nachfolgenden Beispiel wird der Klang immer dann abgespielt, wenn das Fenster den Focus erhält. Wird dem Fenster der Focus entzogen, wird das Abspielen des Klangs abgebrochen.

void CUserResView::OnSetFocus(CWnd* pOldWnd)
{
    CView::OnSetFocus(pOldWnd);
   
    // TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen
    ::sndPlaySound(m_pszWave,SND_MEMORY|SND_ASYNC);   
}

void CUserResView::OnKillFocus(CWnd* pNewWnd)
{
    CView::OnKillFocus(pNewWnd);
   
    // TODO: Code für die Behandlungsroutine für Nachrichten hier einfügen
    ::sndPlaySound(NULL,SND_MEMORY|SND_ASYNC);        
}

Sehen wir uns nun an, wie eigene Daten als Ressourcen abgelegt und später geladen werden. Um eigene Daten innerhalb einer Ressource abzulegen, gehen Sie zunächst wieder in die Ressourcen-Ansicht und fügen dort eine benutzerdefinierte Ressource hinzu (markierter Button im nachfolgenden Bild).

Benutzdefinierte Ressource hinzufügen

Danach werden Sie aufgefordert, einen beliebigen Namen für den Ressource-Typ anzugeben. Nach dem Sie den Namen eingegeben und den OK-Button gedrückt haben, wird eine entsprechende Ressource angelegt. Im nachfolgenden Bild wurde eine Ressource mit dem Namen MYSTRING und der ID IDR_MYSTRING1 zu den Ressourcen hinzugefügt.

Die benutzerdefinierte Ressource

Im Editorfenster können Sie dann die Daten Ihrer Ressource binär eingeben. Noch ein kleiner Tipp zur Eingabe der Ressource-Daten: soll die Ressource auch Text enthalten, wie im Beispiel unten, so können Sie den Text z.B. im NOTEPAD eingeben und ihn dann über die Zwischenablage (Kopieren-Einfügen) in die Ressource einfügen.

Die Ressource-Daten

Der erste markierte Bereich (rote Umrandung) enthält einen Text der nachher ausgegeben wird. Danach folgt die Hintergrundfarbe des Fensters als RGB-Wert (grün umrandet) und zum Schluss die Textfarbe, ebenfalls als RGB-Wert (blau umrandet). Beachten Sie bitte bei der binären Dateneingabe, dass binäre Daten immer in der Reihenfolge Low-Byte -> High-Byte angegeben werden müssen. So ist der z.B. der RGB-Wert für die Hintergrundfarbe 0x0000, 0x0000, 0x0080, was der Farbe blau entspricht.

Als nächstes geht's wieder ans Laden der Daten aus der eigenen Ressource. Auch hier müssen Sie zunächst mittels FindResource(...) das Ressource-Handle bestimmen und dann die Ressource mit LoadResource(...) laden. Als Returnwert liefert LoadResource(...), bei erfolgreichen Aufruf, wie erwähnt einen Zeiger auf den Speicherbereich, in den die Ressource geladen wurde. Der Zugriff auf die Ressource kann dann über diesen Zeiger erfolgen.

CUserResView::CUserResView()
{
    ....
    ASSERT(m_pszWave);
    // eigene Ressource suchen
    hRes = ::FindResource(NULL,MAKEINTRESOURCE(IDR_MYSTRING1),"MYSTRING");
    ASSERT(hRes);
    // Ressource laden
    char *pcRes = (char*)::LoadResource(NULL,hRes);
    ASSERT(pcRes);
    // Zeiger auf Text aus Ressource holen
    m_pcText = pcRes;
    // Hintergrund- und Schriftfarbe aus Ressource auslesen
    // und in COLORREF-Wert konvertieren
    pcRes += strlen(m_pcText)+1;
    m_BkColor = RGB(*(short*)(pcRes),*(short*)(pcRes+2),*(short*)(pcRes+4));
    m_TextColor = RGB(*(short*)(pcRes+6),*(short*)(pcRes+8),*(short*)(pcRes+10));
}

Das fertige Programm zu diesem Thema finden Sie unter 07Ressourcen\UserRes.



Copyright © 2004

Senden Sie Emails mit Fragen oder Kommentaren zu dieser Website an: mailto:info@cpp-tutor.de
 Wolfgang Schröder, Lerchenweg 23, D-72805 Lichtenstein. Tel: +49 7129 6470