如何为状态栏的部分着色?(Winapi)

  • 本文关键字:Winapi 状态栏 c++ winapi
  • 更新时间 :
  • 英文 :


大家好,

我在写一个GUI为我的应用程序在c++中,使用WinAPI。一切都很好,我已经得到了我需要的一切,包括一个分开的状态栏,除了彩色的部分。

我的工作GUI

我创建的状态栏是这样的:

int statwidths[] = {150, 350, 500, -1};
(...)
case WM_PAINT:
(...)
hStatus = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, hwnd, (HMENU)IDC_MAIN_STATUS, GetModuleHandle(NULL), NULL);        
SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)"Item:");
SendMessage(hStatus, SB_SETTEXT, 1, (LPARAM)"Item:");
SendMessage(hStatus, SB_SETTEXT, 2, (LPARAM)"Setpoint:");
SendMessage(hStatus, SB_SETTEXT, 3, (LPARAM)"Status");
break;

给整个东西上色相当容易:

SendMessage(hStatus, SB_SETBKCOLOR, 0, RGB(255,0,0));

. .但那不是我需要的。我希望能够控制各个部分的颜色。我尝试了几种方法,包括在MSDN上找到的这个函数:

HWND DoCreateStatusBar(HWND hwndParent, int idStatus, HINSTANCE
hinst, int cParts)
{
HWND hwndStatus;
RECT rcClient;
HLOCAL hloc;
PINT paParts;
int i, nWidth;
// Ensure that the common control DLL is loaded.
InitCommonControls();
// Create the status bar.
hwndStatus = CreateWindowEx(
0,                       // no extended styles
STATUSCLASSNAME,         // name of status bar class
NULL,           // no text when first created
SBARS_SIZEGRIP |         // includes a sizing grip
WS_CHILD | WS_VISIBLE,   // creates a visible child window
0, 0, 0, 0,              // ignores size and position
hwndParent,              // handle to parent window
(HMENU) idStatus,       // child window identifier
hinst,                   // handle to application instance
NULL);                   // no window creation data
// Get the coordinates of the parent window's client area.
GetClientRect(hwndParent, &rcClient);
// Allocate an array for holding the right edge coordinates.
hloc = LocalAlloc(LHND, sizeof(int) * cParts);
paParts = (PINT) LocalLock(hloc);
// Calculate the right edge coordinate for each part, and
// copy the coordinates to the array.
nWidth = rcClient.right / cParts;
int rightEdge = nWidth;
for (i = 0; i < cParts; i++) {
paParts[i] = rightEdge;
rightEdge += nWidth;
}
// Tell the status bar to create the window parts.
SendMessage(hwndStatus, SB_SETPARTS, (WPARAM) cParts, (LPARAM)
paParts);
// Free the array, and return.
LocalUnlock(hloc);
LocalFree(hloc);
return hwndStatus;
}

我希望能够玩几个彩色矩形,并通过这种方式得到我需要的,不工作。试图通过ownerdraw创建部件:SendMessage(hStatus1, SB_SETTEXT, 0 | SBT_OWNERDRAW, 0);,并处理设置的颜色和背景在wm_drawitem的情况下,同样令人失望的结果:状态栏正在绘制,但我不能颜色它。例如,我可以在我的wm_drawwitem:

中使用以下代码对窗格中的文本进行着色
lpDIS=(LPDRAWITEMSTRUCT)lParam;
ptStr =(PTSTR)lpDIS->itemData;
SetTextColor(lpDIS->hDC, RGB(0xFF, 00, 00));
ExtTextOut(lpDIS->hDC, 0, 0, 0 , &lpDIS->rcItem,ptStr, strlen(ptStr), NULL);

它(奇怪地)给了我这个结果

试着用一些零碎的东西来给主GUI的背景上色:

HBRUSH brush;
RECT rect;
pen=CreatePen(PS_SOLID, 1, bkgndcolor);
brush=CreateSolidBrush(bkgndcolor);
SelectObject((HDC)wParam, pen);
SelectObject((HDC)wParam, brush);

. .但我被困住了。GetClientRect(hwnd, &rect); Rectangle((HDC)wParam, rect.left, rect.top, rect.right, rect.bottom);显然不起作用,因为&;rect&;包含主窗口的矩形,而不是状态栏或它的一部分。

至少有人能给我指出正确的方向吗?搜索这个论坛和互联网没有得到我;很显然我想要的东西是比较稀有的。但我无法想象这是不可能的。

非常感谢!

感谢大家的回复。我设法使它工作与以下的点点滴滴:

在wParam中用SBT_OWNERDRAW填充我的部件。我的窗口处理看起来像这样:

(...)
case WM_DRAWITEM:
lpDIS=(LPDRAWITEMSTRUCT)lParam;
GetClientRect((HWND)lpDIS->hwndItem, &rect);
pen=CreatePen(PS_SOLID, 1, bkgndcolor);
brush=CreateSolidBrush(bkgndcolor);
SelectObject(lpDIS->hDC, pen);
SelectObject(lpDIS->hDC, brush);
Rectangle(lpDIS->hDC, rect.left, rect.top, rect.right, rect.bottom);
ptStr =(PTSTR)lpDIS->itemData;
SetTextColor(lpDIS->hDC, RGB(0,0,0));
SetBkColor(lpDIS->hDC, bkgndcolor);
SetBkMode( lpDIS->hDC, TRANSPARENT );
DrawText(lpDIS->hDC, ptStr, -1, &rect, DT_VCENTER | DT_SINGLELINE);
break;

我只是调整了矩形结构体(。Left and .right),以使矩形覆盖它。

结果和我想要的差不多

小提示,文本没有很好地放置在窗格中。我试过用ExtTextOutA写文本,给它一个x和y偏移量,但这只写左窗格中的字符串。DrawText似乎可以在适当的矩形中书写。要给它一些间距,一个快速的解决方法是将rect.left增加2。如果你能提出一个不那么难看的解决方案,我将不胜感激。

另一个评论是,字体似乎是不同的,如果我自己绘制它:看看截图,#1到#3是自己绘制的。不是最大的问题,但我想我喜欢"原创"。字体。假设我必须自己选择这个字体,有人知道这个字体是什么以及它需要多大才能匹配原来的字体吗?

谢谢!

最新更新