gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 02:07:39 25 4
gpt4 key购买 nike

我目前正在 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/

25 4 0