レガシー Windows API(概要)について

ここで紹介しているAPIは、Windows95、Windows NT3.5時代のAPI群であり、最新のAPIは含まれていないことに注しして欲しい。なお、当時の解説書は現在よりもより詳細に解説しているため、参考になるはずである。

  • レイアウトを変換する際、崩れているページがあります。
  • 概要およびSampleコードはありますが、APIの解説はありません。

ご要望があれば旧版のWin32 API(HELP形式)をお譲りします。問い合わせフォームより申し込みください。

Windows API リソースの概要

「リソース」とは、 リソース コンパイラなどがアプリケーションの実行可能ファイルに追加するバイナリ データです。リソースには、 標準のものと、 アプリケーション定義のものがあります。「標準リソース」のデータには、 アイコン、 カーソル、 メニュー、 ダイアログ ボックス、 ビットマップ、 フォント、 アクセラレータ テーブル、 メッセージ テーブル エントリ、 文字列 テーブル エントリ、 バージョンなどがあります。「アプリケーション定義リソース」(「カスタム リソース」) には、 特定のアプリケーションが必要とするデータがあります。

次に示すトピックでは、 Windowsのリソースについて説明しています。

  • リソースの検索とロード
  • リソースの追加、 削除、 置き換え
  • リソースの列挙
  • リソースの更新
  • リソース リストの作成
  • リソース関数

このトピックでは、 次に示す作業をアプリケーションが行うための関数について説明します。

  • モジュール内のリソースの検索
  • 実行可能ファイルへのリソースの追加、 削除、 置き換え
  • モジュールに含まれるリソースのリストの生成

 

実行可能ファイル内のリソース データの構成について詳しくは、 リソース形式のマニュアルを参照してください。

標準のリソースの作成方法については、 次の表に示すトピックを参照してください。

 

リソース トピック

ビットマップ ビットマップの概要

カーソル カーソルの概要

ダイアログ ボックス ダイアログ ボックスの概要

フォント フォントとテキストの概要

アクセラレータ テーブル キーボード アクセラレータの概要

アイコン アイコンの概要

メニュー メニューの概要

メッセージ テーブル エントリ メッセージ コンパイラのマニュアルを参照してください。

文字列テーブル エントリ 文字列操作とUnicodeの概要

バージョン情報 ファイル インストール ライブラリの概要

Microsoft(R) Windows(TM) 実行可能ファイルにリソース データを付加する方法については、 リソース コンパイラのマニュアルを参照してください。

リソースの検索とロード

アプリケーションは、 リソースを使う前に、 メモリにリソースをロードしなければなりません。FindResource関数とFindResourceEx関数は、 モジュール内でリソースを検索し、 バイナリのリソース データのハンドルを返します。FindResourceは、 リソースを種類と名前で識別します。FindResourceEx関数は、 リソースを種類、 名前、 言語で識別します。このトピックのFindResourceに関する記述は、 FindResourceExにも適用されます。

LoadResource関数は、 FindResourceが返したリソース ハンドルを使って、 リソースをメモリにロードします。アプリケーションがLoadResourceを使ってリソースをロードした後、 Windowsはメモリの状況やアプリケーションの実行に応じてリソースをアンロードしたり再ロードするため、 不要になったリソースをアプリケーションが明示的にアンロードする必要はありません。

任意の種類のリソースを検索してロードするにはFindResourceLoadResourceを使いますが、 これらの関数は、 その後の関数呼び出しでバイナリのリソース データにアクセスしなければならないときだけ使ってください。リソースをそのまま使うときは、 次に示すリソース固有関数を使って、 1回の呼び出しでリソースを検索、 ロードしてください。

 

関数 動作

FormatMessage メッセージ テーブル エントリをロードして書式化します。

LoadAccelerators アクセラレータ テーブルをロードします。

LoadBitmap ビットマップ リソースをロードします。

LoadCursor カーソル リソースをロードします。

LoadIcon アイコン リソースをロードします。

LoadMenu メニュー リソースをロードします。

LoadString 文字列テーブル エントリをロードします。

たとえば、 画面に表示するアイコンをロードするには、 LoadIcon関数を使います。しかし、 アイコンのデータをほかのアプリケーションにコピーするためにアイコンをロードするには、 FindResourceLoadResourceを使ってください。

