Win32: у окна есть один и тот же HDC на протяжении всего срока службы?
Могу ли я использовать 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 ().
Особенно сейчас, во времена Desktop Composition, допустимо ли рисовать на DC, который я получаю за пределами BeginPaint?
Кажется, есть два способа, которыми я могу заставить DC рисовать во время цикла рисования:
постоянный ток =GetDC(HWND);
BeginPaint (& PAINTSTRUCT);
Есть третий способ, но, похоже, это ошибка в Borland Delphi, с которой я разрабатываю.
В течениеWM_PAINT В процессе обработки Delphi считает, что wParam является DC, и приступает к рисованию на нем. Принимая во внимание, что MSDN говорит, что wParam сообщения WM_PAINT не используется.
ПочемуМоя настоящая цельэто попытаться сохранить постоянный объект GDI + Graphics против 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 будет использоваться для определенного окна, пока оно существует.
Примечание: я не использую двойную буферизацию,потому что я хочу быть хорошим разработчиком и делать правильные вещи, Иногда это означает, что двойная буферизация - это плохо.