Bra*_*don 2 c++ winapi embedded-resource
我有一个使用WinAPI创建的程序.在程序中,我将位图嵌入为资源,程序加载该资源并通过bitblt将其显示为背景图像.
下面,我创建了一个控制台程序来替换WinAPI程序中的背景.它成功替换了位图,但现在WinAPI程序不再显示背景.我知道替换工作,因为使用ResourceHacker,我可以点击资源,它显示它很好.
此屏幕截图显示已成功替换:

但是,如果我使用ResourceHacker将图像保存回磁盘,则无法使用任何编辑器预览或打开图像:

如果我使用resourcehacker替换WinAPI程序中的图像,它可以正常工作,程序将其显示为背景.
尽管如此,任何人都能解释下面我做错了什么吗?
//In my resource file of the WINAPI PROGRAM:
//IDI_ICON ICON "Resources/Icon.ico"
//IDB_BACKGROUND BITMAP DISCARDABLE "Resources/BackgroundImg.bmp"
#include <windows.h>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
bool Update(int ResourceID, std::string ModulePath, string FilePath)
{
HANDLE hResource = BeginUpdateResource(ModulePath.c_str(), false);
if (hResource != nullptr)
{
std::fstream File(FilePath.c_str(), std::ios::in | std::ios::binary);
if (File.is_open())
{
File.seekg(0, std::ios::end);
std::size_t FileSize = File.tellg();
File.seekg(0, std::ios::beg);
std::vector<std::uint8_t> Data(FileSize); //Also used a pointer.. makes no difference..
File.read(reinterpret_cast<char*>(Data.data()), FileSize);
File.close();
if (UpdateResource(hResource, RT_BITMAP, MAKEINTRESOURCE(ResourceID), MAKELANGID(0x0409, 0x1), Data.data(), FileSize))
{
EndUpdateResource(hResource, false);
return true;
}
}
}
return false;
}
int main()
{
if (Update(1001, "Module.exe", "Resources/BackgroundImg.bmp"))
{
std::cout<<"Updated Successfully";
}
else
{
std::cout<<"Failed To Update";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GAAHHH!我解决了!对于任何阅读的人来说,这都是答案..这是一篇关于微软支持的旧文章:http://support.microsoft.com/default.aspx? scid = kb%3ben- us%3b67883
现在,如果你不理解它:
它说,来自文件的位图和作为资源存储的位图之间的唯一区别是,一个是DIB,另一个是打包的DIB.这两者之间的区别在于,一个具有BITMAPFILEHEADER而另一个没有.资源存储时没有FileHeaders,因此必须将其删除.
因此,在更新位图资源时,必须删除BitmapFileHeader(注意下面的SizeOf偏移量):
bool UpdateBitmap(int ResourceID, std::string ModulePath, string FilePath)
{
HANDLE hResource = BeginUpdateResource(ModulePath.c_str(), false);
if (hResource != nullptr)
{
std::fstream File(FilePath.c_str(), std::ios::in | std::ios::binary);
if (File.is_open())
{
File.seekg(0, std::ios::end);
std::size_t FileSize = File.tellg();
File.seekg(0, std::ios::beg);
std::vector<std::uint8_t> Data(FileSize);
File.read(reinterpret_cast<char*>(Data.data()), FileSize);
File.close();
if (UpdateResource(hResource, RT_BITMAP, MAKEINTRESOURCE(ResourceID), MAKELANGID(0x0409, 0x1), Data.data() + sizeof(BITMAPFILEHEADER), FileSize - sizeof(BITMAPFILEHEADER))) //Notice the sizeof.
{
EndUpdateResource(hResource, false);
return true;
}
}
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
此代码与OP中的代码之间的唯一区别是sizeof(BITMAPFILEHEADER)的偏移量.