VCpp MinGW编译器将图片、字体等资源文件编译进程序和使用

⌚Time: 2023-12-21 12:02:53

👨‍💻Author: Jack Ge

Mingw使用附带的windres.exe可以将资源文件编译成.o文件, 之后与其他目标文件一起g++.exe链接生成程序

为了方便,使用mingw编译器版本的codeblock编写程序

用位图资源作为例子,新建一个空项目,在项目下新建一个资源文件,resource.rc,一个cpp文件main.cpp,一个头文件resource.h

会自动生成对应的虚拟目录

在resource.h文件里面定义一个资源ID,名字和(无符号整型)数值随便起


#define ID_FIRSTIMAGE 201

#define ID_ICO 101

...

在resource.rc文件里面定义资源ID对应的资源类型、所在路径。一定要包含resource.h文件,否则之后程序无法通过资源ID的定义找到资源


#include "resource.h"

ID_FIRSTIMAGE BITMAP "./res/cc0-0.bmp"

ID_ICO ICON "./res/ico.ico"

...

对于其他资源,如字体,光标也可以添加进去

rc文件里面定义的资源文件存在于项目目录下的res文件夹,所以把用到的资源放到相应的目录下。

main.cpp里面用到位图资源,使用LoadBitmap从程序中加载并画到窗口中。要包含resource.h


void draw_image(HDC hdc){



    HBITMAP hBitmap;

    BITMAP bitmap;

    //查找资源

    hBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_FIRSTIMAGE));

    GetObject(hBitmap, sizeof(bitmap), &bitmap);

    HDC hdcMem = CreateCompatibleDC(hdc);



    // 将位图选入内存设备上下文

    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBitmap);

    // 获取位图宽度和高度

    BITMAP bmpInfo;

    GetObject(hBitmap, sizeof(BITMAP), &bmpInfo);

    int bmpWidth = bmpInfo.bmWidth;

    int bmpHeight = bmpInfo.bmHeight;

    // 在屏幕上显示位图

    BitBlt(hdc, 0, 0, bmpWidth, bmpHeight, hdcMem, 0, 0, SRCCOPY);

    //释放资源

    SelectObject(hdcMem, hOldBitmap);

    DeleteDC(hdcMem);

    DeleteObject(hBitmap);

}

如果是其他的资源,使用的函数

|函数 |操作| 删除资源|

|-|-|-|

|FormatMessage |加载消息表条目并设置其格式。| 无需执行任何操作。|

|LoadAccelerators |加载加速键表。| DestroyAcceleratorTable|

|LoadBitmap |加载位图资源。| DeleteObject|

|LoadCursor |加载光标资源。| DestroyCursor|

|LoadIcon |加载图标资源。| DestroyIcon|

|LoadImage| 加载图标、光标或位图。 |DestroyIcon、 DestroyCursor、 DeleteObject|

|LoadMenu| 加载菜单资源。| DestroyMenu|

|LoadString |加载字符串表条目。| 无需执行任何操作。|

点击编译,codeblock会自动调用windres而无需手动使用windres编译资源文件了,相关的编译命令输出


windres.exe  -J rc -O coff -i C:\Users\jack\DOCUME~1\CODEBL~1\PicTop3\resource.rc -o obj\Debug\resource.res

g++ -o xx.exe obj\Debug\main.o  obj\Debug\resource.res -lgdi ...

运行就会显示出图

全部源代码

main.cpp




#include <windows.h>

#include <iostream>

#include "resource.h"

void draw_image(HDC hdc){



    HBITMAP hBitmap;

    BITMAP bitmap;

    //查找资源

    hBitmap = LoadBitmap(GetModuleHandle(NULL), MAKEINTRESOURCE(ID_FIRSTIMAGE));

    GetObject(hBitmap, sizeof(bitmap), &bitmap);

    HDC hdcMem = CreateCompatibleDC(hdc);



    // 将位图选入内存设备上下文

    HBITMAP hOldBitmap = (HBITMAP)SelectObject(hdcMem, hBitmap);

    // 获取位图宽度和高度

    BITMAP bmpInfo;

    GetObject(hBitmap, sizeof(BITMAP), &bmpInfo);

    int bmpWidth = bmpInfo.bmWidth;

    int bmpHeight = bmpInfo.bmHeight;

    // 在屏幕上显示位图

    BitBlt(hdc, 0, 0, bmpWidth, bmpHeight, hdcMem, 0, 0, SRCCOPY);

    //释放资源

    SelectObject(hdcMem, hOldBitmap);

    DeleteDC(hdcMem);

    DeleteObject(hBitmap);

}



//win32窗体建立

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow)

{

    // 注册窗体类

    const char CLASS_NAME[]  = "rrrr33";



    WNDCLASSA wc = { };



    wc.lpfnWndProc   = WindowProc;

    wc.hInstance     = hInstance;

    wc.lpszClassName = CLASS_NAME;



    RegisterClassA(&wc);



    //创建窗体

    HWND hwnd = CreateWindowExA(

        0,                              // Optional window styles.

        CLASS_NAME,                     // Window class

        "cccc",    // Window text

        WS_OVERLAPPEDWINDOW,            // Window style



        // Size and position

        CW_USEDEFAULT, CW_USEDEFAULT, 400, 400,



        NULL,       // Parent window

        NULL,       // Menu

        hInstance,  // Instance handle

        NULL        // Additional application data

        );



    if (hwnd == NULL)

    {

        return 0;

    }



    //显示窗口

    ShowWindow(hwnd, nCmdShow);





    //消息循环

    MSG msg = { };

    while (GetMessage(&msg, NULL, 0, 0) > 0)

    {

        TranslateMessage(&msg);

        DispatchMessage(&msg);

    }



    return 0;

}

//窗体过程函数

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)

{

    switch (uMsg)

    {

    case WM_DESTROY:

        PostQuitMessage(0);

        return 0;

    break;

    //窗体绘制事件

    case WM_PAINT:

        {

            PAINTSTRUCT ps;

            HDC hdc = BeginPaint(hwnd, &ps);

            //绘图

            draw_image(hdc);

            EndPaint(hwnd, &ps);

        }

        return 0;



    }

    return DefWindowProc(hwnd, uMsg, wParam, lParam);

}


resource.h




#define ID_FIRSTIMAGE 201


resource.rc


#include "resource.h"

ID_FIRSTIMAGE BITMAP "./res/cc0-0.bmp"