2016-03-18 13 views
5

Próbuję narysować obraz przy użyciu GDI +. Kiedy to zrobić wewnątrz WM_PAINT to działa:GDI + Grafika :: DrawImage nie działa

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; 

} 

Ale kiedy robię to na kliknięcie przycisku lub wewnątrz WM_CREATE nie rysować obraz:

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

Nawet jeśli używam BeginPaint() i EndPaint() nadal się nie udaje. Czy istnieje sposób na narysowanie obrazu poza numerem WM_PAINT?

+1

Jeśli zrobisz to w WM_CREATE, to zrobisz to za wcześnie, okno nie jest jeszcze widoczne. Kiedy robisz to w procedurze obsługi przycisku, to prawdopodobnie działa, ale po prostu nie możesz go zobaczyć, ponieważ zostaje ponownie zamalowany ponownie o milisekundę później. Cóż, właśnie dlatego istnieje WM_PAINT, niezawodnie mówi, kiedy * powinieneś * malować. –

Odpowiedz

4

W Win32, prawie wszystkie rysunki muszą się zdarzyć w procedurze WM_PAINT. Prawdopodobnie nie widać żadnego rysunku, ponieważ po ukończeniu obsługi kliknięcia przycisku otrzymasz WM_PAINT.

W przypadku rysowania poza WM_PAINT rysunek ma krótką żywotność z powodu unieważnienia okien, a następnie komunikatu WM_PAINT.

Poprawnym sposobem narysowania w Win32 jest obsługa WM_PAINT.

Edytowałem odpowiedź po komentarzu autora. Załóżmy, że musisz zmienić obraz po kliknięciu myszą. Możesz zrobić:

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

Funkcja InvalidateRect jest odpowiedzią. Za pomocą tej funkcji powiadamiasz system Windows, aby przerysował okno. To jest link do strony man: InvalidateRect

+0

W takim przypadku, w jaki sposób mogę narysować obraz po kliknięciu przycisku lub po prostu po utworzeniu okna? – DimChtz

+0

Bo kiedy rysuję wewnątrz WM_PAINT. Rysowanie obrazu tylko przy zmianie rozmiaru okna. – DimChtz

1

Jeśli chcesz zaktualizować obraz w oparciu o kliknięcie przycisku (lub inny program obsługi zdarzeń Windows), musisz unieważnić obszar zajmowany przez obraz na ekranie - zwykle przez InvalidateRect() - a następnie poproś o zdjęcie swojego operatora WM_PAINT.

+0

Użyłem tego, ale nadal się nie udało: RECT rcClient; \t \t \t GetClientRect (hWnd, & rcClient); \t \t \t InvalidateRect (hWnd, & rcClient, true); \t \t \t UpdateWindow (hWnd); – DimChtz

+1

@DimChtz nie potrzebujesz klienta, wystarczy przekazać 'NULL' do' InvalidateRect'. I nie trzeba wywoływać 'UpdateWindow', system Windows automatycznie wygeneruje komunikat' WM_PAINT'. –