2

WinAPI を使用して作成したプログラムがあります。プログラム内にビットマップをリソースとして埋め込むと、プログラムはそのリソースを読み込み、bitblt を介して背景画像として表示します。

以下に、WinAPI プログラムの背景を置き換えるコンソール プログラムを作成しました。ビットマップは正常に置き換えられますが、WinAPI プログラムは背景を表示しなくなりました。ResourceHacker を使用すると、リソースをクリックして問題なく表示できるため、置換が機能したことはわかっています。

このスクリーンショットは、正常に置き換えられたことを示しています。 ここに画像の説明を入力

ただし、ResourceHacker を使用して画像をディスクに保存すると、画像をプレビューしたり、エディターで開いたりすることができません。

ここに画像の説明を入力

WinAPI プログラム内で resourcehacker を使用して画像を置き換えると、問題なく動作し、プログラムはそれを背景として表示します。

以上のことを踏まえて、私が以下で間違ったことを誰か説明できますか?

//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;
}
4

1 に答える 1

6

ガーッ!解決しました!これは、Microsoft のサポートに関する古い KB 記事です: http://support.microsoft.com/default.aspx?scid=kb%3ben-us%3b67883

あなたがそれを理解していない場合:

ファイルからのビットマップとリソースとして保存されたビットマップの唯一の違いは、一方が DIB であり、もう一方がパックされた DIB であることです。これら 2 つの違いは、一方には 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;
}

このコードと OP のコードの唯一の違いは、sizeof(BITMAPFILEHEADER) によるオフセットです。

于 2013-03-02T19:29:18.390 に答える