WinAPI - как нарисовать пунктирную линию? - PullRequest
3 голосов
/ 12 февраля 2009

Я создаю HPEN, используя метод WinAPI GDI:

HPEN hPen = CreatePen(PS_DOT, 1, color);

Затем нарисуйте линию, используя методы MoveToEx и LineTo.

На самом деле нарисованная линия пунктирная . 3 пикселя пусто, 3 пикселя с пунктирной линией.

Почему стиль PS_DOT не рисует пунктирную линию? Как нарисовать пунктирную линию с помощью WinAPI?

Ответы [ 4 ]

5 голосов
/ 12 февраля 2009

Вот замечательное решение от MaxHacher, которое я нашел в CodeProject
(http://www.codeproject.com/KB/GDI/DOTTED_PEN.aspx)

LOGBRUSH LogBrush;<br> LogBrush.lbColor = color;<br> LogBrush.lbStyle = PS_SOLID;<br> HPEN hPen = ExtCreatePen( PS_COSMETIC | PS_ALTERNATE, 1, &LogBrush, 0, NULL );

Работает хорошо!

1 голос
/ 12 февраля 2009

У меня тоже была эта проблема в прошлом. Я прибег к использованию LineDDA и обратному вызову.

struct LineData{
    CDC* pDC;
    COLORREF crForegroundColor;
    COLORREF crBackgroundColor;
};
.
.
.
LineData* pData = new LineData;
pData->crForegroundColor = crForegroundColor;
pData->crBackgroundColor = crBackgroundColor;
pData->pDC = pdc;

LineDDA(nStartx, nStarty, nEndPointX, nEndPointY, LineDDAProc, (LPARAM) pData);
delete pData;
.
.
.

void 
LineDDAProc(int x, int y, LPARAM lpData)
{
   static short nTemp = 0;

   LineData* pData = (LineData*) lpData;

   if (nTemp == 1)
    pData->pDC->SetPixel(x, y, pData->crForegroundColor);
   else
    pData->pDC->SetPixel(x, y, pData->crBackgroundColor);
   nTemp = (nTemp + 1) % 2;
}

Возможно, это не самый эффективный алгоритм рисования, но теперь вы также полностью контролируете расстояние между точками. Я пошел с этим подходом, потому что были другие не родные стили пера, которые я использовал для рендеринга линий, которые использовали немного образца. Затем я прошелся по биту и использовал setpixel для включенных бит. Это работало хорошо и увеличило количество полезных стилей.

0 голосов
/ 16 октября 2018

Я использовал это вместо вышеупомянутого, чтобы избежать двух пикселей подряд

void LineDDAProc(int x, int y, LPARAM lpData)
{
   LineData* pData = (LineData*) lpData;

   if (x%2!=y%2)
    pData->pDC->SetPixel(x, y, pData->crForegroundColor);
}
0 голосов
/ 12 февраля 2009

Я не пробовал этого, но, возможно, стоит проверить результаты

HPEN hPen = CreatePen(PS_DOT, 0, color);

Ширина пера, равная нулю, заставляет GDI всегда делать перо шириной в один пиксель, независимо от масштабирования, связанного с контекстом устройства. Этого может быть достаточно, чтобы получить нужные вам точки.

...