如何在子控件上使用 WS_EX_LAYERED [英] How to use WS_EX_LAYERED on child controls

查看:52
本文介绍了如何在子控件上使用 WS_EX_LAYERED的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从 Windows 8 开始,WS_EX_LAYERED 可用于子控件,(MSDN 上如是说)但是我一直无法让它工作.在下面的代码中,我试图使子控件半透明,但是当在控件上使用 WS_EX_LAYERED 时,什么都不绘制.

Since windows 8, WS_EX_LAYERED is available to use on child controls, (so says MSDN) However I've been unable to make it work. In the following code, I'm trying to make a child control semi transparent but when WS_EX_LAYERED is used on the control, nothing draws.

int APIENTRY wWinMain(_In_ HINSTANCE hInst, _In_opt_ HINSTANCE hPrevInst, _In_ LPWSTR lpCmdLine, _In_ int nCmdShow)
{
    WNDCLASSEX wc = {};

    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WndProc;
    wc.hInstance = hInst;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszClassName = _T("main");
    wc.hCursor = LoadCursor(0, IDC_ARROW);
    RegisterClassEx(&wc);

    HWND MWhwnd = CreateWindowEx(NULL, _T("main"), _T(""),
       WS_OVERLAPPEDWINDOW| WS_CLIPCHILDREN,
       CW_USEDEFAULT, 0, CW_USEDEFAULT,0, NULL, NULL, hInst, NULL);

    wc.lpfnWndProc = WndProcPanel;
    wc.lpszClassName = _T("CPanel");
    wc.style = NULL;
    RegisterClassEx(&wc);

    HWND Panelhwnd = CreateWindowEx(WS_EX_LAYERED, _T("CPanel"), _T(""), 
       WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS| WS_CLIPCHILDREN,
       100, 10, 400, 400, MWhwnd, NULL, hInst, NULL);

    COLORREF crefKey = RGB(0, 255, 0);
    SetLayeredWindowAttributes(Panelhwnd, crefKey, 155, LWA_ALPHA);

    ShowWindow(MWhwnd, nCmdShow);   

在本例中,我使用的是自定义控件,但我尝试使用 WC_BUTTON 获得相同的结果.控件无法绘制.但是我可以毫无问题地使主窗口透明.

In this example, I'm using a custom control but I've tried with a WC_BUTTON with same result. The control fails to draw. But I can make the main window transparent without a problem.

使用 WINDOWS 10 和 VS2015 以及普通的 win32(无 MFC、ATL 等)

Using WINDOWS 10 and VS2015 and plain win32 (no MFC, ATL etc)

推荐答案

感谢@Hans 建议的链接,我已经找到了答案.需要一个清单条目,至少指定 Windows 8 兼容性(子分层支持仅从 Windows 8 开始).对于想要使用分层子窗口的任何人,以下内容应作为清单文件包含在内.

Thanks to the link @Hans suggested I have found the answer. A manifest entry is required that specifies at least Windows 8 compatibility (child layering support only started with Windows 8). The following should be included as a manifest file for anyone wanting to use layered child windows.

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
    <application>
      <!--The ID below indicates app support for Windows 8 -->
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
    </application>
  </compatibility>
  <dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="*"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
  </dependency>
</assembly>

为了完整起见,我包含了整个文件,但相关标记是指定 Windows 8 GUID 的 元素.

For the purposes of completeness, I've included the entire file but the relevant tag is the <compatibility> element specifying the GUID for Windows 8.

您也可以声明与其他操作系统版本的兼容性,如文档页面针对 Windows 应用程序".

You may declare compatibility for other OS versions too, as described at the docs page "Targeting your application for Windows".

这篇关于如何在子控件上使用 WS_EX_LAYERED的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