リソーススクリプト(ResourceScript)





Resource 文のつくりかた


SYNTAX (u16 | string) ICON file nameID ICON filename DESC resource とは 実行ファイルに埋め込まれたデータ 種類としては 文字列 | Bitmap画像 | ボタン, アイコン, サウンド 作成するには resource script を利用する POINT リソースのメリット
[.] Data(見た目) と Program(ロジック) の記述を分離できるので, 変更はリソーススクリプトのコンパイルだけでよくなる [.] 見た目の編集を Program 内に記述しなくてよくなる [.] ファイルをバイナリの中に埋め込みたいときに使う( 見せたくないとき ) [.] Program 本体と独立しているため再利用できる。 [.] 多言語対応をする時に文字リソースだけを言語ごとに変更するだけですむ。



リソーススクリプトのかきかた


テキスト文なので、適当なエディターで以下の構文で利用したいGUI部品を定義する。
// id : 固有の適当な数値 // GUI : リソースの種類 // param : リソースの設定情報 id GUI param
ICON を "test.ico" というファイルから ID_ICON_0 という名前で作成する。
ID_ICON_0 ICON DISCARDABLE "test.ico"
id はソースコードからも参照するため, resource.h などで定義して共有しておく。 数値、または文字列で固有の値をつけておく。
// resource.h # define ID_ICON_0 1001 # include resource.h ID_ICON_0 ICON DISCARDABLE "test.ico"
ソースコードでは id からリソースを検索して読み込む
winc.hIcon = LoadIcon(hInst , "ID_ICON_0" ); winc.hIcon = LoadIcon( hInst , MAKEINTRESOURCE( IDI_ICON ) );
// u16 -> string cast( 型変換 ) // #define MAKEINTRESOURCE(i) (LPTSTR) ( (DWORD)( (WORD)(i) ) ) MyICON : 識別文字列( "" 必要なし, cmp が自動認識 ) resource script は resource compiler で コンパイルされる ( static な Text がバイナリに埋め込まれているのと同じ ) ICON を埋め込む( ICON 文を使用する )
ICON : ICON 文 DISCARDABLE : icon 破棄可能であることを windows に通知 ( Dialog なら 未使用なら Memory 上から破棄する )



リソースをコンパイルして実行ファイルに埋め込む


rc.exe を利用してリソーススクリプトをコンパイルしてバイナリを作成。
$vc/VC/bin/rc.exe /out:"test.res" test.rc
後は Objectファイルと同じように link.exe に渡すだけで完了。
link main.obj test.res user32.lib gdi32.lib
// ID の指定は 文字列でもよい。 "xxx" ["] を忘れずに ----------------- ID | IDC_1 ----------------- ----------------- ID | "MyMenu" -----------------


リソースの種類


// Menu ID_MENU_0 MENU Window と BIND wcex.lpszMenuName = MAKEINTRESOURCE(IDC_D); // Dialog DIALOG 文記述. || ( RE > RMB > Dialog を挿入 ) DialogBox( ID_DLG ); で作成 // BITMAP // LoadImage( ID_BMP_0 ); で指定する ID_BMP_0 BITMAP "d:/test.bmp"



Dialog(DialogBox)


SAMPLE https://www.dropbox.com/s/9mvqyavvof73e6t/httpclient_gui.exe( HTTP クライアント GUI ) SYNTAX id DIALOG x, y, w, h [optional-statements] { control-statement . . . }
# include<window.h> // x, y は ClientArea の場所 ID_DIALOG DIALOG 0, 0, 100, 100 // OPTION STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU CAPTION "タイトル" // Font FONT 9, "MS UI Gothic" // ダイアログ上に配置する子コントロール { // デフォルトボタン DEFPUSHBUTTON "ボタンを押す", 101, 10, 10, 100, 20 // 属性つき DEFPUSHBUTTON "ボタンを押す", 101, 10, 10, 100, 20, WS_GROUP // スタティック文字列 LTEXT "文字" IDC_STATIC 0 0 200 107 // エディットボックス( 数字キーのみ ) EDITTEXT ID_EDIT, 95, 56, 30, 11, ES_NUMBER }



DialogBox


SYNTAX int DialogBox( HINSTANCE hInstance , LPCTSTR lpTemplate , // ダイアログリソースの ID HWND hWnd , // 親ウィンドウのハンドル DLGPROC lpDialogFunc // ダイアログのプロシージャ ); RET -1 : FAIL nResult : EndDialog() がかえす値 DESC モーダルダイアログを作成する。 Modeless なら CreateDialog() メッセージループを Windows が行うため DialogBox() の呼び出しだけになる。
int main() { HANDLE hInst = GetModuleHandle( NULL ); DialogBox( hInst, MAKEINTRESOURCE( IDD_1 ), HWND_DESKTOP, DlgProc ); return 0; }
ダイアログに送られるメッセージを処理するハンドラを用意する。 自分でメッセージを処理したときは TRUE 処理をしない( 無視する )ときは FALSE を返す。
BOOL CALLBACK DlgProc( HWND hWnd , UINT msg , WPARAM wp , LPARAM lp ) { switch ( msg ) { // ボタンがおされたらダイアログを終了 case WM_COMMAND: if ( wp == ID_BUTTON_CLOSE ) { EndDialog( hWnd, 0 ); return TRUE; } break; default: break; } return FALSE; }
POINT 初期化のタイミングは WM_INITDIALOG でする。WM_CREATE に相当する。 ダイアログ上のコントロールへの参照は GetDlgItem() でとっておく。
case WM_INITDIALOG: { HWND hEdit = GetDlgItem( hWnd, ID_EDIT_0 ); SetWindowText( hEdit, "www.google.com" ); break; }
WARNING BAD return DefWindowProc(); すると正しく動作しない OD return 0; Dialog 内の Control の値を取得 | Set する // この window の この Control の値を 符号つきでくれ GetDlgItemInt( hDlg, IDC_ANGLE, &ret, TRUE ); SetDlgItemInt( hDlg, IDC_ANGLE, val, TRUE );


EndDialog


SYNTAX BOOL EndDialog( HWND hDlg, // 破棄するダイアログのウィンドウハンドルを指定 int nResult // DialogBox() 関数の戻り値を指定 ); DESC Modal Dialog を終了する RET !0 : OK 0 : FAIL


GetModuleHandle


SYNTAX HANDLE GetModuleHandle( LPCTSTR lpModuleName // モジュール名 ) DESC 指定したモジュール名のハンドルを取得する。 モジュール名( 実行ファイル, DLL )の指定はファイル名、パスで指定する。
GetModuleHandle( "test.dll" ); GetModuleHandle( "test.exe" ); // パスは \ 区切りらしい GetModuleHandle( "d:\test.exe" );
NULL を指定すると、現在のプロセスの作成に使われたファイルハンドルが返る。
HANDLE hInst = GetModuleHandle( NULL );



GetDlgItem


SYNTAX HWND GetDlgItem( HWND hDlg, // ダイアログボックスのハンドル int nIDDlgItem // コントロールの識別子 ); DESC ダイアログ上の配置したコントロールのハンドルを取得する。 ダイアログリソーススクリプトで指定した ID から参照をとる。
HWND hEdit = GetDlgItem( hWnd, ID_EDIT_0 );



Dialog コントロール


desc Dialog に文字を表示するには, resource 文を利用する POINT menu 項目の更新は Windows によって再描画されるまでは, 更新されない -> BOOL DrawMenuBar(HWND hWnd); DeleteMenu( GetMenu(hwnd) , LOWORD(wp), MF_BYCOMMAND); // 選択した menu を消去 DrawMenuBar(hwnd);