我目前正在WinApi中构建一个ProgressBar,我希望在其上显示标题“正在加载”。

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

这是我的代码:

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强制栏来回移动。你不想在这里。除非通过 list 文件或Visual Studio中的以下行启用了视觉样式,否则它将无法正常工作:
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

关于c++ - 一种标签,其背景一方面是透明的,另一方面是上部窗口,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48409334/

10-10 18:14