Technologieaustausch

„Tägliche Windows-API-Praxis“ 9.1.5 Benutzerdefinierte Ressourcen

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Benutzerdefinierte Ressourcen sind eine Art von Ressource, die in Windows-Programmen zum Speichern anwendungsspezifischer Daten, Bilder, Audiodateien, Binärdateien usw. verwendet wird. Durch benutzerdefinierte Ressourcen können Entwickler verschiedene von der Anwendung benötigte Ressourcendateien zentral verwalten und speichern, um einen einfachen Zugriff und eine einfache Verwendung im Programm zu ermöglichen.

Hier sind einige wichtige Punkte zu benutzerdefinierten Ressourcen:

●Typen benutzerdefinierter Ressourcen:

1. Benutzerdefinierte Ressourcen können beliebige anwendungsspezifische Daten oder Dateien sein, z. B. Bilder, Audio, XML-Konfigurationsdateien, Textdateien usw.

2. Benutzerdefinierte Ressourcen können mithilfe einer benutzerdefinierten Ressourcentypkennung identifiziert werden, z. B. „MY_CUSTOM_RESOURCE“.

●Erstellen und bearbeiten Sie benutzerdefinierte Ressourcen:

1. Benutzerdefinierte Ressourcen sind normalerweise in der Ressourcendatei (.rc) einer Anwendung enthalten.

2. Benutzerdefinierte Ressourcen können mit einem Ressourceneditor, beispielsweise der Ressourcenansicht von Visual Studio, erstellt und bearbeitet werden.

3. In der Ressourcendatei können Sie für jede Ressource eine eindeutige Ressourcenkennung und den entsprechenden Ressourcendateipfad angeben.

●Sie können auf benutzerdefinierte Ressourcen verweisen und diese verwenden:

1. Wenn Sie benutzerdefinierte Ressourcen im Code referenzieren und verwenden, können Sie Ressourcen-IDs verwenden, um die entsprechenden Ressourcen zu laden oder darauf zuzugreifen.

2. Verwenden Sie die entsprechenden API-Funktionen (wie LoadResource, FindResource, LockResource usw.), um benutzerdefinierte Ressourcen zu laden und zu betreiben.

3. Abhängig vom Typ der benutzerdefinierten Ressource können Sie unterschiedliche API-Funktionen verwenden (z. B. können Bildressourcen GDI-Funktionen und Audioressourcen DirectSound-Funktionen verwenden), um benutzerdefinierte Ressourcen zu verarbeiten.

■Das Folgende ist ein Beispielcodeausschnitt, der zeigt, wie eine benutzerdefinierte Ressource geladen und verwendet wird:

#enthalten<Windows.h>

int main()

{

HINSTANCE hInstance = GetModuleHandle(NULL); // Aktuelles Instanzhandle abrufen

HRSRC hResource = FindResource(hInstance, MAKEINTRESOURCE(IDR_MY_RESOURCE), "MY_CUSTOM_RESOURCE"); // Benutzerdefinierte Ressourcen finden

HGLOBAL hResData = LoadResource(hInstance, hResource); // Benutzerdefinierte Ressourcen laden

LPVOID pData = LockResource(hResData); // Benutzerdefinierte Ressourcen sperren

// Benutzerdefinierte Ressourcen verwenden...

gebe 0 zurück;

}

Im obigen Beispiel ist IDR_MY_RESOURCE die Kennung der benutzerdefinierten Ressource und der entsprechende Ressourcendateipfad ist in der Ressourcendatei definiert. Verwenden Sie die FindResource-Funktion, um die benutzerdefinierte Ressource zu finden, verwenden Sie dann die LoadResource-Funktion, um die benutzerdefinierte Ressource zu laden, und verwenden Sie schließlich die LockResource-Funktion, um die benutzerdefinierte Ressource zu sperren, um einen Zeiger auf die Ressourcendaten zu erhalten. Anschließend kann der Zeiger pData je nach Art und Anforderungen der Ressource für nachfolgende Verarbeitungen und Operationen verwendet werden.

Es ist wichtig zu beachten, dass die Verwendung einer benutzerdefinierten Ressource vom Ressourcentyp und den Anforderungen der Anwendung abhängt. Entwickler können geeignete Ressourcentypen und entsprechende API-Funktionen auswählen, um benutzerdefinierte Ressourcen basierend auf den tatsächlichen Anforderungen zu verarbeiten.

