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 будет использоваться для определенного окна, пока оно существует.

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

Ответы на вопрос(3)

Ваш ответ на вопрос