C ++,GDI +,加载位图并使用UpdateLayeredWindow显示位图

时间:2016-10-10 13:18:57

标签: 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);
}

感谢您的帮助!

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:0)

感谢您的帮助,我自己找到了解决方案。我忘记了ShowWindow(hwnd,SW_SHOW);和 2。void DeleteSplashWindow(){ ReleaseDC(splashOwner, NULL); ShowWindow(splashOwner, NULL); }