C ++ win32 проект двойной буферизации - PullRequest
1 голос
/ 14 марта 2011

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

hdc = BeginPaint(hWnd, &ps);
hdcBack = CreateCompatibleDC(hdc); 
GetClientRect(hWnd, &windowRect); 
backBuffer = CreateCompatibleBitmap(hdc, windowRect.right, windowRect.bottom);
SelectObject(hdcBack, backBuffer); 
FloodFill(hdcBack, 0, 0, RGB(255, 255, 255)); 
BitBlt(hdcBack,0,0,windowRect.right,windowRect.bottom,hdc,0,0,SRCCOPY);
color = RGB(rand() % 255, rand() % 255, rand() % 255); 
hBrush = CreateSolidBrush(color); 
SelectObject (hdcBack, hBrush); 

MoveToEx(hdcBack,x1,y1,NULL); //x1,y1,x2,y2 are the initial click point and the current position of the mouse when keeping the left button down and dragging
LineTo(hdcBack,x2,y2);
BitBlt(hdc, 0, 0, windowRect.right, windowRect.bottom, hdcBack, 0, 0, SRCCOPY);

DeleteObject(hBrush); 
DeleteDC(hdcBack);
DeleteObject(backBuffer);
EndPaint(hWnd, &ps);

Я также пытался не копировать фон в буфер до рисования линии, и он правильно рисует линию, но когда я рисую новую линию, ранее нарисованная линия исчезает. Итак, как я могу нарисовать несколько линий с двойной буферизацией и сохранить предыдущие нарисованные линии?

Ответы [ 2 ]

1 голос
/ 14 марта 2011

Проблема присуща дизайну, если я правильно понимаю требование.

Первый BitBlt() копирует содержимое предыдущего в буфер, затем вы рисуете линию и затем применяете изменения к экрану, который дает точные результаты, которые вы описали. Таким образом, вы только добавляете графику, а не заменяете, и видите несколько строк вместо одной.

Если вы хотите отобразить линию, которая перетаскивается мышью, вам необходимо сначала заполнить задний буфер любым фоном, который вы имели в виду (назовите его constant-data ), и нарисовать на нем соответствующая графика (назовите это изменяющиеся данные ) каждое движение мыши. Во всяком случае, я считаю, что комментирование этого первого BitBlt() должно сработать.

Кроме того, вы выбираете кисть перед вызовом линейных функций, в которых используется ручка . Разве этот звонок не должен прийти до звонка FloodFill()?

РЕДАКТИРОВАТЬ:

Используйте третий буфер для хранения самых последних данных, как предложено в моем комментарии к вашему. В вашем обработчике «мышью вверх», наконец, нарисуйте новую строку на этом буфере.
Таким образом, вы читаете из этого буфера в вашем обработчике перемещения мыши и в обработчике при рисовании, и записываете в него в обработчике перемещения мыши, когда пользователь, наконец, уверен, как он хочет его линия нарисована.

0 голосов
/ 14 марта 2011

Один из способов создать это без использования буфера буфера - это вести динамический список линий, которые вы рисуете каждый раз.

Ваш процесс сообщения может выглядеть примерно так:

  • В WM_LBUTTONDOWN добавьте новую строку в список с текущей позицией в качестве начала.
  • Вкл. WM_MOUSEMOVE (левой кнопкой вниз), измените конечную позициюпоследняя строка в списке для текущей позиции мыши.

На каждой перерисовке вы просто перебираете список и рисуете каждую линию.

...