技術共有

「Windows API の日常実践」9.1.5 カスタム リソース

2024-07-12

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

カスタム リソースは、アプリケーション固有のデータ、画像、オーディオ、バイナリ ファイルなどを保存するために Windows プログラムで使用されるリソースの種類です。開発者は、カスタム リソースを通じて、アプリケーションに必要なさまざまなリソース ファイルを一元管理および保存し、プログラム内で簡単にアクセスして使用できます。

カスタム リソースに関する重要なポイントをいくつか示します。

●カスタムリソースの種類:

1.カスタム リソースには、画像、音声、XML 構成ファイル、テキスト ファイルなど、アプリケーション固有のデータまたはファイルを使用できます。

2.カスタム リソースは、「MY_CUSTOM_RESOURCE」などのカスタム リソース タイプ識別子を使用して識別できます。

●カスタム リソースの作成と編集:

1.カスタム リソースは通常、アプリケーションのリソース ファイル (.rc) に含まれています。

2.カスタム リソースは、Visual Studio のリソース ビューなどのリソース エディターを使用して作成および編集できます。

3.リソース ファイルでは、各リソースの一意のリソース識別子と、対応するリソース ファイル パスを指定できます。

●カスタムリソースの参照と使用:

1.コード内でカスタム リソースを参照および使用する場合、リソース識別子を使用して、対応するリソースを読み込んだりアクセスしたりできます。

2.対応する API 関数 (LoadResource、FindResource、LockResource など) を使用して、カスタム リソースを読み込み、操作します。

3.カスタム リソースの種類に応じて、さまざまな API 関数 (たとえば、画像リソースは GDI 関数を使用し、オーディオ リソースは DirectSound 関数を使用できます) を使用してカスタム リソースを処理できます。

■以下は、カスタム リソースをロードして使用する方法を示すサンプル コード スニペットです。

#含む<Windows.h>

int メイン()

{

HINSTANCE hInstance = GetModuleHandle(NULL); // 現在のインスタンス ハンドルを取得します。

HRSRC hResource = FindResource(hInstance, MAKEINTRESOURCE(IDR_MY_RESOURCE), "MY_CUSTOM_RESOURCE"); // カスタム リソースを検索します。

HGLOBAL hResData = LoadResource(hInstance, hResource); // カスタム リソースをロードします。

LPVOID pData = LockResource(hResData); // カスタム リソースをロックします。

// カスタム リソースを使用します...

0を返します。

}

上記の例では、IDR_MY_RESOURCE はカスタム リソースの識別子であり、対応するリソース ファイルのパスがリソース ファイルに定義されています。 FindResource 関数を使用してカスタム リソースを検索し、次に LoadResource 関数を使用してカスタム リソースを読み込み、最後に LockResource 関数を使用してカスタム リソースをロックし、リソース データへのポインターを取得します。その後、リソースのタイプと要件に応じて、ポインター pData を後続の処理と操作に使用できます。

カスタム リソースがどのように使用されるかは、リソースの種類とアプリケーションのニーズによって異なることに注意することが重要です。開発者は、実際のニーズに基づいてカスタム リソースを処理するために、適切なリソース タイプと対応する API 関数を選択できます。

カスタム リソースは、アプリケーションに必要なさまざまなデータやファイルを均一に管理し、プログラム内で簡単にアクセスして使用できる柔軟なリソース管理方法を提供します。カスタム リソースを使用すると、アプリケーションをよりモジュール化し、保守しやすく、拡張しやすくすることができます。

       ■VSでカスタムリソースを追加する

1. リソースを追加する

2. 「カスタマイズ」をクリックし、リソースタイプ「テキスト」を入力します。

3. リソースをインポートし、text1.bin ファイルを自動的に生成します (リソース ID: IDR_TEXT1)

4. VS で、カスタム コンパイラにリソース ファイル名を直接入力し、ID を変更します。「外部リソースをロードできません。リソースがインポートされていないことが考えられます。」というエラー メッセージが表示されます。

5. リソース ビュー ボックスにリソースを追加します。

6. 外部リソース ファイルをインポートします。

7. リソース ファイル名と ID を入力します。ID 名には引用符で囲まれた文字列「ANNABELLEE」を入力する必要があることに注意してください。

8. 設定を保存するだけです。

 

もっと簡単な方法として、リソース ファイル POEPOEM.rc を直接変更する方法があります。 TEXT の下の行にリソースを追加するだけです。

      

9.1.6 演習 57: 文字列リソース テーブルとカスタム リソース

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

057 WIN32 API 毎日練習する

     例 57 POEPOEM.C: 文字列リソース テーブルとカスタム リソース

ロード文字列 関数

