2016-03-18 12 views
5

Ich versuche, ein Bild mit GDI + zu zeichnen. Wenn ich es in WM_PAINT tun es funktioniert:GDI + Graphics :: DrawImage funktioniert nicht

case WM_PAINT: { 
    hdc = BeginPaint(hWnd, &ps); 
    Gdiplus::Graphics graphics(hdc); 
    Gdiplus::Image gdiImage(L"unt.png"); 
    graphics.DrawImage(&gdiImage, 40, 40); 
    EndPaint(hWnd, &ps); 

    break; 

} 

Aber wenn ich es auf eine Schaltfläche klicken tun oder in WM_CREATE es nicht das Bild zeichnen:

HDC hdc2 = GetDC(hWnd); 
Gdiplus::Graphics graphics(hdc2); 
Gdiplus::Image gdiImage(L"unt.png"); 
graphics.DrawImage(&gdiImage, 40, 40); 

Auch wenn ich BeginPaint() und EndPaint() es schlägt immer noch fehl. Gibt es eine Möglichkeit, das Bild außerhalb von WM_PAINT zu zeichnen?

+1

Wenn Sie es in WM_CREATE tun, dann tun Sie es zu früh, das Fenster ist noch nicht sichtbar. Wenn Sie es in einem Button-Click-Handler tun, funktioniert es wahrscheinlich, aber Sie können es einfach nicht sehen, da es eine Millisekunde später wieder übermalt wird. Nun, deshalb gibt es WM_PAINT, es sagt dir zuverlässig, wann du * malen * sollst. –

Antwort

4

In Win32 muss fast alle Zeichnung in WM_PAINT-Handler geschehen. Wahrscheinlich sehen Sie keine Zeichnung, denn sobald Sie fertig sind, den Knopf zu drücken, erhalten Sie eine WM_PAINT.

Wenn Sie außerhalb von WM_PAINT zeichnen, haben Ihre Zeichnungen eine kurze Lebensdauer, da Windows ungültig ist und dann die Meldung WM_PAINT angezeigt wird.

So ist der richtige Weg zum Zeichnen in Win32 der WM_PAINT-Handler.

Ich habe die Antwort nach einem Kommentar des Autors bearbeitet. Angenommen, Sie müssen das Bild nach einem Mausklick ändern. Sie können:

case WM_PAINT: { 
    hdc = BeginPaint(hWnd, &ps); 
    Gdiplus::Graphics graphics(hdc); 
    Gdiplus::Image gdiImage(clicked ? L"image_A.png" : L"image_B.png"); 
    graphics.DrawImage(&gdiImage, 40, 40); 
    EndPaint(hWnd, &ps); 
    break; 

} 
case WM_LBUTTONDOWN: { 
    clicked = true; 
    InvalidateRect(hwnd, NULL, true); 
    break; 
} 

Die InvalidateRect-Funktion ist die Antwort. Mit dieser Funktion weisen Sie Windows an, das Fenster neu zu zeichnen. Dies ist der Link zur man-Seite: InvalidateRect

+0

Wie kann ich in diesem Fall ein Bild beim Klicken auf die Schaltfläche oder einfach beim Erstellen eines Fensters zeichnen? – DimChtz

+0

Weil wenn ich in WM_PAINT zeichne. Bild wird nur gezeichnet, wenn ich die Größe des Fensters ändere. – DimChtz

1

Wenn Sie ein Bild basierend auf einem Klick (oder einem anderen Windows Event-Handler) aktualisieren müssen, müssen Sie den Bereich ungültig machen, den das Bild auf dem Bildschirm einnimmt - normalerweise durch InvalidateRect() -und dann haben Sie Ihre WM_PAINT Handler das Bild zeichnen.

+0

Ich habe das verwendet, aber immer noch scheitert: RECT rcClient; \t \t \t GetClientRect (hWnd, & rcClient); \t \t \t InvalidateRect (hWnd, & rcClient, true); \t \t \t UpdateWindow (hWnd); – DimChtz

+1

@DimChtz Sie müssen den Client nicht rect, übergeben Sie einfach 'NULL' zu' InvalidateRect'. Sie müssen 'UpdateWindow' nicht aufrufen, Windows generiert automatisch eine 'WM_PAINT'-Nachricht. –

Verwandte Themen