2017-05-06 9 views
1

私は、ユーザーがマウスの左ボタンを押し下げてマウスをどこかにドラッグし、「ボーダーのついた矩形」(下にあるものを示す四角形、基本的にはボーダー)を描画する機能を実装しようとしています。WM_MOUSEMOVEに枠線をドラッグして描画しますか?

は、私が何かは、このコードでの作業があります。

  case WM_MOUSEMOVE: 
       if (draw) { 
        endX = GET_X_LPARAM(lParam); 
        endY = GET_Y_LPARAM(lParam); 
        hdc = GetDC(hwnd); 
        SelectObject(hdc, GetStockObject(NULL_BRUSH)); 
        Rectangle(hdc, startX, startY, endX, endY); 
        ReleaseDC(hwnd, hdc); 
       } 
      break; 

(WM_LBUTTONDOWNが解雇とWM_LBUTTONUPが発射されたときにfalseに設定されている場合は引き分けがtrueに設定されています)。

これは次のようなものです。私は基本的にこれを望んでいます。内側に黒い線がなく、おそらく太い境界線があります。 enter image description here

私が抱えている問題は、矩形領域内で「失われた」ものを再描画する方法を理解できないことです。私は、私は、Rectangleの代わりにInvalidateRectを使用する必要があると思うが、WM_PAINTで再描画する方法がわからない。おそらく、私はこれとはまったく異なる方法に接近しているはずですか?これは私の初めてのWinapiです。デビッドHeffernanのに

+1

通常、ラバーバンディング(この方法でボックスを描く)では、背景上に単色が塗られず、代わりに背景とXORされます。行を消去するには、元の背景が戻ってくる同じ行をもう一度XORするという単純な問題です。 – enhzflep

+0

私は上記のように矩形を描画する前にROP2をXORPENに設定しようとしましたが、あなたの言うことに似ていますが、その関数では成功しませんでした: SetROP2(hdc、R2_XORPEN); – Zhinkk

+1

ここで例をご覧ください:https://msdn.microsoft.com/en-us/library/windows/desktop/dd145184(v=vs.85).aspx –

答えて

0

おかげで、私は解決策を持っている:

case WM_MOUSEMOVE: 
     if (draw) { 
      // Get current mouse position 
      endX = GET_X_LPARAM(lParam); 
      endY = GET_Y_LPARAM(lParam); 

      // Paint over previous rectangle 
      hdc = GetDC(hwnd); 
      hdcMem = CreateCompatibleDC(hdc); 
      hbmOld = (HBITMAP) SelectObject(hdcMem, screenshot); 
      BitBlt(hdc, 0, 0, fullW, fullH, hdcMem, 0, 0, SRCCOPY); 
      SelectObject(hdcMem, hbmOld); 

      // Change to NULL_BRUSH (no fill) 
      hBrush = (HBRUSH) GetStockObject(NULL_BRUSH); 
      hOldBrush = (HBRUSH) SelectObject(hdc, hBrush); 

      // Change to red pen 
      hPen = GetStockObject(DC_PEN); 
      hOldPen = SelectObject(hdc, hPen); 
      SetDCPenColor(hdc, RGB(255,0,0)); 

      // Draw new rectangle 
      Rectangle(hdc, startX, startY, endX, endY); 

      // Restore original brush and brush 
      SelectObject(hdc, hOldBrush); 
      SelectObject(hdc, hOldPen); 

      ReleaseDC(hwnd, hdc); 
      DeleteDC(hdcMem); 
     } 
    break; 

基本的に私は、描画が(スクリーンショットと呼ばれるビットマップで)始まる前に、ウィンドウのスクリーンショットを保存し、画面全体の上にマウスを移動するたびに描きます。 startXとstartYは、WM_LBUTTONDOWNが起動されたときに一度設定されます。画面全体を再描画するのは非常に効率が悪いと思いますが、再描画が必要な領域を部分的に描画してしまえば、動作させることができませんでした。パフォーマンスが問題だと思えば、私はこれに戻ってくるかもしれませんが、私のテストでは非常にスムーズでした。

関連する問題