Урок за въвеждане на WTL от нулата (3) WTL чертеж на прозорец, двойно буфериране

Wtl Entry Tutorial From Scratch Wtl Window Drawing



Тъй като WinApi не е имал толкова красив стандарт за визуален израз като Material Design, когато се е родил, неговият стил на управление на системата е доста оскъден и пълен с инженерски стил на дизайн, така че през повечето време контролът трябва да изпълнява персонализиран чертеж, дори ако е просто прост цвят на фона.
След като завършим най-простия контрол на прозореца по-горе, нека добавим цвят на фона към него.
Методът за рисуване се извиква, когато системата актуализира контролата. Следователно това също зависи от цикъла на съобщението. Можем да го намерим във файла за дефиниция на съобщението.
изображение
и OnClose По същия начин за добавяне
OnPaint
Параметрите на метода CDCHandle Това е обект, използван за рисуване, но не можем директно да използваме този параметър.

Накратко анализирайте чертежния обект

Отидете на CDCHandle Определение
CDCHandle
можете да видите, че той е CDCT Псевдоним за различни родови параметри на класа и има и друг съответстващ CDC клас
Нека да разгледаме CDCT Каква роля играе общият параметър
CDCT
премина CDCT Дефиницията на може да се види от общия параметър t_bУправляван Обявен за CDCT Провежда се от субекта HDC Дали обектът се управлява от само себе си и след това в CDCT Унищожи при унищожаване HDC
тук HDC Това е дръжка, дефинирана от WinApi за рисуване.
Накратко, този подход е да Дръжката, държана от плотера, може да се предава по стойност, без да се засяга дръжката. Но в крайна сметка дръжката ще бъде унищожена само когато създателят я унищожи
Of course, it doesn't matter if you don't understand. Just know what to do next.
използване CPrintDC Клас, който е дефиниран в ATL за получаване от манипулатора на прозореца HDC Дръжка
погледни CPrintDC Определение
CPrintDC



използване CPrintDC
изображение
HBRUSH Инструментът за четки е предоставен от WinApi CreateSolidBrush Е да създадете монохромна четка, тук създаваме еднаЗащитно оцветяванеЧетка за боя
GetClientRect Е да се получи позицията на текущия контрол спрямо себе си. Това е техният собствен размер. Предайте a CRect На адреса му ще бъде присвоена стойност.
FillRect Посочете четката за съответната област. Тоест операции по теглене.
изображение



Динамично рисуване

Ако сте били изложени на интерфейсния API на други платформи, трябва да можете директно да мислите за следните точки:
Операциите по теглене могат да се извикват само от системата Методът на рисуване е метод за изпълнение на определен процес. Не може да се извиква активно
Например следните операции
Добавете събитие за отговор на кликване на мишката чрез съобщението, то ще бъде извикано, когато левият бутон на мишката бъде щракнат в прозореца OnLbuttonDown
Добавете това, което искате да направите тук
изображение



Анулиране () Методът е метод, който може да се използва за актуализиране на контролата. Той ще обезсили контрола и ще бъде актуализиран от системата в свободно време.
UpdateWindow () Методът позволява незабавният контрол да се опреснява незабавно и също така да се преначертае. Ако не е необходимо да опреснявате веднага, не е нужно да го добавяте.
Вижда се, че нито директното използване на четката, нито външното извикване на метода OnPaint не са променили цвета на интерфейса.
изображение
Интерфейсът става син, което всъщност се извиква автоматично от системата OnPaint След като методът влезе в сила.
След това ще използвам този код, за да демонстрирам процеса
изображение
The black square is missing because GIF recording will have dropped frames
Добавеният код първо рисува фона и след това изчертава черна точка около мишката при щракване на мишката. Отменете позицията на черната точка, когато мишката е повдигната, и след това актуализирайте чертежа отново.
След това добавете някои функции
Четка за рисуване CPen И рисуване на текст
изображение

void printLine( CDCHandle dc) { CPen pen pen.CreatePen(PS_SOLID, 2, RGB(255, 255, 255)) dc.SelectPen(pen.m_hPen) CPoint start start.x = 10 start.y = 10 dc.MoveTo(start) CPoint dest dest.x = mouseClickLocation.left dest.y = mouseClickLocation.top if (dest.x != 0) { dc.LineTo(dest) } } void printText(CDCHandle dc) { CString text CRect textLocation text = 'hello world' dc.SetTextColor(RGB(0, 0, 0)) dc.ExtTextOutA(mouseClickLocation.left, mouseClickLocation.top, ETO_OPAQUE, NULL, text, text.GetLength(), NULL) }

Най-общо казано, ако си прав CPringDC Ако разговорът е независим чертеж
Трябва да го използвате преди рисуване SaveDC Запазете и го извикайте в края
RestoreDC (-1) Метод за възстановяване на предишното ви състояние
DC
Може би сте забелязали тук имам OnPaint Заменете метода с DoPaint Метод, който включва една точка, която трябва да се добави следваща

Двойно буфериране

Когато рисувате, ако многократно прерисувате, част от него ще се покаже поради чертежа. Ако прерисуването е прекалено бързо, следващият чертеж ще бъде изпълнен преди завършването на последния чертеж, което ще предизвика трептене.
изображение
Необходим по това време CDoubleBufferImpl , Той е проектиран като основен клас, който е еквивалентен на разширение и по това време се случва множествено наследяване.
Нейната реализация
CDoubleBufferImpl
CDoubleBufferImpl Той получи съобщение, че ще извика рисуване. След това осигурява интерфейс DoPaint
Затова го използвайте така
1. Добавете наследяване на клас
изображение
2. Добавете връзка към съобщение
изображение
CHAIN_MSG_MAP Можете да свържете съобщенията в съответния клас с текущия клас
защото CDoubleBufferImpl Вече постигнато MSG_WM_PAINT (OnPaint) , Така че трябва да се коментира.
3. Прилагане DoPaint метод
е да поставите тук цялото съдържание, което първоначално трябва да нарисувате. DC Вече тук CDoubleBufferImpl Е заловен и предаден на DoPaint , Така че просто го използвайте директно.
DoPaint
за да видите ефекта
CDoubleBufferImpl
In the event of mouse movement, complex drawing may lead to drawing errors. This may be caused by the high return rate of the mouse (the high-end mouse can reach 1000HZ). The drawing call exceeds the rendering capability of the GPU. In this case, you need to actively reduce the drawing frequency, such as limited to 60 frames, and the independent windows are drawn separately, so you should try to avoid redrawing a large number of custom drawing windows at the same time
По отношение на чертежа, няма да разширявам твърде много тук.