Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
695 views
in Technique[技术] by (71.8m points)

winapi - How to use WS_EX_LAYERED on child controls

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);   

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.

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

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.

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...