在WinAPI中的单词旁边画一条线

Edw*_*rak 3 c user-interface winapi

如何在带有C的WinAPI中绘制像"Counts"这样的单词旁边的这样一行?

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

Dre*_*pin 6

使用对话资源


创建一个静态文本控件,其中没有高度为1或2像素的文本,打开border(WS_BORDER),并将其样式设置为Static Edge(WS_EX_STATICEDGE).然后在其上创建一个静态文本控件,其中包含单词"Counts".然后使用CreateDialog()DialogBox()显示对话框.

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
Run Code Online (Sandbox Code Playgroud)

注意:这是Visual Studio使用对话框设计器生成的内容.


使用CreateWindow()(由Jonathan Potter建议)创建静态控件


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);
}
Run Code Online (Sandbox Code Playgroud)


手动绘制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);
}
Run Code Online (Sandbox Code Playgroud)

注意:在此示例中我没有考虑的是默认字体的高度.您需要调整代码.

以下是此方法输出的屏幕截图.

在此输入图像描述

在你的例子中,它看起来像一个像素线,所以这就是我画的,但是如果你想让线看起来更像是'固定3D'或'降低斜角线'(这就是组合框)倾向于绘制它的边界线),然后你可以用按钮突出显示颜色在它下面绘制另一条线.

SetDCPenColor(hdc, GetSysColor(COLOR_BTNHIGHLIGHT));
MoveToEx(hdc, 10, 18, NULL);
LineTo(hdc, 280, 18);
Run Code Online (Sandbox Code Playgroud)

正如Ben Voigt所指出的那样,DrawEdge尽管这样做可能会更好.

RECT line;
SetRect(&line, 10, 17, 280,17);
DrawEdge(hdc, &line, EDGE_ETCHED, BF_TOP );
Run Code Online (Sandbox Code Playgroud)


创建一个Group Box Control(Hans Passant建议)


当我测试它时,Hans Passant建议用Group Box做这件事.它仍然绘制了一个矩形,当你启用视觉样式时,很难看到它.不过,如果你想试一试,这应该可以让你开始.

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);
Run Code Online (Sandbox Code Playgroud)


附加说明


我想建议的另一件事是你使用可以使用Visual Studio附带的Spy ++来分析你正在看的窗口.这至少会告诉你它是否是一个子控件,或者是否是手动绘制它.如果它是一个子控件,您还可以看到应用于它的矩形和样式,以及许多其他信息.

在此输入图像描述