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