アプリケーションは、 終了する前に、 次の表の関数を使って、 アクセラレータ テーブルやビットマップ、 カーソル、 アイコン、 メニューなどのメモリを解放してください。

 

リソース 解放関数

アクセラレータ テーブル DestroyAcceleratorTable

ビットマップ DeleteObject

カーソル DestroyCursor

アイコン DestroyIcon

メニュー DestroyMenu

上記以外の種類のリソースの場合、 アプリケーションが終了すると、 Windowsは自動的にメモリを解放します。

 

リソースの追加、 削除、 置き換え

アプリケーションは、 実行可能ファイルのリソースの追加、 削除、 置き換えを頻繁に行わなければなりません。このような作業を行うには、 2つの方法があります。1つは、 リソース定義ファイルを編集してリソースを再コンパイルし、 そのリソースをアプリケーションの実行可能ファイルに追加する方法です。もう1つは、 リソース データをアプリケーションの実行可能ファイルに直接コピーする方法です。

たとえば、 英語のアプリケーションをノルウェーで使うためにローカライズするには、 英語のダイアログ ボックスをノルウェー語に置き換えなければなりません。ダイアログ ボックスを作成するには、 ダイアログ ボックス エディタを使うか、 リソース定義ファイルでテンプレートを作成します。それから、 リソースをコンパイルして、 新しいリソースをアプリケーションの実行可能ファイルに追加します。

しかし、 適切なダイアログ ボックスがバイナリ形式で存在していれば、 3つのWindows関数を使って、 そのデータをローカライズする実行可能ファイルに直接コピーできます。BeginUpdateResource関数は、 リソースを変更する実行可能ファイルの更新ハンドルを作成します。UpdateResource関数は、 このハンドルを使って、 実行可能ファイルのリソースの追加、 削除、 置き換えを行います。EndUpdateResource関数は、 ハンドルをクローズします。

実行可能ファイルの更新ハンドルをBeginUpdateResourceで作成したら、 UpdateResourceを使って、 リソース データを変更します。UpdateResourceを呼び出すたびに、 追加、 削除、 置き換えを記録する内部リストが更新されますが、 データは実際には実行可能ファイルには書き込まれません。EndUpdateResourceは、 更新ハンドルをクローズする直前に、 蓄積された変更を実行可能ファイルに書き込みます。

場合によっては、 アプリケーションは、 リソースをコピーしたり、 リソースのサイズを調べなければならないことがあります。LoadLibrary関数は、 リソースをコピーする実行可能ファイルのモジュール ハンドルを取得します。また、 LockResource関数は、 指定されたモジュールのリソース データを指すポインタを取得します。SizeofResource関数は、 指定されたリソースのバイト単位のサイズを返します。

 

リソースの列挙

特定のモジュールのリソースの種類、 名前、 言語のリストを取得する関数は3つあります。EnumResourceTypes関数は、 モジュール内のリソースの種類のリストを取得します。EnumResourceNames関数は、 特定の種類の各リソースの名前を取得します。また、 EnumResourceLanguages関数は、 特定の名前と種類の各リソースの言語を取得します。これらの関数と、 対応するコールバック関数によって、 モジュール内のすべてのリソースのリストを作成できます。この処理については、 リソース リストの作成で説明します。

リソースの使用

ここでは、 Windowsのリソース関数を使って実行可能ファイルにリソースを追加し、 その実行可能ファイル内の全リソースのリストを作成する方法を説明します。

 

リソースの更新

次の例は、 次に示す手順で、 HAND.EXE実行可能ファイルのダイアログ ボックス リソースをFOOT.EXE実行可能ファイルにコピーします。

1. LoadLibrary関数で、 実行可能ファイルHAND.EXEをロードします。

2. FindResource関数とLoadResource関数で、 Ifという名前のダイアログ ボックス リソースをファイルから検索してロードします。

3. LockResource関数で、 ダイアログ ボックス リソース データを指すポインタを取得します。

4. BeginUpdateResource関数で、 FOOT.EXEの更新ハンドルを取得します。

5. UpdateResource関数で、 HAND.EXEのダイアログ ボックス プロシージャをFOOT.EXEにコピーします。

6. EndUpdateResource関数で更新を完了します。

次のコードは、 上記の手順を実現したものです。

HRSRC hResLoad; /* 
				handle to loaded resource */
