2016-11-27 12 views
0

マウスの左ボタンが押された場所にビットマップを表示する簡単なウィンドウプログラムを作成します。初めてマウスの左ボタンをクリックすると、ビットマップが表示されます。しかし、2回目の言葉では、マウスを左クリックした場所にビットマップが表示されません。ここでWindows C:LoadBitmap()関数が機能していません

は、コードが日曜日から7種類の方法について間違っている

LRESULT CALLBACK myHandler(HWND hw, UINT m, UINT mextra, long co_ord) 
{ 
HDC hdc, hmemdc; 
PAINTSTRUCT ps; 
HBITMAP hbmp; 
RECT r; 
HGDIOBJ holdbmp; 
int x, y; 

switch(m) 
{ 
case WM_LBUTTONDOWN: 

    hdc = BeginPaint(hw,&ps); 
    hmemdc = CreateCompatibleDC(hdc); 
    hbmp = LoadBitmap(h, MAKEINTRESOURCE(IDB_BITMAP1)); 
    holdbmp = SelectObject(hmemdc, hbmp); 
    x = LOWORD(co_ord); 
    y = HIWORD(co_ord); 
    BitBlt(hdc, x, y, 190, 220, hmemdc, 0, 0, SRCCOPY); 
    EndPaint(hw,&ps); 

    SelectObject(hmemdc, holdbmp); 
    DeleteObject(hbmp); 
    DeleteDC(hmemdc); 
    DeleteDC(hdc); 
    break; 
case WM_DESTROY: 
    PostQuitMessage(0); 
    break; 
default: 
    return DefWindowProc(hw,m,mextra,co_ord); 

} 
return 0L; 
} 
+0

'DeleteDC(hdc);'はまったく存在してはいけません。 'BeginPaint'から返されたDCのデバイスコンテクストのクリーンアップはあなたが既に呼び出した' EndPaint'によって管理されます。さらに重要なことに、 'BeginPaint' /' EndPaint'は 'WM_PAINT'への応答でない限り*呼び出されるべきではありません。 – WhozCraig

+0

Thank You WhozCraig、BeginPaint()、EndPaint()、DeleteDC()を削除しました。代わりにGetDC()関数を使用しました。私は働いています.... – Sai

+0

覚えておいてください:あなたが 'Get'と' Delete'をあなたが '作成する'あなたのケースでは、 'GetDC'がクライアントDCを取得するならば、それを終了したときに結果として生じる「ReleaseDC」を含む。がんばろう。 – WhozCraig

答えて

3

.........私のコードです。 WhozCraigのコメントに対する変更の後でさえ、それはまだ間違っています。

最初にBeginPaintEndPaintと呼ぶことができる場所はWM_PAINTというメッセージに対応しています。 WM_LBUTTONDOWNメッセージに応答してこれらの関数を呼び出そうとしています。それはうまくいかない。あなたは、メッセージハンドラ内でInvalidateRect()関数を呼び出し、ウィンドウハンドルを渡し、無効化する(ウィンドウ全体を無効にする)NULLという関数を呼び出すことで、WM_PAINTメッセージをトリガすることができます。次に、WM_PAINTメッセージハンドラの内部でBeginPaint/EndPaintと呼び出して、図面を作成することができます。マウスの左ボタンが押されているかどうかによって図面が異なるようにするには、WM_LBUTTONDOWNメッセージハンドラの中にフラグを設定し、WM_PAINTメッセージハンドラ内でそのフラグの値をテストするか、 GetKeyStateを押して、マウスボタンがダウンしているかどうかを確認します(VK_LBUTTON)。

GDIオブジェクトをリリース/破棄していないため、GDIオブジェクトも漏洩しています。 LoadBitmapでロードされたビットマップは、DeleteObjectを呼び出すことによって破棄する必要があります。 (ただし、WM_PAINTメッセージハンドラの内部でビットマップを繰り返しロードすると、パフォーマンスが低下する可能性があります。代わりに、WM_CREATEメッセージに応答してビットマップを1回ロードし、そのハンドルをグローバルまたはクラスレベルの変数にキャッシュして使用します

LOWORDHIWORDマクロはカーソル座標抽出するために使用されることはないべき必要な場合、及びWM_DESTROYメッセージに応答して、そのハンドルを介してビットマップを破壊します。)。これらは、複数のモニターシステムで間違った結果を返す可能性があります。代わりに、GET_X_LPARAMGET_Y_LPARAMを使用してください。これは、WM_LBUTTONDOWNメッセージのMSDNドキュメントに具体的に記載されています。 常にあなたによく慣れていないことのドキュメントをお読みください!

最後に、ウィンドウプロシージャの署名もです。完全にが間違っています。私はあなたがその署名をどこに持っているのか分かりませんが、それらの引数の実際の意味を隠す非標準のパラメータ名を持っているだけでなく、間違った型を持っています。ウィンドウプロシージャは、次のようになります

LRESULT CALLBACK myHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
{ 
    ... 
} 

ちょうどあなたがMSDNのドキュメントを読んに関する規律されていない場合は特に、周りのハッキングすることによって、Windows APIプログラミングを学ぶことは非常に困難です。あなたが本当にそれを学びたいなら、Charles Petzold's classic Programming Windows, 5th editionのような本の購入を検討してください(はい、あなたは新しい版ではなく、5版が必要です)。

関連する問題