Here's a minimal example:
void CSDIView::OnLButtonDown(UINT nFlags, CPoint point)
{
m_ptStart = point;
m_ptEnd = point;
SetCapture();
}
void CSDIView::OnMouseMove(UINT nFlags, CPoint point)
{
if (GetCapture() == this)
{ m_ptEnd = point;
Invalidate();
}
}
void CSDIView::OnLButtonUp(UINT nFlags, CPoint point)
{
if (GetCapture() == this)
{ ReleaseCapture();
m_ptEnd = point;
Invalidate();
}
}
void CSDIView::OnDraw(CDC* pDC)
{
CRect r(m_ptStart, m_ptEnd);
pDC->Rectangle(&r);
}
--
Scott McPhillips [VC++ MVP]
I've modified your code in OnMouseMove to support SDI applications. It
seems to be working fine. Please reply otherwise.
void CXxxDlg::OnMouseMove(UINT nFlags, CPoint point)
{
if (GetCapture() == this)
{
m_ptEnd = point;
Invalidate();
}
CRect r(m_ptStart, m_ptEnd);
CPaintDC dc(this);
dc.GetSafeHdc();
dc.Rectangle(&r);
Why are you drawing your rectangle in the OnMouseMove method? All your
drawing code should be in OnPaint, just the way Scott posted it.
In your OnMouseMove, while there is capture you are recording the endpoint
and then invalidating the client area which will cause a WM_PAINT to get
posted after OnMouseMove returns, and then drawing a rect which will get
erased when the WM_PAINT from the Invalidate() call gets processed.
Anyway drawing anything in OnMouseMove is pointless.
AliR.
"Charles Tam" <Charl...@discussions.microsoft.com> wrote in message
news:B1E93C60-C653-45DA...@microsoft.com...
CPaintDC is specialized for use only in a WM_PAINT handler. It is an error
to use it elsewhere. When painting outside of a WM_PAINT handler you should
use CClientDC.
It also does not make sense to call Invalidate() and then paint. The
Invalidate() is going to cause WM_PAINT as soon as you return, and that will
erase or overwrite your illegal painting.
Why are you trying to paint on a dialog?
CPoint anchor;
CPoint endpoint;
void CMyClass::OnLButtonDown(...CPoint point)
{
anchor = endpoint = point;
CClientDC dc(this);
dc.DrawFocusRect(anchor.x, anchor.y, endpoint.x, endpoint.y);// very small rectangle
SetCapture();
}
void CMyClass::OnMouseMove(..., CPoint point)
{
if(GetCapture() != NULL)
{ /* rubber band */
CClientDC dc(this);
dc.DrawFocusRect(anchor.x, anchor.y, endpoint.x, endpoint.y);
endpoint = point;
dc.DrawFocusRect(anchor.x, anchor.y, endpoint.x, endpoint.y);
} /* rubber band */
void CMyClass::OnLButtonUp(..., CPoint point)
{
if(GetCapture() != NULL)
{ /* banding */
CClientDC dc(this);
dc.DrawFocusRect(anchor.x, anchor.y, endpoint.x, endpoint.y);
Selection = CRect(anchor.x, anchor.y, point.x, point.y);
ReleaseCapture();
InvalidateRect(&Selection);
} /* banding */
I think DrawFocusRect does an xor; if not, you will have to SetROP2 to select a
complementing mode.
The advantage of this technique is that it doesn't require redrawing everything, or for
that matter, anything, until the selection process has finished.
joe
On Sun, 30 Mar 2008 17:07:00 -0700, Charles Tam <Charl...@discussions.microsoft.com>
wrote:
>In MFC 6, how do I draw a rectangle via a mouse drag?
>Is there any example code I could look at?
Joseph M. Newcomer [MVP]
email: newc...@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
>Hi Scott,
>
>I've modified your code in OnMouseMove to support SDI applications. It
>seems to be working fine. Please reply otherwise.
>
>void CXxxDlg::OnMouseMove(UINT nFlags, CPoint point)
>{
>if (GetCapture() == this)
****
GetCapture only has to be non-NULL. If you have capture, you get the message; if you
don't have capture, you're not in dragging mode. No need to compare to this
*****
>{
>m_ptEnd = point;
>Invalidate();
*****
See my later post; typically you do not Invalidate() the whole area, or any part of it,
during dragging
****
>}
>
>CRect r(m_ptStart, m_ptEnd);
>CPaintDC dc(this);
****
This makes no sense here. CPaintDC can only be used in OnPaint handlers
****
>dc.GetSafeHdc();
****
This makes no sense because it does nothing.
****
>dc.Rectangle(&r);
****
Probably wrong; you did not select the HOLLOW_BRUSH to fill, so you will get a solid white
rectangle that will overwrite everything. See my example.
Note that SDI is no different from any CWnd, so it is not clear what you had to "change"
to use it with SDI.
****
>}
>
>
>
>"Scott McPhillips [MVP]" wrote:
>
>> "Charles Tam" <Charl...@discussions.microsoft.com> wrote in message
>> news:8CA07CA7-F2AE-432F...@microsoft.com...
>> > In MFC 6, how do I draw a rectangle via a mouse drag?
>> > Is there any example code I could look at?
>> >
>>
>> Here's a minimal example:
>>
>> void CSDIView::OnLButtonDown(UINT nFlags, CPoint point)
>> {
>> m_ptStart = point;
>> m_ptEnd = point;
>> SetCapture();
>> }
>>
>> void CSDIView::OnMouseMove(UINT nFlags, CPoint point)
>> {
>> if (GetCapture() == this)
>> { m_ptEnd = point;
>> Invalidate();
>> }
>> }
>>
>> void CSDIView::OnLButtonUp(UINT nFlags, CPoint point)
>> {
>> if (GetCapture() == this)
>> { ReleaseCapture();
>> m_ptEnd = point;
>> Invalidate();
>> }
>> }
>>
>> void CSDIView::OnDraw(CDC* pDC)
>> {
>> CRect r(m_ptStart, m_ptEnd);
>> pDC->Rectangle(&r);
>> }
>>
>>
>> --
>> Scott McPhillips [VC++ MVP]
>>
>>
I am new to C++,I tried the first, Drawing a rectangle via mouse drag? example by Scott McPhillips , it works fine ,, but
the 2ed example
Drawing a rectangle via mouse drag? by Joseph M. errors out saying
error C2660: 'DrawFocusRect' : function does not take 4 parameters.
Please let me know how to draw transparent rectangle , with a solid drak border.
Thanks
Priyanka
There are two DrawFocusRect functions, one is an API and one is a CDC member
function. Neither one of them takes 4 parameters! Neither one of them
draws with a solid dark border!
Why do you have 4 parameters? Perhaps you should show your code.
--
Ajay
"priyanka k" wrote in message news:200872517541...@gmail.com...