简体   繁体   English

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

[英]Draw a line next to word in WinAPI

How do I draw a line like this that is right next to a word like "Counts", in WinAPI with C? 如何在带有C的WinAPI中绘制像“Counts”这样的单词旁边的这样一行?

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

Using Dialog Resources 使用对话资源


Create a static text control with no text that is 1 or 2 pixels in height, turn on the border ( WS_BORDER ), and set its style to Static Edge ( WS_EX_STATICEDGE ). 创建一个静态文本控件,其中没有高度为1或2像素的文本,打开边框( WS_BORDER ),并将其样式设置为静态边缘( WS_EX_STATICEDGE )。 Then create a static text control with the word "Counts" in it on top of that. 然后在其上创建一个静态文本控件,其中包含单词“Counts”。 Then use CreateDialog() or DialogBox() to show the dialog box. 然后使用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

Note: This is verbatim what Visual Studio generated using the dialog designer. 注意:这是Visual Studio使用对话框设计器生成的内容。


Creating Static Controls Using CreateWindow() (as suggested by Jonathan Potter) 使用CreateWindow()创建静态控件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);
}


Drawing manually on the WM_PAINT 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 did not account for in this example is the height of the default font. 注意:在此示例中我没有考虑的是默认字体的高度。 You will want to adjust the code for that. 您需要调整代码。

Here is a screenshot of the output of this method. 以下是此方法输出的屏幕截图。

在此输入图像描述

In your example, it looked like a single one pixel line, so that's what I drew, but if you'd like to make the line look more like a 'Fixed 3D' or 'lowered bevel line' (which is what the group box tends to draw for it's border line), then you can draw another line below it with the button highlight color. 在你的例子中,它看起来像一个像素线,所以这就是我画的,但是如果你想让线看起来更像是'固定3D'或'降低斜角线'(这就是组合框)倾向于绘制它的边界线),然后你可以用按钮突出显示颜色在它下面绘制另一条线。

SetDCPenColor(hdc, GetSysColor(COLOR_BTNHIGHLIGHT));
MoveToEx(hdc, 10, 18, NULL);
LineTo(hdc, 280, 18);

As pointed out by Ben Voigt, it might be better to do this with DrawEdge though. 正如Ben Voigt所指出的那样,使用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) 创建一个Group Box Control (Hans Passant建议)


Hans Passant's suggestion of doing this with a Group Box did work when I tested it. 当我测试它时,Hans Passant建议用Group Box做这件事。 It still drew a rectangle , and when you enabled visual styles it was very difficult to see . 仍然绘制了一个矩形 ,当你启用视觉样式时, 很难看到它 Nevertheless, this should get you started if you want to give it a go. 不过,如果你想试一试,这应该可以让你开始。

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 use can use Spy++ which comes with Visual Studio to analyze the window you are looking at. 我想建议的另一件事是你使用可以使用Visual Studio附带的Spy ++来分析你正在看的窗口。 This will tell you at the very least if it's a child control, or whether they are painting it manually. 这至少会告诉你它是否是一个子控件,或者是否是手动绘制它。 If it's a child control you will also be able to see the rectangle and styles that are applied to it, as well lots of additional information. 如果它是一个子控件,您还可以看到应用于它的矩形和样式,以及许多其他信息。

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM