Могу ли я использовать DC вне цикла рисования?
DC моего окна гарантированно будет действителен вечно?
Я пытаюсь выяснить, как долго действителен контекст устройства (DC) моего элемента управления.
я знаю, что могу позвонить:
GetDC(hWnd);
чтобы получить контекст устройства окна моего элемента управления, но разрешено ли это?
Когда Windows отправляет мне сообщение WM_PAINT, я должен позвонить BeginPaint / EndPaint , чтобы правильно подтвердить, что я его нарисовал, и внутренне очистить недопустимую область:
BeginPaint(hWnd, {out}paintStruct);
try
//Do my painting
finally
EndPaint(hWnd, paintStruct);
end;
Но вызов BeginPaint также возвращает мне DC внутри структуры PAINTSTRUCT. Это DC, на котором я должен рисовать.
Я не могу найти ничего в документации, которая говорит, что DC, возвращаемый BeginPaint (), является тем же DC, который я получил бы от GetDC ().
Особенно сейчас, во времена составления рабочего стола, допустимо ли рисовать на DC, который я получаю за пределами BeginPaint?
Кажется, есть 2 способа заставить DC рисовать во время цикла рисования:
dc = GetDC (hWnd);
BeginPaint (& PAINTSTRUCT);
Есть 3-й способ, но, похоже, это ошибка в Borland Delphi, с которой я разрабатываю.
Во время обработки WM_PAINT Delphi полагает, что wParam является DC, и продолжает рисовать на нем. Принимая во внимание, что MSDN говорит, что wParam сообщения WM_PAINT не используется.
Почему
Моя настоящая цель - попытаться сохранить постоянный графический объект GDI + против HDC, чтобы я мог использовать некоторые более эффективные функции GDI +, которые зависят от наличия постоянного DC.
Во время обработки сообщения WM_PAINT я хочу нарисовать изображение GDI + на холсте. Следующая версия nieve очень медленная:
WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, ps);
Graphics g = new Graphics(ps.hdc);
g.DrawImage(m_someBitmap, 0, 0);
g.Destroy();
EndPaint(h_hwnd, ps);
}
GDI содержит более быстродействующее растровое изображение, CachedBitmap. Но использование его без размышлений не дает никакого выигрыша в производительности:
WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, ps);
Graphics g = new Graphics(ps.hdc);
CachedBitmap bm = new CachedBitmap(m_someBitmap, g);
g.DrawCachedBitmap(m_bm, 0, 0);
bm.Destroy();
g.Destroy();
EndPaint(h_hwnd, ps);
}
Прирост производительности достигается за счет создания CachedBitmap один раз, поэтому при инициализации программы:
m_graphics = new Graphics(GetDC(m_hwnd));
m_cachedBitmap = new CachedBitmap(b_someBitmap, m_graphcis);
А теперь в цикле рисования:
WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(m_hwnd, ps);
m_graphics.DrawCachedBitmap(m_cachedBitmap, 0, 0);
EndPaint(h_hwnd, ps);
}
За исключением того, что теперь я верю, что DC, полученный после инициализации программы, будет тем же DC для моего окна, пока приложение работает. Это означает, что он выживает через:
- быстрые пользовательские переключатели
- композиция включена / отключена
- переключение тем
- отключение темы
В MSDN я не нахожу ничего, что гарантировало бы, что один и тот же DC будет использоваться для определенного окна, пока оно существует.
Примечание: я не использую двойную буферизацию, , потому что я хочу быть хорошим разработчиком и делать правильные вещи . Иногда это означает, что двойная буферизация плохая.