3

The Win32 GDI DrawFocusRect(HDC, const RECT*) function draws the dotted outline of a rectangle on the desired devince context. The cool thing about this function is it draws the dots using an XOR function so that when you call it a second time on the same device context and rectangle, it erases itself:

RECT rc = { 0, 0, 100, 100 };
DrawFocusRect(hdc, &rc); // draw rectangle
DrawFocusRect(hdc, &rc); // erase the rectangle we just drew

I want to achieve the same dotted line effect as DrawFocusRect() but I just want a line, not a whole rectangle. I tried doing this by passing a RECT of height 1 to DrawFocusRect() but this doesn't work because it XORs the "bottom line" of the rectange on top of the top line so nothing gets painted.

Can I create a plain HPEN that achieves the same effect as DrawFocusRect() so I can draw just a single line?

0xbe5077ed
  • 4,565
  • 6
  • 35
  • 77
  • 1
    [`SetROP2`](http://msdn.microsoft.com/en-us/library/windows/desktop/dd145088.aspx) with a `R2_XORPEN` drawmode should achieve the same effect, when used with the other line drawing APIs. – IInspectable Nov 23 '13 at 20:15
  • Thanks a lot @IInspectable. Any idea what system color is used to draw the focus rectangle? I'd like to use the same one if possible... – 0xbe5077ed Dec 03 '13 at 04:38

1 Answers1

3

As @IInspectable commented, you want to use SetROP2(). The other half of the battle is creating the correct pen. Here is how the whole thing shakes out:

HPEN create_focus_pen()
{
    LONG width(1);
    SystemParametersInfo(SPI_GETFOCUSBORDERHEIGHT, 0, &width, 0);
    LOGBRUSH lb = { };     // initialize to zero
    lb.lbColor = 0xffffff; // white
    lb.lbStyle = BS_SOLID;
    return ExtCreatePen(PS.GEOMETRIC | PS.DOT, width, &lb, 0, 0);
}

void draw_focus_line(HDC hdc, HPEN hpen, POINT from, POINT to)
{
    HPEN old_pen = SelectObject(hdc, hpen);
    int old_rop = SetROP2(R2_XORPEN);
    MoveToEx(hdc, from.x, from.y, nullptr);
    LineTo(hdc, to.x, to.y);
    SelectObject(hdc, old_pen);
    SetROP2(old_rop);
}
0xbe5077ed
  • 4,565
  • 6
  • 35
  • 77