meideru blog

家電メーカーで働いているmeideruのブログです。主に技術系・ガジェット系の話を書いています。

【Windows API】リソース名はMAKEINTRESOURCEを使用しなければならない?

 

昨日と今日はWin32APIと格闘してました。大喧嘩です。疲れました(´;ω;`)

苦戦した理由は、リソース(ダイアログボックス)を使用するときに上手くいかなかったことです。

解決策も見つかりました。簡単に説明すると、リソース名を入力するときは、MAKEINTRESOURCEというマクロを使う必要があるようです。

meideru blogの読者の方の中にも、同じような内容で苦労している方がいるかもしれないので、今日の記事に詳しく書こうと思います。

目次

事の発端

事の発端は、ダイアログボックスを表示しようと思ったことです。

以下のようなソースを書きました。

// dialog01.cpp

#include <windows.h>
#include "resource.h"

BOOL CALLBACK MyDlgProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hCurInst, HINSTANCE hPrevInst,
	LPSTR lpsCmdLine, int nCmdShow)
{
	// ダイアログボックスを表示
	DialogBox(
		hCurInst,              // インスタンスハンドル
		TEXT("IDD_DIALOG1"),   // リソース名
		NULL,                  // 親ウィンドウハンドル
		(DLGPROC)MyDlgProc);   // プロシージャ名
	
	return 0;
}

// ダイアログプロシージャ
BOOL CALLBACK MyDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
{
	switch (msg) {
	case WM_COMMAND:
		switch (LOWORD(wp)) {
		case IDCANCEL:
			EndDialog(hDlg, IDCANCEL);
			return TRUE;
		case IDOK:
			EndDialog(hDlg, IDCANCEL);
			return TRUE;
		}
		return FALSE;
	}
	return FALSE;
}

 

リソースヘッダは以下のように記述しました。

#define IDD_DIALOG1                     101

 

リソースファイルは以下のように記述しました。

IDD_DIALOG1 DIALOGEX 0, 0, 309, 177
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,198,156,50,14
    PUSHBUTTON      "キャンセル",IDCANCEL,252,156,50,14
END

 

予定だと、以上のコードをコンパイルすると、ダイアログボックスが表示されるはずですが

実際にはそうはなりませんでした・・・。

 

問題点は、DialogBox関数の第二引数のTEXT(“IDD_DIALOG1”)にあります。デバッグによって発見しました。

MSDNでDialogBox関数を調べると以下のように書いてあります。

INT_PTR DialogBox(
  HINSTANCE hInstance,  // モジュールのハンドル
  LPCTSTR lpTemplate,   // ダイアログボックステンプレート
  HWND hWndParent,      // オーナーウィンドウのハンドル
  DLGPROC lpDialogFunc  // ダイアログボックスプロシージャ
);

第二引数はLPCTSTRですので、const char*と同じ意味です。引数としては、TEXT(“IDD_DIALOG1”)は正しいはずです。

しかし、正常に動作せず・・・。

解決策

実は、以前にも同じような問題に出くわしたことがありました。

それは、「【Win32API】リソースをバイナリで出力する方法」という記事に書いてあります。

【関連記事】
【Win32API】リソースをバイナリで出力する方法

そのときは、リソース名にMAKEINTRESOURCEというマクロを使用していました。なので、今回のケースにもそれを適用してみました。

具体的には、DialogBox関数の第二引数のTEXT(“IDD_DIALOG1”)をMAKEINTRESOURCE(IDD_DIALOG1)と入れ替えてみました。

 

すると・・・

上手く行きました!!!

しっかりとダイアログボックスが表示されました!!

原因は何だったのか

原因は、未だに不明です(・.・;)

ネットで調べてみたのですが、わかりませんでした。

LPCTSTR = const char* なので、TEXT(“リソース名”)で正しいと思うんですけどね・・・。

謎です。

 

なにか知っている方は是非教えて下さい!

 

ノシ

 - 技術系