HANDLE hExe; /* handle to existing .EXE file */
HRSRC hRes; /* handle/ptr. to res. info. in hExe */
HANDLE hUpdateRes; /* update resource handle */
char *lpResLock; /* pointer to resource data */
BOOL result;

/* Load the .EXE file that contains the dialog box you want to copy. */

hExe = LoadLibrary("hand.exe");

if (hExe == NULL) {
ErrorHandler("Could not load exe.");
}

/* Locate the dialog box resource in the .EXE file. */

hRes = FindResource(hExe, "AboutBox", RT_DIALOG);

if (hRes == NULL) {
ErrorHandler("Could not locate dialog box.");
}

/* Load the dialog box into global memory. */

hResLoad = LoadResource(hExe, hRes);

if (hResLoad == NULL) {
ErrorHandler("Could not load dialog box.");
}

/* Lock the dialog box into global memory. */

lpResLock = LockResource(hRes);

if (lpResLock == NULL) {
ErrorHandler("Could not lock dialog box.");
}

/* Open the file to which you want to add the dialog box resource. */

hUpdateRes = BeginUpdateResource("foot.exe", FALSE);

if (hUpdateRes == NULL) {
ErrorHandler("Could not open file for writing.");
}

/* Add the dialog box resource to the update list. */

result = UpdateResource(hUpdateRes, /* update resource handle */
RT_DIALOG, /* change dialog box resource */
"AboutBox", /* dialog box name */
MAKELANGID(LANG_NEUTRAL,
SUBLANG_NEUTRAL), /* neutral language ID */
lpResLock, /* ptr to resource info */
SizeofResource(hExe, hRes)); /* size of resource info. */

if (result == FALSE) {
ErrorHandler("Could not add resource.");
}

/* Write changes to FOOT.EXE and then close it. */

if (!EndUpdateResource(hUpdateRes, FALSE)) {
ErrorHandler("Could not write changes to file.");
}

/* Clean up. */

if (!FreeLibrary(hExe)) {
ErrorHandler("Could not free executable.");
}

 

 

 

リソース リストの作成

次の例は、 HAND.EXEファイルの全リソースのリストを作成します。また、 そのリストをRESINFO.TXTファイルに書き込みます。

このコードは、 実行可能ファイルのロードと、 リソース情報を書き込むファイルの作成を行います。また、 EnumResourceTypes関数を使って、 モジュール内の各リソースの種類を、 アプリケーション定義のコールバック関数であるEnumTypesFunc関数に送ります。このコールバック関数は、 さらに、 EnumResourceNames関数を使って、 特定の種類の各リソースの名前をアプリケーション定義のコールバック関数であるEnumNamesFunc関数に渡します。EnumNamesFuncは、 EnumResourceLanguages関数を使って、 特定の種類と名前の各リソースの言語をアプリケーション定義のEnumLangsFuncコールバック関数に渡します。EnumLangsFuncは、 特定の種類、 名前、 言語のリソースに関する情報をRESINFO.TXTファイルに書き込みます。

 

char szBuffer[80]; /* print buffer for EnumResourceTypes */
DWORD cbWritten; /* number of bytes written to res. info. file */
int cbString; /* length of string in sprintf */

/* Declare callback functions. */

BOOL EnumTypesFunc(
HANDLE hModule,
LPTSTR lpType,
LONG lParam);

BOOL EnumNamesFunc(
HANDLE hModule,
LPCTSTR lpType,
LPTSTR lpName,
LONG lParam);

BOOL EnumLangsFunc(
HANDLE hModule,
LPCTSTR lpType,
LPCTSTR lpName,
WORD wLang,
LONG lParam);

/* Load the .EXE whose resources you want to list. */

hExe = LoadLibrary("hand.exe");

if (hExe == NULL) {
ErrorHandler("Could not load .EXE.");
}

/* Create a file to contain the resource info. */

hFile = CreateFile("resinfo.txt", /* name of file */
GENERIC_READ | GENERIC_WRITE, /* access mode */
0, /* share mode */
(LPSECURITY_ATTRIBUTES) NULL, /* no security */
CREATE_ALWAYS, /* create flags */
FILE_ATTRIBUTE_NORMAL, /* file attributes */
(HANDLE) NULL); /* no template */
if (hFile == INVALID_HANDLE_VALUE) {
ErrorHandler("Could not open file.");
}

/* Find all of the loaded file's resources. */

