Windows API:UpdateLayeredWindow 返回值

3

我的程序中有一个分层窗口,它在视觉上似乎工作正常,但是UpdateLayeredWindow的返回值应该是一个非零值表示成功。在我的情况下,它是0,而GetLastError返回87,这是一个不正确的参数。请问我的设置是否有问题?以下是完整的函数,窗口样式为WS_EX_LAYERED|WS_EX_TOPMOSTWS_POPUP

bool SplashScreen(HWND hwnd, HINSTANCE m_hinstance)
{
    HBITMAP hBitmap = (HBITMAP)LoadImage(m_hinstance, "splash.bmp", IMAGE_BITMAP, 640, 640, LR_LOADFROMFILE);
    PAINTSTRUCT     ps;
    HDC             hdc;
    BITMAP          bitmap;
    HDC             hdcMem;
    HGDIOBJ         oldBitmap;
    int result=0;

    if(!SetLayeredWindowAttributes(hwnd, 0, (255 * 100) / 100, LWA_ALPHA))
    {
        char msg[255];
        sprintf(msg,"Error SetLayeredWindowAttributes: %d",GetLastError());
        MessageBox(hwnd,msg,"System",MB_OK);
        return false;
    }

    hdc = BeginPaint(hwnd, &ps);
    if(!hdc)
    {
        char msg[255];
        sprintf(msg,"Error BeginPaint: %d",GetLastError());
        MessageBox(hwnd,msg,"System",MB_OK);
        return false;
    }

    hdcMem = CreateCompatibleDC(hdc);
    if(!hdcMem)
    {
        char msg[255];
        sprintf(msg,"Error CreateCompatibleDC: %d",GetLastError());
        MessageBox(hwnd,msg,"System",MB_OK);
        return false;
    }

    oldBitmap = SelectObject(hdcMem, hBitmap);

    GetObject(hBitmap, sizeof(bitmap), &bitmap);
    result=BitBlt(hdc, 0, 0, 640, 640, hdcMem, 0, 0, SRCCOPY);
    if(result==0)
    {
        char msg[255];
        sprintf(msg,"Error BitBlt: %d",GetLastError());
        MessageBox(hwnd,msg,"System",MB_OK);
        return false;
    }

    BLENDFUNCTION blend = { 0 };
    blend.BlendOp = AC_SRC_OVER;
    blend.SourceConstantAlpha = 255;
    blend.AlphaFormat = AC_SRC_ALPHA;

    result=UpdateLayeredWindow(hwnd,GetDC(NULL),NULL,NULL,hdcMem,NULL, RGB(0,0,0),&blend, ULW_ALPHA);// Returns non-zero on success(!), in reality works when 0 is returned.
    if(result==0)
    {
        char msg[255];
        sprintf(msg,"Error UpdateLayeredWindow: %d",GetLastError());// Error UpdateLayeredWindow: 87
        MessageBox(hwnd,msg,"System",MB_OK);
        return false;
    }

    result=SetLayeredWindowAttributes(hwnd, RGB(255,255,255), 0, ULW_COLORKEY);
    if(result==0)
    {
        char msg[255];
        sprintf(msg,"Error SetLayeredWindowAttributes: %d",GetLastError());
        MessageBox(hwnd,msg,"System",MB_OK);
        return false;
    }

    result=EndPaint(hwnd, &ps);
    if(result==0)
    {
        char msg[255];
        sprintf(msg,"Error EndPaint: %d",GetLastError());
        MessageBox(hwnd,msg,"System",MB_OK);
        return false;
    }

    SelectObject(hdcMem, oldBitmap);
    DeleteDC(hdc);
    DeleteObject(hdcMem);
    return true;
}
1个回答

9
您正在同一HWND上调用SetLayeredWindowAttributes()和UpdateLayeredWindow()。这样做是行不通的,文档已经非常明确了:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms633540(v=vs.85).aspx

请注意,一旦为分层窗口调用了SetLayeredWindowAttributes,后续的UpdateLayeredWindow调用将失败,直到图层样式位被清除并重新设置。
不要同时使用SetLayeredWindowAttributes()和UpdateLayeredWindow()。它们是非常不同的方法。要么使用带有传统WM_PAINT绘图的SetLayeredWindowAttributes(),要么使用带有内存位图的UpdateLayeredWindow()。不要同时使用两者。根据您所展示的内容,您应该仅使用UpdateLayeredWindow()。它将设置一个位图作为窗口内容,并同时设置窗口的透明度/alpha。
并且不要在WM_PAINT处理程序之外使用Begin/EndPaint()。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接