C++、GDI+、Load Bitmap并使用UpdateLayeredWindow显示Bitmap

标签 c++ windows

社区,我有一个小问题,需要帮助。 我想加载位图并用 UpdatelayerDWindow 显示它。我写了下面的源代码。但是什么也没有出现。 当我使用 BitBlt 函数时,图片出现了。 我的源代码中哪里有错误?

ATOM SplashRegisterClass(HINSTANCE hInstance) {
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = NULL;
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = NULL;
    wcex.lpszClassName = szWindowClass;
    wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    return RegisterClassEx(&wcex);
}

void ShowBitMap(HWND hwnd, HINSTANCE hInstance) {
    int nuXPos = 0;
    int nuYPos = 0;
    int width = 0;
    int height = 0;
    BITMAP bm;

    hbmpSplash = (HBITMAP)::LoadImage(hInstance, L"software.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
    if (hbmpSplash == NULL)
    {
        ::MessageBox(NULL, __T("Image not Found"), __T("Error"), MB_OK);
    }

    GetObject(hbmpSplash, sizeof(bm), &bm);
    SIZE size = { bm.bmHeight, bm.bmWidth };
    width = bm.bmWidth;
    height = bm.bmHeight;

    POINT ptZero = { 0 };
    HMONITOR hmonPrimary = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);
    MONITORINFO monitorinfo = { 0 };
    monitorinfo.cbSize = sizeof(monitorinfo);
    GetMonitorInfo(hmonPrimary, &monitorinfo);

    const RECT & rcWork = monitorinfo.rcWork;

    nuXPos = rcWork.left + (rcWork.right - rcWork.left) / 2;
    nuYPos = rcWork.top + (rcWork.bottom - rcWork.top) / 2;

    nuXPos = nuXPos - (175 / 2);
    nuYPos = nuYPos - (170 / 2);

    HDC hdcScreen = GetDC(NULL);
    HDC hdcneu = CreateCompatibleDC(hdcScreen);
    HDC hdcMem = CreateCompatibleDC(hdcScreen);
    HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcMem, hbmpSplash);

    POINT position = { nuXPos, nuYPos };

    BLENDFUNCTION blend = { 0 };
    blend.BlendOp = AC_SRC_OVER;
    blend.SourceConstantAlpha = 255;
    blend.AlphaFormat = AC_SRC_ALPHA;
    //Next line only for test!
    //::BitBlt(hdcScreen, nuXPos, nuYPos, width, height, hdcMem, 0, 0, SRCCOPY);

    //Show the Bitmap
    if (!UpdateLayeredWindow(splashOwner, hdcScreen, &position, &size, hdcMem, NULL, RGB(0, 0, 0), &blend, ULW_ALPHA))
    {
        //int LastError = GetLastError();
    }

    SelectObject(hdcMem, hbmpOld);
    DeleteDC(hdcMem);
    ReleaseDC(NULL, hdcScreen);
}

HWND CreateSplashWindow(HINSTANCE hInstance, int nCmdShow) {
    SplashRegisterClass(hInstance);

    splashOwner = CreateWindow(szWindowClass, NULL, WS_POPUP, 0, 0, 100, 100, NULL, NULL, hInstance, NULL);
    if (!splashOwner)
    {
        ::MessageBox(NULL, __T("Error"), __T("Error"), MB_OK);
    }

    ShowBitMap(splashOwner, hInstance);

    return CreateWindowEx(WS_EX_LAYERED, szWindowClass, 0, WS_POPUP, 0, 0, 100, 100, splashOwner, NULL, hInstance, NULL);
}

我想在主程序运行时删除所有内容。我可以用这个功能制作吗?

void DeleteSplashWindow(){
    ReleaseDC(splashOwner, 0);
}

感谢您的帮助!

最佳答案

hbmpSplash = (HBITMAP)::LoadImage(hInstance, L"software.bmp",
    IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

这个函数失败了,应该会报错。改成

hbmpSplash = (HBITMAP)::LoadImage(0, L"software.bmp",
    IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);

创建分层窗口时,必须调用 SetLayeredWindowAttributes。示例

HWND CreateSplashWindow(HINSTANCE hInstance, int nCmdShow) {
    ...
    HWND hwnd = CreateWindowEx(WS_EX_LAYERED, szWindowClass, 
            0, WS_POPUP, 0, 0, 100, 100, 
            splashOwner, NULL, hInstance, NULL);

    SetLayeredWindowAttributes(hwnd, transparentColor, alpha, LWA_COLORKEY | LWA_ALPHA);
    return hwnd;
}

关于C++、GDI+、Load Bitmap并使用UpdateLayeredWindow显示Bitmap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39959268/

相关文章:

c++ - 一个很好的、简单的、可移植的解决方案,用于在 C++ 中等待直到按下输入

c++ - 即使 glfwInit() 返回 1,也无法让 GLFW 工作

c++ - Python 依赖,windows (CMake)

c - 即使以管理员身份运行,打开 $MFT 文件也会导致访问被拒绝

windows - CMD 多个条目复制到一个txt文件

windows - 批处理 : Dynamic variable name (eval equivalent)

c++ - 文件处理 C++ 时出错

c++ - 向后的 cpp 无法再构建,尽管链接但仍缺少 lbdf

windows - 如何将 SHCreateItemFromParsingName 与 shell 命名空间中的名称一起使用?

windows - Very Sleepy 在捕获 MinGW 编译文件时看不到函数名称