SetLayeredWindowAttributes无法在Windows 8+(C ++)上运行

时间:2017-08-31 00:32:37

标签: c++ windows winapi

我正在编写一个库,使窗口客户区中的颜色不可见。

在应用程序的一半,我首先调用window_fix_transparent_color()来使窗口分层。然后我使用window_set_transparent_color()使客户区中的颜色不可见。

这是我的图书馆代码:

#define _WIN32_WINNT 0x0501
#include <windows.h>

extern "C"
{
    void window_fix_transparent_color(double window_handle)
    {
        // sets the window flags to support RGB color transparency.
        SetWindowLong((HWND)(DWORD)window_handle,GWL_EXSTYLE,
            GetWindowLong((HWND)(DWORD)window_handle,GWL_EXSTYLE)|WS_EX_LAYERED);
    }

    void window_set_transparent_color(double window_handle,double red,double green,double blue)
    {
        // sets the RGB color to be transparent for the specified window.
        SetLayeredWindowAttributes((HWND)(DWORD)window_handle,RGB(red,green,blue),255,LWA_COLORKEY);
    }
}

我正在使用与最新的Code :: Blocks一起打包的MinGW版本作为我的编译器。它适用于Windows 7,但不适用于Windows 8,8.1或10 ......

为什么会有这样的想法?此外,一个值得注意的奇怪的事情 - 它曾经在Windows 8 / 8.1 / 10上工作,这让我相信这些平台的某些Windows更新可能会破坏我的代码。自从它停止在Windows 7以后的平台上工作以来,我没有对我的代码进行任何更改。

谢谢!

2 个答案:

答案 0 :(得分:2)

为什么你使用奇怪的类型和演员表?您绝不应该将句柄类型转换为DWORD,如果必须,请使用INT_PTRUINT_PTRdouble实际上比32位应用程序中的HWND大,所以除了让自己更难以实现之外,你实际上也在浪费空间。 double不能用于在64位应用程序中存储句柄!

您也没有检查SetLayeredWindowAttributes的返回值,因此无法确定问题究竟是什么。

使用正确的类型和错误处理重写该函数:

void display_error(DWORD error)
{
    char buf[100];
    wsprintfA(buf, "Error %u!", error);
    MessageBoxA(NULL, buf, 0, 0); // Ideally you would pass a window handle here but I don't know if your handle is actually valid
}

void window_fix_transparent_color(HWND window_handle)
{
    DWORD error;

    // get the window flags to see if RGB color transparency is supported.
    SetLastError(0);
    LONG_PTR ExStyle = GetWindowLongPtr(window_handle, GWL_EXSTYLE);
    if (ExStyle == 0)
    {
        error = GetLastError();
        if (error != 0)
        {
            display_error(error);
            return;
        }
    }

    if ((ExStyle & WS_EX_LAYERED) == 0)
    {
        // set the window flags to support RGB color transparency.
        SetLastError(0);
        if (!SetWindowLongPtr(window_handle, GWL_EXSTYLE, ExStyle | WS_EX_LAYERED))
        {
            error = GetLastError();
            if (error != 0)
                display_error(error);
        }
    }
}

void window_set_transparent_color(HWND window_handle, BYTE red, BYTE green, BYTE blue)
{
    // sets the RGB color to be transparent for the specified window.
    if (!SetLayeredWindowAttributes(window_handle, RGB(red, green, blue), 255, LWA_COLORKEY))
    {
        display_error(GetLastError());
    }
}

...

HWND mywindow = CreateWindowEx(...);
window_fix_transparent_color(mywindow);
window_set_transparent_color(mywindow, ...);

答案 1 :(得分:1)

我的猜测是你在Windows 7上使用“基本”或“经典”主题。虽然 未记录,它激活桌面窗口的Windows XP兼容模式 经理,并改变分层窗口的工作方式。这不会在以后发生 Windows版本。