一个标签,其背景一方面是透明的,另一方面是上部窗口

A label whose background is transparent on the one hand and the upper window on the other

本文关键字:透明 另一方面 窗口 一方面 背景 一个 标签      更新时间:2023-10-16

我目前正在WinApi中构建一个进度条,我希望标题"正在加载"出现在上面。

我设法创建了一个具有透明背景的标签,但我无法使标题高于进度条窗口。

这是我的代码:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
    WPARAM wParam, LPARAM lParam)
{
    static HWND hwndPrgBar;
    static HWND lable;
    static int i = 1;
    HDC hdcStatic = NULL;
    INITCOMMONCONTROLSEX InitCtrlEx;
    InitCtrlEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
    InitCtrlEx.dwICC = ICC_PROGRESS_CLASS;
    InitCommonControlsEx(&InitCtrlEx);
    switch (msg)
    {
    case WM_CREATE:
        CenterWindow(hwnd);
        /* creating the progress bar */
        hwndPrgBar = CreateWindowEx(0, PROGRESS_CLASS, NULL,
            WS_CHILD | WS_VISIBLE | PBS_SMOOTH | PBS_MARQUEE, // pbs_smooth makes no difference when manifest sets new windows styles
            0, 0, 350, 25, hwnd, NULL, g_hinst, NULL);
        /* sets progress bar looks */
        SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(hwndPrgBar));
        SendMessage(hwndPrgBar, (UINT)PBM_SETBKCOLOR, 0, RGB(224, 224, 224));
        SendMessage(hwndPrgBar, (UINT)PBM_SETBARCOLOR, 0, (LPARAM)RGB(131, 203, 123)); 
        SendMessage(hwndPrgBar, (UINT)PBM_SETMARQUEE, (WPARAM)TRUE, (LPARAM)5);
        /* create the lable as child of prgress bar */
        lable = CreateWindowEx(WS_EX_TRANSPARENT, L"STATIC", L"", WS_CHILD | WS_VISIBLE | SS_LEFT | WS_SYSMENU, 140, 5, 100, 100, hwnd, (HMENU)(100), (HINSTANCE)GetWindowLong(hwndPrgBar, GWL_HINSTANCE), NULL);
        /* sets lable text to Loading */
        SendMessage(lable, WM_SETTEXT, NULL, (LPARAM)L"Loading");
        SetWindowPos(lable, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
        /* I have tried this lines -> it didn't worked
        SetForegroundWindow(lable);
        BringWindowToTop(lable);
        SetActiveWindow(lable);
        SwitchToThisWindow(lable, TRUE);
        SetWindowPos(lable, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); 
        */
        /* set progress bar components */
        SendMessage(hwndPrgBar, PBM_SETRANGE, 0, MAKELPARAM(0, 150));
        SendMessage(hwndPrgBar, PBM_SETSTEP, 1, 0);
        /* start prorgess bar */
        i = 1;
        SendMessage(hwndPrgBar, PBM_SETPOS, 0, 0); 
        SetTimer(hwnd, ID_TIMER, 100, NULL); 
        break;

    case WM_TIMER:
        SendMessage(hwndPrgBar, PBM_STEPIT, 0, 0);
        i++;
        if (i == 150)
        {
            KillTimer(hwnd, ID_TIMER);
            exit(0);
        }
        break;
    case WM_COMMAND:
        break;
    case WM_DESTROY:
        KillTimer(hwnd, ID_TIMER);
        PostQuitMessage(0);
        break;
    case WM_CTLCOLORSTATIC:
        /* makes the lable transperent*/
        hdcStatic = (HDC)wParam;
        SetTextColor(hdcStatic, RGB(0, 0, 0));
        SetBkMode(hdcStatic, TRANSPARENT);
        return (LRESULT)GetStockObject(NULL_BRUSH);
    }
    return DefWindowProc(hwnd, msg, wParam, lParam);
}

如何使一侧的标签具有透明背景,另一方面它将位于进度条上方?

处理WM_CTLCOLORSTATIC将起作用,但每次进度条更改背景时,您都必须使label无效:

case WM_TIMER:
    SendMessage(hwndPrgBar, PBM_STEPIT, 0, 0);
    InvalidateRect(lable, NULL, FALSE);
    ...

或者改用子类(删除静态控件(:

LRESULT CALLBACK PrgBarProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
    UINT_PTR, DWORD_PTR)
{
    switch(msg) {
    case WM_PAINT:
    {
        LRESULT lres = DefSubclassProc(hwnd, msg, wp, lp);
        HDC hdc = GetDC(hwnd);
        RECT rc;
        GetClientRect(hwnd, &rc);
        SetBkMode(hdc, TRANSPARENT);
        DrawText(hdc, L"Text", -1, &rc, DT_CENTER|DT_VCENTER|DT_SINGLELINE);
        ReleaseDC(hwnd, hdc);
        return lres;
    }
    case WM_NCDESTROY:
        RemoveWindowSubclass(hwnd, SubclassProc, 0);
        return DefSubclassProc(hwnd, msg, wp, lp);
    }
    return DefSubclassProc(hwnd, msg, wp, lp);
}
...
SetWindowSubclass(hwndPrgBar, PrgBarProc, 0, 0);

PBS_MARQUEE迫使酒吧来回走动。你不希望在这里。除非通过清单文件或 Visual Studio 中的以下行启用视觉样式,否则它不起作用:

#pragma comment(linker,""/manifestdependency:type='win32' 
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' 
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'"")