Draw a line next to a word in WinAPI

How do I draw a line like this that is next to the word "Counts" in WinAPI with C?

https://drive.google.com/file/d/0B2XoQDQTCSrNbnlSVTFENDM0ZmM/view?usp=sharing

+3


source to share


1 answer


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.



enter image description here

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.

enter image description here

+6


source







All Articles