CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    May 2007
    Posts
    9

    HELP: I need to display a Selection Rectangle

    I am writing an image processing program for which I need to crop the image. I need to display a selection rectangle for this purpose and update its dimensions in the OnMouseMove() function. Also I need to repaint the window because the previously drawn rectangle should be erased (otherwise this causes a filled rectangle to be drawn). But this causes flickering of the window as my OnPaint() function takes some time to paint the window. How can I display the selection rectangle (is there any other way) without my window contents flickering and also update the selection rectangle's contents on mouse move.

  2. #2
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,244

    Re: HELP: I need to display a Selection Rectangle

    Drawing a selection rectangle is one of few examples in which you dont need (and it's not a good idea) to draw in WM_PAINT message handler (or in MFC's CView::OnDraw function).
    You just have to simply draw a rectangle by previously call SetROP2(R2_NOT) which allows to "delete" the old selection).
    Here is a sample code:
    Code:
    class CMyView : public CView
    {
    // ...
    // Attributes
    protected:
       CRect  m_rcTrack;
       CPoint m_ptStartTrack;
       // ...
    // Implementation
    protected:
       void DrawSelection();
    };
    Code:
    void CMyView::OnLButtonDown(UINT nFlags, CPoint point) 
    {
       m_rcTrack.SetRectEmpty();
       m_ptStartTrack = point;
       CRect rcClient;
       GetClientRect(rcClient);
       ClientToScreen(rcClient);
       ::ClipCursor(rcClient); 
       SetCapture();
       CView::OnLButtonDown(nFlags, point);
    }
    void CMyView::OnMouseMove(UINT nFlags, CPoint point) 
    {
       if(MK_LBUTTON & nFlags)
       {
          // remove the old selecton
          DrawSelection();
          m_rcTrack.SetRect(m_ptStartTrack, point);
          m_rcTrack.NormalizeRect();
          // draw the new selection
          DrawSelection();
       }
       CView::OnMouseMove(nFlags, point);
    }
    void CMyView::OnLButtonUp(UINT nFlags, CPoint point) 
    {
       ::ClipCursor(NULL);
       ::ReleaseCapture();
       // send, for an example, a message signaling end selection,
       // and then... remove it
       DrawSelection();
       CView::OnLButtonUp(nFlags, point);
    }
    void CMyView::DrawSelection()
    {
       CClientDC dc(this);
       int nROP2Old = dc.SetROP2(R2_NOT);
       dc.MoveTo(m_rcTrack.left, m_rcTrack.top);
       dc.LineTo(m_rcTrack.right, m_rcTrack.top);
       dc.LineTo(m_rcTrack.right, m_rcTrack.bottom);
       dc.LineTo(m_rcTrack.left, m_rcTrack.bottom);
       dc.LineTo(m_rcTrack.left, m_rcTrack.top);
       dc.SetROP2(nROP2Old);
    }
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

  3. #3
    Join Date
    May 2007
    Posts
    9

    Re: HELP: I need to display a Selection Rectangle

    Thanks a lot!

    That helped a lot. I was stuck here because a lot of my filters required a selection. So thanks again.

    The selection rectangle is being drawn in some arbitrary color though. Can I make it of a uniform color by OR'ing the R2_NOT with something else? Also, is there something like R2_NOT which'll blend the old color with the new one so that I can get a translucent selection rectangle?

  4. #4
    Join Date
    Nov 2006
    Posts
    1,611

    Re: HELP: I need to display a Selection Rectangle

    Code:
    The selection rectangle is being drawn in some arbitrary color though. Can I make it of a uniform color by OR'ing the R2_NOT with something else? Also, is there something like R2_NOT which'll blend the old color with the new one so that I can get a translucent selection rectangle?
    That's the one thing that logical (binary) operations can't do.

    They're quick and efficient (no memory impact), but you have no control over the resulting color of the results.

    If you want such effects (alpha blended, colored, etc.) - which as a design IS desirable - you'll have to use some kind of buffering technique which preserves the unaltered version.

    You'll end up blitting or otherwise copying (blitting by another name, non-OS method perhaps) from the unaltered copy to the output buffer (or display, if you're drawing directly on the display) in order to erase the previous position of the rectangle, then drawing the replacement in the new position, a la animation.

    That can be fast enough, depending on hardware and the size of the target. Even a 1024 x 768 true color image can be blitted for such updates in the area of 30fps + ( each portion of the work will function in the range of 100fps on machines upwards of 1.5Ghz AMD, 2Ghz P4).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured