Mingw使用附带的windres.exe可以将资源文件编译成.o文件, 之后与其他目标文件一起g++.exe链接生成程序
为了方便,使用mingw编译器版本的codeblock编写程序
用位图资源作为例子,新建一个空项目,在项目下新建一个资源文件,resource.rc,一个cpp文件main.cpp,一个头文件resource.h
会自动生成对应的虚拟目录

在resource.h文件里面定义一个资源ID,名字和(无符号整型)数值随便起
在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
resource.rc
#include "resource.h"
ID_FIRSTIMAGE BITMAP "./res/cc0-0.bmp"