Benutzerdefinierte Ressourcen bieten eine flexible Methode zur Ressourcenverwaltung für Anwendungen. Verschiedene von Anwendungen benötigte Daten und Dateien können einheitlich verwaltet und im Programm einfach abgerufen und verwendet werden. Durch die Verwendung benutzerdefinierter Ressourcen können Sie Ihre Anwendung modularer, wartbarer und erweiterbarer machen.

       ■im VSFügen Sie benutzerdefinierte Ressourcen hinzu

1. Ressourcen hinzufügen

2. Klicken Sie auf „Anpassen“ und geben Sie den Ressourcentyp „TEXT“ ein.

3. Importieren Sie Ressourcen und generieren Sie automatisch die Datei text1.bin, Ressourcen-ID: IDR_TEXT1

4. Geben Sie in VS den Namen der Ressourcendatei direkt in den benutzerdefinierten Compiler ein und ändern Sie die ID. Es wird eine Fehlermeldung angezeigt: Externe Ressourcen können nicht geladen werden – der mögliche Grund ist, dass die Ressourcen nicht importiert werden.

5. Fügen Sie im Feld „Ressourcenansicht“ Ressourcen hinzu.

6. Importieren Sie externe Ressourcendateien.

7. Geben Sie den Namen und die ID der Ressourcendatei ein. Beachten Sie, dass der ID-Name mit der in Anführungszeichen gesetzten Zeichenfolge „ANNABELLEE“ ausgefüllt werden muss.

8. Speichern Sie einfach die Einstellungen.

 

Es gibt eine einfachere Methode: Ändern Sie direkt die Ressourcendatei POEPOEM.rc. Fügen Sie einfach Ressourcen unter der Zeile unter TEXT hinzu.

      

9.1.6 Übung 57: String-Ressourcentabelle und benutzerdefinierte Ressourcen

/*------------------------------------------------------------------------

057 WIN32 API Jeden Tag üben

     Beispiel 57 POEPOEM.C: String-Ressourcentabelle und benutzerdefinierte Ressourcen

Ladezeichenfolge Funktion

Ressource laden Funktion

Ressourcensuche Funktion

Ressource sperren Funktion

AnsiWeiter Makrodefinition

(c) www.bcdaren.com Programmierer

-----------------------------------------------------------------------*/

#enthalten <windows.h>

#enthalten "ressource.h"

LRESULT RUF ZURÜCK WndProc (HWND, UINT, WPARAM, LPARAM) ;

HINSTAND hInst ;

int WINAPI WinMain (HINSTAND hInstanz, HINSTAND hPrevInstance,

 PSTR szBefehlszeile, int iCmdShow)

{   //Name, Titel und Fehlermeldung der Ressourcendatei

     TCHAR szAppName[16], szBildunterschrift[64], szErrMsg[64];

     HWND hwnd;

     Nachricht Nachricht;

     WNDKLASSE wndclass;

     //String-Ressourcen laden

     Ladezeichenfolge(hInstanz, IDS_APPNAME, szAppName,

          Größe von(szAppName) / Größe von(TCHAR));

     Ladezeichenfolge(hInstanz, IDS_CAPTION, szBildunterschrift,

          Größe von(szBildunterschrift) / Größe von(TCHAR));

     wndclass.Stil = CS_HREDRAW | CS_VREDRAW;

     wndclass.lpfnWndProc = WndProc;

     wndclass.Abonnieren = 0;

     wndclass.cbWndExtra = 0;

     wndclass.hInstanz = hInstanz;

//Symbol hinzufügen

     wndclass.hSymbol = Symbol laden(hInstanz, MAKEINTRESOURCE(IDI_ICON1));

     //wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);

//Benutzerdefinierter Mauszeiger

     wndclass.hCursor = LadeCursor(hInstanz,MAKEINTRESOURCE(IDC_CURSOR1));

     wndclass.hbrHintergrund = (HBRUSH)GetStockObject(WHITE_BRUSH);

     wndclass.lpszMenüName = NULL;

     wndclass.lpszKlassenname = szAppName;

     //hInst = hInstanz;//Es ist nicht im Originalcode enthalten und es wird kein Fehler gemeldet.

     Wenn (!RegisterClass(&wndclass))

     {

          //LoadStringA(hInstance, IDS_APPNAME, (char *)szAppName,

          // Größe von (szAppName));

          ZeichenfolgeA laden(hInstanz, IDS_ERRMSG, (verkohlen *)szErrMsg,

               Größe von(szErrMsg));

          NachrichtenfeldA(NULL, (verkohlen *)szErrMsg,

               (verkohlen *)szAppName,

               MB_ICONERROR);

          zurückkehren 0;

     }

     hwnd = Fenster erstellen(szAppName, szBildunterschrift,

          WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,

          CW_USEDEFAULT, CW_USEDEFAULT,

          CW_USEDEFAULT, CW_USEDEFAULT,

          NULL, NULL, hInstanz, NULL);

     Schaufenster(hwnd, iCmdShow);

     Fenster aktualisieren(hwnd);

     während (Nachricht abrufen(&Nachricht, NULL, 0, 0))

     {

          Nachricht übersetzen(&Nachricht);

          Versandnachricht(&Nachricht);

     }

     zurückkehren Nachricht.wParam;

}

