2016-03-18 12 views
5

GDI +を使用して画像を描画しようとしています。私はWM_PAINT内でそれを行うとき、それは動作します:GDI + Graphics :: DrawImageが機能しません。

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; 

} 

しかし、私はボタンのクリックやWM_CREATEの内側にそれを行う際には、画像を描画していません:

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

私はBeginPaint()EndPaint()を使用する場合でもそれでも失敗します。では、WM_PAINTの外に画像を描画する方法はありますか?

+1

WM_CREATEで実行した場合、早すぎるとウィンドウが表示されません。あなたがボタンクリックハンドラでそれを行うと、それはおそらく動作しますが、それはミリ秒後にもう一度塗り直されるので、それを見ることはできません。さて、WM_PAINTが存在する理由は、それが確実にあなたが*ペイントすべきであることを伝えます。 –

答えて

4

Win32では、ほぼすべての描画がWM_PAINTハンドラで行われる必要があります。 おそらく、ボタンのクリックを処理するとすぐにWM_PAINTを受け取るため、図面は表示されません。

WM_PAINTの外に描画すると、ウィンドウの無効化とWM_PAINTメッセージのために図面の寿命が短くなります。

Win32で描画する正しい方法は、WM_PAINTハンドラです。

私は著者のコメントの後に答えを編集しました。 マウスをクリックした後にイメージを変更する必要があるとします。次のようにすることができます。

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

InvalidateRect関数が答えです。この関数を使用すると、ウィンドウを再描画するようにWindowsに指示します。 InvalidateRect

+0

その場合、ボタンをクリックしたとき、または単にウィンドウを作成したときに、どのように画像を描くことができますか? – DimChtz

+0

なぜ私はWM_PAINTの中に描画します。ウィンドウのサイズを変更したときにのみ画像を描画します。 – DimChtz

1

ボタンクリック(または他のWindowsイベントハンドラ)に基づいて画像を更新する必要がある場合は、画像が画面上で占める領域を無効にする必要があります通常はInvalidateRect()を経由して、WM_PAINTハンドラに画像を描画させます。

+0

私はこれを使用しましたが、まだ失敗します:RECT rcClient; \t \t \t GetClientRect(hWnd、&rcClient); \t \t \t InvalidateRect(hWnd、&rcClient、true); \t \t \t UpdateWindow(hWnd); – DimChtz

+1

@DimChtzクライアントを取得する必要はありません。単にInvalidateRectにNULLを渡すだけです。そして 'UpdateWindow'を呼び出す必要はなく、Windowsは自動的に' WM_PAINT'メッセージを生成します。 –

関連する問題