cbString = sprintf(szBuffer,
"The file contains the following resources:\n\n");

WriteFile(hFile, /* file to hold resource info. */
szBuffer, /* what to write to the file */
(DWORD) cbString, /* number of bytes in szBuffer */
&cbWritten, /* number of bytes written */
NULL); /* no overlapped I/O */

EnumResourceTypes(hExe, /* module handle */
(ENUMRESTYPEPROC)EnumTypesFunc, /* callback function */
0); /* extra parameter */

/*
* Unload the executable file whose resources were
* enumerated and close the file created to contain
* the resource information.
*/

FreeLibrary(hExe);
CloseHandle(hFile);

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

FUNCTION: EnumTypesFunc(HANDLE, LPSTR, LONG)

PURPOSE: Resource type callback

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

BOOL EnumTypesFunc(
HANDLE hModule, /* module handle */
LPTSTR lpType, /* address of resource type */
LONG lParam) /* extra parameter, could be */
/* used for error checking */
{
int cbString;

/*
* Write the resource type to a resource information file.
* The type may be a string or an unsigned decimal
* integer, so test before printing.
*/

if ((ULONG)lpType & 0xFFFF0000) {
cbString = sprintf(szBuffer, "Type: %s\n", lpType);
}
else {
cbString = sprintf(szBuffer, "Type: %u\n", (USHORT)lpType);
}

WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);

/* Find the names of all resources of type lpType. */

EnumResourceNames(hModule,
lpType,
(ENUMRESNAMEPROC)EnumNamesFunc,
0);

return TRUE;
}


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

FUNCTION: EnumNamesFunc(HANDLE, LPSTR, LPSTR, LONG)

PURPOSE: Resource name callback

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

BOOL EnumNamesFunc(
HANDLE hModule, /* module handle */
LPCTSTR lpType, /* address of resource type */
LPTSTR lpName, /* address of resource name */
LONG lParam) /* extra parameter, could be */
/* used for error checking */
{
int cbString;

/*
* Write the resource name to a resource information file.
* The name may be a string or an unsigned decimal
* integer, so test before printing.
*/

if ((ULONG)lpName & 0xFFFF0000) {
cbString = sprintf(szBuffer, "\tName: %s\n", lpName);
}
else {
cbString = sprintf(szBuffer, "\tName: %u\n",
(USHORT)lpName);
}

WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);

/*
* Find the languages of all resources of type
* lpType and name lpName.
*/

EnumResourceLanguages(hModule,
lpType,
lpName,
(ENUMRESLANGPROC)EnumLangsFunc,
0);

return TRUE;
}


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

FUNCTION: EnumLangsFunc(HANDLE, LPSTR, LPSTR, WORD, LONG)

PURPOSE: Resource language callback

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


BOOL EnumLangsFunc(
HANDLE hModule, /* module handle */
LPCTSTR lpType, /* address of resource type */
LPCTSTR lpName, /* address of resource name */
WORD wLang, /* resource language */
LONG lParam) /* extra parameter, could be
used for error checking */
{
HANDLE hResInfo;
char szBuffer[80];
int cbString = 0;


hResInfo = FindResourceEx(hModule, lpType, lpName, wLang);

/* Write the resource language to the resource information file. */

cbString = sprintf(szBuffer, "\t\tLanguage: %u\n",
(USHORT)wLang);

WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);

/* Write the resource handle and size to buffer. */

cbString = sprintf(szBuffer,
"\t\thResInfo == %lx, Size == %lu\n\n",
hResInfo,
SizeofResource(hModule, hResInfo));

WriteFile(hFile, szBuffer, (DWORD) cbString,
&cbWritten, NULL);

return TRUE;

リソース関数

リソースに関する関数を次に示します。

  • BeginUpdateResource
  • EndUpdateResource
  • EnumResLangProc
  • EnumResNameProc
  • EnumResourceLanguages
  • EnumResourceNames
  • EnumResourceTypes
  • EnumResTypeProc
  • FindResource
  • FindResourceEx
  • LoadResource
  • LockResource
  • SizeofResource
  • UpdateResource

 

使われなくなったか、 または削除された関数

  • FreeResource
  • SetResourceHandler
  • UnlockResource

 

▲ページトップに戻る

【本を読んでもよくらからない】 … 個別指導でわかりやすくお教えします
inserted by FC2 system