LRESULT RUF ZURÜCK WndProc ( HWND hwnd, UINT Nachricht, WPARAM wParam, LPARAM

lParam)

{

     //statisches Zeichen * pText;

     statisch LPCSTR pText;

     statisch HGLOBAL hRessource;//Ressourcenhandle – ein Handle, das auf einen Speicherblock zeigt

     statisch HWND hScrollenenenenenenenen;

     statisch int iPosition, cxChar, cyChar, cyClient,

          iAnzahlZeilen, xScrollenenenen;

     HDC hdc;

     LACKIERUNGSANLEITUNG ps;

     RECHTECK rechteck;

     TEXTMETRISCH tm;

     schalten (Nachricht)

     {

     Fall WM_CREATE:

          hdc = GetDC(hwnd);

          GetTextMetrics(hdc, &tm);

          cxChar = tm.tmAveCharWidth;

          cyChar = tm.tmHöhe + tm.tmExternalLeading;

          FreigabeDC(hwnd, hdc);

//Die Breite der vertikalen Bildlaufleiste in Pixel

          xScrollenenenen = Systemmetriken abrufen(SM_CXVSCROLL);

          //Bildlaufleiste generieren

          hScrollenenenenenenenen = Fenster erstellen(TEXT("Scrollleiste"), NULL,

               WS_CHILD | WS_VISIBLE | SBS_VERT,

               0, 0, 0, 0,

               hwnd, (HMENÜ)1, hInst, NULL);

          //Texthandle abrufen

          hRessource = Ressource laden(hInst,

               Ressourcensuche(hInst, TEXT("AnnabelLee"),//Stellen Sie sicher, dass es den angegebenen Typ und Namen hat

Der Speicherort der Ressource im angegebenen Modul

                    TEXT("TEXT")));

          //Rufen Sie einen Zeiger auf eine angegebene Ressource im Speicher ab

          pText = (LPCSTR)Ressource sperren(hRessource);

          iAnzahlZeilen = 0;//Lesen Sie die Anzahl der Textzeilen

          //Ermitteln Sie die Anzahl der Textzeilen

          während (*pText != '\' && *pText != '0')//Endet mit oder 0

          {

               Wenn (*pText == 'N')

                    iAnzahlZeilen++;

                //Gibt die nächste Position (Zeiger) im Ansi-String zurück, AnsiNext unter 16-Bit-Windows

//Als Makrodefinition verwendet Win32 stattdessen CharNext (AnsiNext kann nur Ansi-Zeichen verarbeiten).

//String; CharNext kann ein Ansi- oder Unicode-String sein)

                //pText = AnsiNext(pText);

               pText = (LPCSTR)CharWeiter((LPCWSTR)pText);

          }

     //*pText = '0';//Der ursprüngliche Code besagt hier, dass er mit einem Nullzeichen endet – der eigentliche Text endet nicht mit einem Nullzeichen.

          //Bildlaufleiste festlegen

          Scrollbereich festlegen(hScrollenenenenenenenen, SB_CTL, 0, iAnzahlZeilen, FALSCH);

          Scrollposition festlegen(hScrollenenenenenenenen, SB_CTL, 0, FALSCH);

          zurückkehren 0;

     Fall WM_SIZE:

          Fenster verschieben(hScrollenenenenenenenen, LOWORD(lParam) - xScrollenenenen, 0,

               xScrollenenenen, cyClient = HIWORD(lParam), WAHR);

          Fokus setzen(hwnd);//Fokus setzen

          zurückkehren 0;

     Fall WM_SETFOCUS:

          Fokus setzen(hScrollenenenenenenenen);//Erfassen Sie den Fokus des Bildlaufleisten-Schiebereglers

          zurückkehren 0;

     Fall WM_VSCROLL:

          schalten (LOWORD(wParam))  //LOWORD muss hinzugefügt werden, da sich der Benachrichtigungscode im Low-Word befindet

          {

          Fall SB_TOP:

               iPosition = 0;

               brechen;

          Fall SB_BOTTOM:

               iPosition = iAnzahlZeilen;

               brechen;

          Fall SB_LINEUP:

               iPosition -= 1;

               brechen;

          Fall SB_LINEDOWN:

               iPosition += 1;

               brechen;

          Fall SB_PAGEUP:

               iPosition -= cyClient / cyChar;

               brechen;

          Fall SB_PAGEDOWN:

               iPosition += cyClient / cyChar;

               brechen;

          Fall SB_THUMBTRACK:

               iPosition = HIWORD(wParam);

               brechen;

          }

          iPosition = max(0, Mindest(iPosition, iAnzahlZeilen));

          Wenn (iPosition != ScrollPos abrufen(hScrollenenenenenenenen, SB_CTL))

          {

               Scrollposition festlegen(hScrollenenenenenenenen, SB_CTL, iPosition, WAHR);

               InvalidateRect(hwnd, NULL, WAHR);

          }

          zurückkehren 0;

     Fall WM_PAINT:

          hdc = Malen beginnen(hwnd, &ps);

          pText = (verkohlen *)Ressource sperren(hRessource);

          GetClientRect(hwnd, &rechteck);

          rechteck.links += cxChar;//Anzeige ab Spalte 2

          rechteck.Spitze += cyChar * (1 - iPosition);

          // Beinhaltet die führende Höhe der äußeren Schriftlinie. Normalerweise werden äußere Zeilenüberschriften nicht in die Höhe einer Textzeile einbezogen.

          ZeichnenTextA(hdc, pText, -1, &rechteck, DT_EXTERNALLEADING);

          Endfarbe(hwnd, &ps);

          zurückkehren 0;

     Fall WM_DESTROY:

          Kostenlose Ressource(hRessource);

          PostQuitMessage(0);

          zurückkehren 0;

     }

     zurückkehren DefWindowProc(hwnd, Nachricht, wParam, lParam);

}

/******************************************************************************

Ladezeichenfolge Funktion: Lädt eine Zeichenfolgenressource und kopiert die Zeichenfolge dann in einen Puffer mit einem abschließenden Nullzeichen.

Oder geben Sie einen schreibgeschützten Zeiger auf die String-Ressource selbst zurück.

*******************************************************************************

Ressource laden Funktion: Ruft ein Handle ab, mit dem ein Zeiger auf das erste Byte der angegebenen Ressource im Speicher abgerufen werden kann

HGLOBAL Ressource laden(

HMODULE hModul,// Ein Handle für das Modul, dessen ausführbare Datei die Ressource enthält.Wenn hModule NULL ist, lädt das System die Ressource aus dem Modul, das zum Erstellen des aktuellen Prozesses verwendet wurde

HRSRC hResInfo//Das Handle für die zu ladende Ressource

);

*******************************************************************************

Ressourcen finden Funktion: Bestimmt den Speicherort einer Ressource des angegebenen Typs und Namens im angegebenen Modul

HRSRC FindResourceA(

HMODULE hModul,//Handle für das Modul, das die Ressource enthält

LPCSTR lpName,/Ressourcenname

LPCSTR lpTyp//Art der Ressource

);

*******************************************************************************

Ressource sperren Funktion: Rufen Sie einen Zeiger auf eine angegebene Ressource im Speicher ab

LPVOID Sperrressource(

HGLOBAL hResData//Das Handle für die Ressource, auf die zugegriffen werden soll

);

*******************************************************************************

AnsiWeiter Makrodefinition:

16Eine API-Funktion unter Windows (genauer gesagt eine Makrodefinition), die nur ANSI-Zeichenfolgen verarbeiten kann;

Später, als Win32 erschien, implementierte Microsoft aus Kompatibilitätsgründen die Kapselung über CharNext.

CharWeiterEs kann sich um eine Ansi- oder Unicode-Zeichenfolge handeln.

Diese Funktion gibt die nächste Position (Zeiger) im Ansi-String zurück.

*/

Ressource.hKopfdatei

//{{KEINE_ABHÄNGIGKEITEN}}

// Microsoft Visual C++ Generierte Include-Dateien.

// Zur Verwendung durch 057_POEPOEM.rc

//

#define IDS_APPNAME 1

#IDS_Caption 2 definieren

#IDS_CAPTION 3 definieren

#define IDS_ERRMSG 4

#define IDI_ICON1 1

#define IDC_CURSOR1 2

#define IDR_TEXT1 107

#define IDR_TEXT2 108

//Weitere Standardwerte für neue Objekte

//

#ifdef APSTUDIO_INVOKED

#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE 126

#define _APS_NEXT_COMMAND_VALUE 40002

#define _APS_NEXT_CONTROL_VALUE 1001

#define _APS_NEXT_SYMED_VALUE 101

#endif

#endif

057_POEPOEM.rcRessourcenskriptdateien enthalten 4 Arten von Ressourcen:

1 . Symbolressourcen:

// Symbol

//

IDI_ICON1 ICON "D:\code\windows5.0\A täglich

Praxis\057_POEPOEM\057_POEPOEM\icon1.ico"

2 . Mauszeiger-Bitmap-Ressource:

// Mauszeiger

//

IDC_CURSOR1 CURSOR "cursor1.cur"

3 . String-Ressourcentabelle:

// String-Tabelle

//

SAITENTABELLE

BEGINNEN

IDS_APPNAME "PoePoem"

IDS_CAPTION „Annabel Lee“ von Edgar Allan Poe

IDS_ERRMSG "Dieses Programm erfordert Windows NT!"

ENDE

4 . Benutzerdefinierte Ressourcen:

// TEXT

//

ANNABELLEE-TEXT "POEPOEM.TXT"

Operationsergebnis:

Abbildung 9-9 String-Ressourcentabelle und benutzerdefinierte Ressourcen

 

Zusammenfassen

Im Ressourcenskript POEPOEM.RC wird die benutzerdefinierte Ressource als TEXT-Typ angegeben und der Textname lautet „ANNABELLEE“: ANNABELLEE TEXT POEPOEM.TXT

Bei der Verarbeitung der WM_CREATE-Nachricht in WndProc wird das Handle der Ressource über FindResource und LoadResource abgerufen. LockResource sperrt die Ressource und eine kleine Routine ersetzt den abschließenden Backslash ( ) in der Datei durch 0. Dies soll die Verwendung der DrawText-Funktion in der nachfolgenden WM_PAINT-Nachricht erleichtern.

[Hinweis] Wir verwenden das Unterfenster-Bildlaufleisten-Steuerelement anstelle der Fenster-Bildlaufleiste. Die Bildlaufleistensteuerung des Unterfensters verfügt über eine automatische Tastaturschnittstelle, sodass die WM_KEYDOWN-Nachricht in POEPOEM nicht verarbeitet werden muss.

POEPOEM verwendet außerdem drei Zeichenfolgen, deren IDs in der Header-Datei RESOURCE.H definiert sind. Zu Beginn des Programms werden die Zeichenfolgen IDS_APPNAME und IDS_CAPTION von LoadString in den Speicher geladen:

LoadString (hlnstance, IDS_APPNAME, szAppName,

sizeof (szAppName) /sizeof (TCHAR));

LoadString (hlnstance, IDS_CAPTION, szCaption,

Größe von (szCaption) / Größe von (TCHAR));

[Hinweis] Diese beiden Aufrufe gehen RegisterClass voraus. Das Programm verwendet LoadStringA, um die Zeichenfolgen IDS_APPNAME und IDS_ERRMSG zu laden, und verwendet MessageBoxA, um ein benutzerdefiniertes Meldungsfeld anzuzeigen:

wenn (!RegisterClass (&wndclass))

{

LoadStringA (hInstance, IDS_APPNAME, (char *) szAppName,

Größe von (szAppName));

LoadStringA (hInstance, IDS_ERRMSG, (char *) szErrMsg,

Größe von (szErrMsg));

MessageBoxA (NULL, (char *) szErrMsg,

(char *) szAppName, MB_ICONERROR);

Rückgabe 0;

}

[Hinweis] Konvertierung von TCHAR-String-Variable in char-Zeiger erzwingen.

AnsiNext ist eine Makrodefinition unter 16-Bit-Windows, die stattdessen CharNext verwendet (AnsiNext kann nur Ansi-Strings verarbeiten; CharNext kann sowohl Ansi-Strings als auch Unicode-Strings verarbeiten).

pText = AnsiNext(pText);

Ersetzen mit:

pText = (LPCSTR)CharNext((LPCWSTR)pText);

Alle von POEPOEM verwendeten Zeichenfolgen sind als Ressourcen definiert, sodass das Programm von Übersetzern problemlos in nicht-englische Versionen konvertiert werden kann.