Draw a line next to a word in WinAPI
Using dialogue resources
Create a static text control with no text with a height of 1 or 2 pixels, turn on the border ( WS_BORDER
) and set the style to Static Edge ( WS_EX_STATICEDGE
). Then create a static text element labeled "Counts". Then use CreateDialog()
or DialogBox()
to display the dialog box.
IDD_DIALOG1 DIALOGEX 0, 0, 172, 63
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
LTEXT "",IDC_STATIC,6,12,156,1,WS_BORDER,WS_EX_STATICEDGE
LTEXT "Counts ",IDC_STATIC,6,8,26,8
END
Note. ... This is literally what Visual Studio created using the dialog designer.
Creating static controls withCreateWindow()
(as Jonathan Potter suggested)
LRESULT OnCreate( HWND hWnd, LPCREATESTRUCT lpCreateStruct )
{
// Get default gui font
NONCLIENTMETRICS metrics;
metrics.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &metrics, NULL);
HFONT hFont = CreateFontIndirect(&metrics.lfMessageFont);
// Create the line
CreateWindowEx(WS_EX_STATICEDGE, _T("STATIC"), NULL, WS_CHILD|WS_VISIBLE|WS_BORDER,
10, 17, 280, 1, hWnd, NULL, lpCreateStruct->hInstance, NULL);
// Create the Counts label
HWND hwndCounts = CreateWindow(_T("STATIC"), _T("Counts "), WS_CHILD|WS_VISIBLE,
10, 10, 50, 26, hWnd, NULL, lpCreateStruct->hInstance, NULL);
// Apply the default gui font
SendMessage(hwndCounts, WM_SETFONT, (WPARAM)hFont, TRUE);
// Cleanup the font object
DeleteObject(hFont);
}
Hand drawing on an event WM_PAINT
void OnPaint( HWND hWnd )
{
// Get the default font
NONCLIENTMETRICS metrics;
metrics.cbSize = sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &metrics, NULL);
HFONT hFont = CreateFontIndirect(&metrics.lfMessageFont);
// Setup HDC
RECT rect;
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
// Select the default font
SelectObject(hdc, hFont);
// Draw the line using the button shadow
SelectObject(hdc, GetStockObject(DC_PEN));
SetDCPenColor(hdc, GetSysColor(COLOR_BTNSHADOW));
MoveToEx(hdc, 10, 17, NULL);
LineTo(hdc, 280, 17);
// Draw the word Counts overtop of the line
SetRect(&rect, 10, 10, 280, 22);
SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
SetBkColor(hdc, GetSysColor(COLOR_BTNFACE));
DrawText(hdc, TEXT("Counts "), -1, &rect, DT_NOCLIP);
// Cleanup the font object
DeleteObject(hFont);
// Quit painting
EndPaint(hWnd, &ps);
}
Note. Something I left out in this example is the default font height. You want to adjust your code for this.
Here is a screenshot of the output of this method.
In your example it looked like one one pixel line, so I was drawing, but if you want the line to look more like "Fixed 3D" or "Decreased bevel line" (this is that the group box tends to draw a border for it) , then you can draw another line below it with the button highlight color.
SetDCPenColor(hdc, GetSysColor(COLOR_BTNHIGHLIGHT));
MoveToEx(hdc, 10, 18, NULL);
LineTo(hdc, 280, 18);
As Ben Voigt pointed out, it would be better to do this with DrawEdge
.
RECT line;
SetRect(&line, 10, 17, 280,17);
DrawEdge(hdc, &line, EDGE_ETCHED, BF_TOP );
Creating a group box control (suggested by Hans Passant)
Hans Passant's suggestion to do it with Group Box actually worked when I tested it. It was still drawing the rectangle , and when you turned on visual styles it was very difficult to see . However, it should get you started if you want to give it away.
HWND hwndGroup = CreateWindow(_T("Button"), _T("Counts "),
WS_CHILD|WS_VISIBLE|BS_GROUPBOX, 10, 10, 280, 2, hWnd, NULL,
lpCreateStruct->hInstance, NULL);
SendMessage(hwndGroup, WM_SETFONT, (WPARAM)hFont, TRUE);
Additional note
Something else I would like to suggest is that you can use Spy ++ that comes with Visual Studio to analyze the window you are viewing.This will show you at least if it is a child control. or they draw it by hand. If it's a child control, you'll also be able to see the rectangle and the styles that are applied to it, as well as a lot of additional information.
source to share