繁体   English   中英

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

[英]C++, GDI+, Load Bitmap and use UpdateLayeredWindow to show Bitmap

社区,我有一个小问题,我需要帮助。 我想加载一个位图,并希望用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;
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM