Win32: Hat ein Fenster für die gesamte Lebensdauer den gleichen HDC?

Darf ich einen Gleichstrom außerhalb eines Lackierzyklus verwenden? Ist der DC meines Fensters garantiert für immer gültig?

Ich versuche herauszufinden, wie lange der Gerätekontext (DC) meines Steuerelements gültig ist.

Ich weiß, dass ich anrufen kann:

GetDC(hWnd);

um den Gerätekontext des Fensters meines Steuerelements abzurufen, aber ist das zulässig?

Wenn Windows mir eine WM_PAINT-Nachricht sendet, soll ich anrufenBeginPaint/EndPaint um zu bestätigen, dass ich es gemalt habe, und um den ungültigen Bereich intern zu löschen:

BeginPaint(hWnd, {out}paintStruct);
try
   //Do my painting
finally
   EndPaint(hWnd, paintStruct);
end;

Der Aufruf von BeginPaint gibt mir jedoch auch einen DC innerhalb der PAINTSTRUCT-Struktur zurück. Dies ist der DC, den ichsollte malen auf.

Ich kann nichts in der Dokumentation finden, die besagt, dass der von BeginPaint () zurückgegebene DC der gleiche DC ist, den ich von GetDC () erhalten würde.

Ist es gerade jetzt in den Tagen von Desktop Composition gültig, ein DC zu malen, das ich außerhalb von BeginPaint erhalte?

Es scheint zwei Möglichkeiten zu geben, wie ich einen DC während eines Malzyklus zum Malen bringen kann:

dc =GetDC(hWnd);

BeginPaint (& paintStruct);

Es gibt einen dritten Weg, aber es scheint ein Fehler mit dem Borland Delphi zu sein, mit dem ich mich entwickle.

WährendWM_PAINT Bei der Verarbeitung glaubt Delphi, dass es sich bei wParam um einen DC handelt, und malt darauf weiter. Während der MSDN besagt, dass das wParam einer WM_PAINT-Nachricht nicht verwendet wird.

Das Warum

Mein echtes Zielist zu versuchen, ein beständiges GDI + Graphics-Objekt beizubehalten gegen einen HDC, so dass ich einige leistungsfähigere Funktionen von GDI + nutzen kann, die von einem dauerhaften DC abhängen.

Während der WM_PAINT-Nachrichtenbehandlung möchte ich ein GDI + -Bild auf die Zeichenfläche zeichnen. Die folgende NIEVE-Version ist sehr langsam:

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 enthält eine schnellere Bitmap, eine CachedBitmap. Die Verwendung ohne nachzudenken bietet jedoch keinen Leistungsvorteil:

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);
}

Der Leistungsgewinn ergibt sich aus der einmaligen Erstellung der CachedBitmap, also bei der Programminitialisierung:

m_graphics = new Graphics(GetDC(m_hwnd));
m_cachedBitmap = new CachedBitmap(b_someBitmap, m_graphcis);

Und jetzt zum Lackierzyklus:

WM_PAINT:
{
   PAINTSTRUCT ps;
   BeginPaint(m_hwnd, ps);
   m_graphics.DrawCachedBitmap(m_cachedBitmap, 0, 0);
   EndPaint(h_hwnd, ps);
}        

Außer jetzt vertraue ich darauf, dass der DC, den ich nach der Programminitialisierung erhalten habe, der gleiche DC für mein Fenster ist, solange die Anwendung ausgeführt wird. Dies bedeutet, dass es überlebt durch:

Schnelle BenutzerwechselKomposition aktiviert / deaktiviertThemenwechselThema deaktivieren

Ich finde nichts in MSDN, das garantiert, dass derselbe DC für ein bestimmtes Fenster verwendet wird, solange das Fenster vorhanden ist.

Hinweis: Ich benutze keine doppelte Pufferung,weil ich ein guter Entwickler sein und das Richtige tun will. Manchmal bedeutet das, dass Doppelpufferung schlecht ist.

Antworten auf die Frage(3)

Ihre Antwort auf die Frage