1.win32程序中资源的使用
1.新建一个空的Win32程序 2.在VC6中新增资源
依次点击File -> New -> Resource Script
3.打开新创建的xxx.rc文件,在资源窗口新增一个对话框,并在对话框上新增2个按钮.
4.打开resource.h文件,观察变化:
#define IDD_DIALOG1 101 #define TEST1 1000 #define TEST2 1001
5.通过DialogBox创建对话框,将以下内容改为代码中对应的内容
INT_PTR DialogBox( HINSTANCE hInstance, // handle to module (句柄) LPCTSTR lpTemplate, // dialog box template(dialog模板) HWND hWndParent, // handle to owner window(父窗口句柄) DLGPROC lpDialogFunc // dialog box procedure(消息处理函数) );
6、定义Dialog消息处理函数
BOOL CALLBACK DialogProc( HWND hwndDlg, // handle to dialog box UINT uMsg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { switch(uMsg) { case WM_INITDIALOG : MessageBox(NULL,TEXT("WM_INITDIALOG"),TEXT("INIT"),MB_OK); return TRUE ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDC_BUTTON_OK : MessageBox(NULL,TEXT("IDC_BUTTON_OK"),TEXT("OK"),MB_OK); return TRUE; case IDC_BUTTON_OUT: MessageBox(NULL,TEXT("IDC_BUTTON_OUT"),TEXT("OUT"),MB_OK); EndDialog(hwndDlg, 0); return TRUE; } break ; } return FALSE ; }
7.最终代码如下
#include "test1.h" #include "resource.h" BOOL CALLBACK DialogProc( HWND hwndDlg, // handle to dialog box UINT uMsg, // message WPARAM wParam, // first message parameter LPARAM lParam // second message parameter ) { switch(uMsg) { case WM_INITDIALOG : MessageBox(NULL,TEXT("WM_INITDIALOG"),TEXT("INIT"),MB_OK); return TRUE ; case WM_COMMAND : switch (LOWORD (wParam)) { case TEST1 : MessageBox(NULL,TEXT("IDC_BUTTON_OK"),TEXT("OK"),MB_OK); return TRUE; case TEST2: MessageBox(NULL,TEXT("IDC_BUTTON_OUT"),TEXT("OUT"),MB_OK); EndDialog(hwndDlg, 0); return TRUE; } break ; } return FALSE ; } int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { DialogBox( hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DialogProc ); return 0; }
//{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by aaa.rc // #define IDD_DIALOG1 101 #define TEST1 1000 #define TEST2 1001 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1002 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif
2.资源表
资源表主要用于描述程序中资源(图标、背景音乐等)的相关信息。资源表位于数据目录项IMAGE_DIRECTORY_ENTRY_RESOURCE
的第三个。资源目录结构中的每一个节点都是由 IMAGE_RESOURCE_DIRECTORY
和后面紧跟的多个IMAGE_RESOURCE_DIRECTORY_ENTRY
组成的。资源表组织结构示意图如下:
2.1 IMAGE_RESOURCE_DIRECTORY结构
typedef struct _IMAGE_RESOURCE_DIRECTORY { DWORD Characteristics; //资源属性 保留 0 DWORD TimeDateStamp; //资源创建的时间 WORD MajorVersion; //资源版本号 未使用 0 WORD MinorVersion; //资源版本号 未使用 0 WORD NumberOfNamedEntries; //以名称命名的资源数量 WORD NumberOfIdEntries; //以ID命名的资源数量 // IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; } IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
2.2 IMAGE_RESOURCE_DIRECTORY_ENTRY结构
2.2.1 结构定义
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { union { //目录项的名称、或者ID struct { DWORD NameOffset:31; DWORD NameIsString:1; }; DWORD Name; WORD Id; }; union { DWORD OffsetToData; //目录项指针 struct { DWORD OffsetToDirectory:31; DWORD DataIsDirectory:1; }; }; } IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
2.2.2 Name含义说明
注:
- 1.当最高位是1时,低31位是一个UNICODE指针,指向一个结构
typedef struct _IMAGE_RESOURCE_DIR_STRING_U { WORD Length; WCHAR NameString[ 1 ]; } IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;
- 2.当最高位是0时,表示字段的值作为 ID 使用
2.2.3 OffsetToData的含义
最高位如果为1,低31位 + 资源地址 == 下一层目录节点的起始位置
- 第一层、第二层全为1.
- 最高位如果为0,指向 IMAGE_RESOURCE_DATA_ENTRY
- 第三层为0