二进制入门学习笔记-11.win32应用资源

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