リソースの読み込み 関数

リソースの検索 関数

ロックリソース 関数

アンシネクスト マクロ定義

著作権 プログラマー

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

#含む <windows.h>

#含む 「リソース.h」

L結果 折り返し電話 ウィンドウプロシージャ (ハンド, 単位, WPARAM, パラメータ) ;

ヒント ヒント ;

整数 ウィナピ ウィンメイン (ヒント hインスタンス, ヒント h前のインスタンス,

 PSTR szコマンド行, 整数 iCmdShow)

{   //リソースファイル名、タイトル、エラーメッセージ

     チャー szAppName[16], キャプション[64], エラーメッセージ[64];

     ハンド ハンド;

     MSG メッセージ;

     WNDCLASS ウインドクラス;

     //文字列リソースをロードする

     ロード文字列(hインスタンス, IDS_アプリ名, szAppName,

          のサイズ(szAppName) / のサイズ(チャー));

     ロード文字列(hインスタンス, キャプション, キャプション,

          のサイズ(キャプション) / のサイズ(チャー));

     ウインドクラス.スタイル = CS_HREDRAW | CS_VREDRAW;

     ウインドクラス.lpfnWndProc = ウィンドウプロシージャ;

     ウインドクラス.cbClsExtra = 0;

     ウインドクラス.cbWndExtra = 0;

     ウインドクラス.hインスタンス = hインスタンス;

//アイコンを追加

     ウインドクラス.hアイコン = ロードアイコン(hインスタンス, リソースの作成(識別子));

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

//カスタムマウスポインター

     ウインドクラス.hカーソル = カーソルの読み込み(hインスタンス,リソースの作成(IDC_CURSOR1));

     ウインドクラス.hbr背景 = (HBRUSH)ストックオブジェクトの取得(ホワイトブラシ);

     ウインドクラス.lpszメニュー名 = ヌル;

     ウインドクラス.lpszクラス名 = szAppName;

     //hInst = hInstance;//これは元のコードにないため、エラーは報告されません。

     もし (!登録クラス(&ウインドクラス))

     {

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

          // sizeof(szAppName) ;

          ロード文字列A(hインスタンス, IDS_ERRMSG, (文字 *)エラーメッセージ,

               のサイズ(エラーメッセージ));

          メッセージボックスA(ヌル, (文字 *)エラーメッセージ,

               (文字 *)szAppName,

               MB_ICONエラー);

          戻る 0;

     }

     ハンド = ウィンドウの作成(szAppName, キャプション,

          WS_オーバーラップウィンドウ | WS_CLIPCHILDREN,

          CW_USEDEFAULT, CW_USEDEFAULT,

          CW_USEDEFAULT, CW_USEDEFAULT,

          ヌル, ヌル, hインスタンス, ヌル);

     ウィンドウを表示(ハンド, iCmdShow);

     更新ウィンドウ(ハンド);

     その間 (メッセージを取得(&メッセージ, ヌル, 0, 0))

     {

          メッセージを翻訳する(&メッセージ);

          ディスパッチメッセージ(&メッセージ);

     }

     戻る メッセージ.wパラメータ;

}

L結果 折り返し電話 ウィンドウプロシージャ ( ハンド ハンド, 単位 メッセージ, WPARAM wパラメータ, パラメータ

lパラメータ)

