c++ 为什么在Windows上显示透明窗口时 Flink ?

rdlzhqv9  于 2023-03-25  发布在  Windows
关注(0)|答案(2)|浏览(124)

我在CreateWindowEx()中设置了WS_OVERLAPPEDWINDOWWS_MAXIMIZEBOX,打开程序时有一瞬间不透明,大约0.5秒后显示透明窗口。
我在CreateWindowEx()中设置了WS_POPUP | WS_VISIBLE,打开程序后立即出现一个透明窗口
为什么会 Flink ,使用WS_OVERLAPPEDWINDOW如何避免这种现象?
对不起,我没有找到答案在谷歌和英语不是我的母语。
下面是我的代码:

#include <windows.h>

LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
        SetWindowLong(hWnd, GWL_EXSTYLE, GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);
        SetLayeredWindowAttributes(hWnd, NULL, 100, LWA_ALPHA);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, BOOL)
{
    WNDCLASS wc = {0};
    wc.lpszClassName = TEXT("wndclass");
    wc.hbrBackground = CreateSolidBrush(RGB(255, 99, 71));
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.lpfnWndProc = WinProc;
    RegisterClass(&wc);

    HWND hWnd = CreateWindow(wc.lpszClassName, TEXT("Window"), WS_MAXIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, 0, 0, hInstance, 0);
    if (hWnd == NULL)
        return 1;
    ShowWindow(hWnd, SW_SHOWNORMAL);

    MSG msg = {0};
    while (GetMessage(&msg, 0, 0, 0))
    {
        DispatchMessage(&msg);
    }

    return 0;
}

当一个程序打开时,窗口 Flink 。

当我点击标题按钮来最大化和最小化窗口时也是一样的。
我想使用WS_OVERLAPPEDWINDOW属性使主窗口立即透明,有什么办法吗?

liwlm1x9

liwlm1x91#

另一种选择是使用DwmEnableBlurBehindWindow。文档中有一个示例。

  • 从Windows 8开始,调用此函数不会导致模糊效果,这是由于窗口呈现方式的样式更改。* 因此它会呈现透明效果。

它也没有调整透明度,它的透明度效果不是那么好。

wnvonmuf

wnvonmuf2#

使用负边距值创建“玻璃片”时,它不会出现窗口 Flink 。https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmextendframeintoclientarea

然后我使用SetWindowRgn重新绘制指定的窗口区域。
添加以下代码,关闭分层窗口即可达到上述效果。

#include<dwmapi.h>
   #pragma comment(lib,"dwmapi.lib")
   ...
   ...
   static const MARGINS shadow_state{ -1 }; 
   DwmExtendFrameIntoClientArea(hWnd, &shadow_state);

   SetWindowRgn(hWnd, CreateRectRgn(0, 0, 800, 600), TRUE);// Specifies that the size of the redraw area matches CreateWindow.

但是,您不能像SetLayeredWindowAttributes那样设置透明度。

相关问题