{

     //静的char * pText;

     静的 LPCSTR pテキスト;

     静的 Hグローバル hリソース;//リソースハンドル - メモリブロックを指すハンドル

     静的 ハンド hスクロール;

     静的 整数 アイポジション, cxChar, サイチャー, cyクライアント,

          行数, xスクロール;

     HDC ハード;

     ペイントストラクト 追伸;

     直角 長方形;

     テキストメトリック tm;

     スイッチ (メッセージ)

     {

     場合 WM_CREATE:

          ハード = DC を取得(ハンド);

          テキストメトリックを取得(ハード, &tm);

          cxChar = tm.tmAveCharWidth;

          サイチャー = tm.tm高さ + tm.tm外部リード;

          リリースDC(ハンド, ハード);

//垂直スクロールバーの幅(ピクセル単位)

          xスクロール = システムメトリックを取得する(SM_CXVSCROLL);

          //スクロールバーを生成する

          hスクロール = ウィンドウの作成(文章("スクロール・バー"), ヌル,

               WS_子供 | WS_VISIBLE | SBS_VERT,

               0, 0, 0, 0,

               ハンド, (Hメニュー)1, ヒント, ヌル);

          //テキストハンドルを取得する

          hリソース = リソースの読み込み(ヒント,

               リソースの検索(ヒント, 文章(「アナベル・リー」),//指定されたタイプと名前があることを確認してください

指定されたモジュール内のリソースの場所

                    文章("文章")));

          //メモリ内の指定されたリソースへのポインタを取得します

          pテキスト = (LPCSTR)ロックリソース(hリソース);

          行数 = 0;//テキストの行数を読み取る

          //テキストの行数を取得する

          その間 (*pテキスト != '\' && *pテキスト != '0')//または 0 で終わる

          {

               もし (*pテキスト == 'ん')

                    行数++;

                //ansi 文字列内の次の位置 (ポインター) を返します。16 ビット Windows では AnsiNext

//マクロ定義、Win32 は代​​わりに CharNext を使用します (AnsiNext は ansi 文字のみを処理できます)

//文字列; CharNext は、ANSI または Unicode 文字列にすることができます)

                //pText = AnsiNext(pText);

               pテキスト = (LPCSTR)CharNext((LPCWSTR)pテキスト);

          }

     //*pText = '0';//ここの元のコードは、ヌル文字で終わると述べていますが、実際のテキストはヌル文字で終わっていません。

          //スクロールバーを設定する

          スクロール範囲の設定(hスクロール, SB_CTL, 0, 行数, 間違い);

          スクロール位置の設定(hスクロール, SB_CTL, 0, 間違い);

          戻る 0;

     場合 WM_サイズ:

          ウィンドウの移動(hスクロール, ローワード(lパラメータ) - xスクロール, 0,

               xスクロール, cyクライアント = ハイワード(lパラメータ), 真実);

          フォーカスの設定(ハンド);//フォーカスを設定する

          戻る 0;

     場合 WM_SETFOCUS:

          フォーカスの設定(hスクロール);//スクロールバー スライダー フォーカスをキャプチャする

          戻る 0;

     場合 WM_VSCROLL:

          スイッチ (ローワード(wパラメータ))  //通知コードが下位ワードにあるため、LOWORD を追加する必要があります

          {

          場合 SB_トップ:

               アイポジション = 0;

               壊す;

          場合 SB_ボトム:

               アイポジション = 行数;

               壊す;

          場合 SB_ラインアップ:

               アイポジション -= 1;

               壊す;

          場合 SB_ラインダウン:

               アイポジション += 1;

               壊す;

          場合 SB_ページアップ:

               アイポジション -= cyクライアント / サイチャー;

               壊す;

          場合 SB_ページダウン:

               アイポジション += cyクライアント / サイチャー;

               壊す;

          場合 SB_サムトラック:

               アイポジション = ハイワード(wパラメータ);

               壊す;

          }

          アイポジション = 最大(0, (アイポジション, 行数));

          もし (アイポジション != スクロール位置を取得(hスクロール, SB_CTL))

          {

               スクロール位置の設定(hスクロール, SB_CTL, アイポジション, 真実);

               無効化矩形(ハンド, ヌル, 真実);

          }

          戻る 0;

     場合 WM_ペイント:

          ハード = ペイント開始(ハンド, &追伸);

          pテキスト = (文字 *)ロックリソース(hリソース);

          GetClientRect(ハンド, &長方形);

          長方形. += cxChar;//2列目から表示

          長方形. += サイチャー * (1 - アイポジション);

          //フォントの外側の行の先頭の高さを含みます。通常、外側の行ヘッダーはテキスト行の高さに含まれません。

          描画テキストA(ハード, pテキスト, -1, &長方形, DT_EXTERNALREADING 外部リード);

          エンドペイント(ハンド, &追伸);

          戻る 0;

     場合 WM_破棄:

          無料リソース(hリソース);

          終了メッセージ投稿(0);

          戻る 0;

     }

     戻る 定義ウィンドウプロセス(ハンド, メッセージ, wパラメータ, lパラメータ);

}

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

ロード文字列 機能: 文字列リソースをロードし、終端 null 文字を含む文字列をバッファにコピーします。

または、文字列リソース自体への読み取り専用ポインターを返します。

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

リソースの読み込み 機能: メモリ内の指定されたリソースの最初のバイトへのポインタを取得するために使用できるハンドルを取得します。

HGLOBAL LoadResource(

HMODULE hModule,//実行可能ファイルにリソースが含まれるモジュールへのハンドル。hModule が NULL の場合、システムは現在のプロセスの作成に使用されたモジュールからリソースをロードします。

HRSRC hResInfo//ロードするリソースのハンドル

);

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

リソースの検索 機能: 指定されたモジュール内の指定されたタイプおよび名前のリソースの場所を決定します。

HRSRC FindResourceA(

HMODULE hModule,//リソースを含むモジュールへのハンドル

LPCSTR lpName,//リソース名

LPCSTR lpType//リソースの種類

);

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

ロックリソース 機能: メモリ内の指定されたリソースへのポインタを取得します。

LPVOID ロックリソース(

HGLOBAL hResData//アクセスするリソースへのハンドル

);

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

アンシネクスト マクロ定義:

16ANSI 文字列のみを処理できる Windows 上の API 関数 (正確にはマクロ定義)。

その後、Win32 が登場すると、Microsoft は互換性を確保するために CharNext を通じてカプセル化を実装しました。

CharNextansi 文字列または Unicode 文字列を使用できます。

この関数は、ANSI 文字列内の次の位置 (ポインタ) を返します。

*/

リソース.hヘッドファイル

//{{依存関係なし}}

// マイクロソフトビジュアルC++ 生成されたインクルード ファイル。

// 057_POEPOEM.rc による使用用

//

#IDS_APPNAME 1 を定義します

#IDS_Caption 2 を定義します

#IDS_CAPTION 3 を定義します

#IDS_ERRMSG 4 を定義する

#IDI_ICON1 1 を定義します

#IDC_CURSOR1 2 を定義する

#IDR_TEXT1 107 を定義する

#IDR_TEXT2 108 を定義する

// 新しいオブジェクトの次のデフォルト値

//

#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

#終了

#終了

057_POEPOEM.rcリソース スクリプト ファイルには、次の 4 種類のリソースが含まれています。

1 .アイコンリソース:

// アイコン

//

IDI_ICON1 アイコン "D:\code\windows5.0\A 毎日

練習\057_POEPOEM\057_POEPOEM\icon1.ico"

2 .マウス ポインター ビットマップ リソース:

// カーソル

//

IDC_CURSOR1 カーソル "cursor1.cur"

3 .文字列リソーステーブル:

// 文字列テーブル

//

ストリングテーブル

始める

IDS_APPNAME「PoePoem」

IDS_CAPTION 「エドガー・アラン・ポー作『アナベル・リー』」

IDS_ERRMSG "このプログラムには Windows NT が必要です!"

終わり

4 .カスタムリソース:

// 文章

//

アナベリー テキスト "POEPOEM.TXT"

操作結果:

図 9-9 文字列リソーステーブルとカスタムリソース

 

要約する

POEPOEM.RC リソース スクリプトでは、ユーザー定義リソースは TEXT タイプとして指定され、テキスト名は「ANNABELLEE」です。 ANNABELLEE TEXT POEPOEM.TXT

WndProc で WM_CREATE メッセージを処理するとき、リソースのハンドルは FindResource と LoadResource を通じて取得されます。 LockResource はリソースをロックし、小さなルーチンがファイル内の末尾のバックスラッシュ ( ) を 0 に置き換えます。これは、後続の WM_PAINT メッセージでの DrawText 関数の使用を容易にするためです。

[注意] ウィンドウのスクロールバーではなく、サブウィンドウのスクロールバーコントロールを使用します。サブウィンドウのスクロール バー コントロールには自動キーボード インターフェイスがあるため、POEPOEM で WM_KEYDOWN メッセージを処理する必要はありません。

POEPOEM は 3 つの文字列も使用し、その ID は RESOURCE.H ヘッダー ファイルで定義されます。プログラムの先頭で、IDS_APPNAME 文字列と IDS_CAPTION 文字列が LoadString によってメモリにロードされます。

LoadString (hlnstance、IDS_APPNAME、szAppName、

sizeof (szAppName) /sizeof (TCHAR));

LoadString (hlnstance、IDS_CAPTION、szCaption、

sizeof (szCaption) /sizeof (TCHAR));

[注意] これら 2 つの呼び出しは RegisterClass よりも前に行われます。プログラムは、LoadStringA を使用して IDS_APPNAME 文字列と IDS_ERRMSG 文字列をロードし、MessageBoxA を使用してカスタム メッセージ ボックスを表示します。

if (!RegisterClass (&wndclass))

{

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

sizeof (szAppName)) ;

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

sizeof(szErrMsg)) ;

メッセージボックスA (NULL、(char *) szErrMsg、

(char *) szAppName、MB_ICONERROR) ;

0 を返します。

}

[注意] TCHAR文字列変数からcharポインタへ強制変換します。

AnsiNext は 16 ビット Windows 上のマクロ定義です。Win32 は代​​わりに CharNext を使用します (AnsiNext は ansi 文字列のみを処理できます。CharNext は ansi 文字列と Unicode 文字列の両方を処理できます)。

pText = AnsiNext(pText);

と置換する:

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

POEPOEM で使用されるすべての文字列はリソースとして定義されているため、翻訳者はプログラムを英語以外のバージョンに簡単に変換できます。