473,382 Members | 1,386 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Mouse Dragging and drawing a rectangle


I am drawing a rectangle on a picture that has already been drawn
on the graphics area (a user control). It works something like this:

//in the MouseDown event
m_isDragging = true;
m_oldX = e.X; //save original positions
m_oldY = e.Y;

//in the MouseMove event
if (m_isDragging)
{
m_newX = e.X;
m_newY = e.Y;
int firstX = (m_newX < m_oldX) ? m_newX : m_oldX;
int firstY = (m_newY < m_oldY) ? m_newY : m_oldY;
m_diffX = Math.Abs(m_oldX - m_newX);
m_diffY = Math.Abs(m_oldY - m_newY);
Graphics g = Graphics.FromHwnd(this.Handle);
Rectangle myRectangle =
new Rectangle(firstX, firstY, m_diffX, m_diffY);
g.DrawRectangle(m_myPen, myRectangle);
g.Dispose();
Invalidate(myRectangle);
}

//in the MouseUp event
if (m_isDragging)
{
m_isDragging = false;
//save the position and size of the rectangle (code snipped)

//invalidate the whole usercontrol (which is just the panel
// on which the picture was already painted)
this.Invalidate();

}

This works great when you keep drawing the rectangle bigger.

But if you backtrack while dragging, it leaves the remnants
of the rectangles you have already drawn behind.

How do I handle that?

I've tried saving thd old rectangle and invalidating that
when drawing the new rectangle, like this:

Rectangle m_oldRectangle;
//in the MouseMove event
if (m_isDragging)
{
m_newX = e.X;
m_newY = e.Y;
int firstX = (m_newX < m_oldX) ? m_newX : m_oldX;
int firstY = (m_newY < m_oldY) ? m_newY : m_oldY;
m_diffX = Math.Abs(m_oldX - m_newX);
m_diffY = Math.Abs(m_oldY - m_newY);
Graphics g = Graphics.FromHwnd(this.Handle);
Rectangle myRectangle =
new Rectangle(firstX, firstY, m_diffX, m_diffY);

g.DrawRectangle(m_myPen, myRectangle);
g.Dispose();

//I'd probably want to use whichever rectangle is larger here,
// but I'm just trying this to see what it does.
Invalidate(m_oldRectangle); //instead of myRectangle

//save the old rectangle
m_oldRectangle =
new Rectangle(firstX, firstY, m_diffX, m_diffY);
}

This doesn't work either.

Any other ideas? I'd appreciate any help you can provide.

Thanks in advance,
Robin S.
Aug 24 '07 #1
4 26890
RobinS wrote:
This works great when you keep drawing the rectangle bigger.

But if you backtrack while dragging, it leaves the remnants
of the rectangles you have already drawn behind.

How do I handle that?
The biggest thing wrong that I see with your code is that you are
drawing the rectangle in the MouseMove event handler. You should only
be drawing anything, selection rectangle included, in your Paint event
handler. (replace "XXX event handler" with "OnXXX override method" as
appropriate :) ).

The second version of MouseMove handling you posted appears to me that
it would have the opposite problem, erasing the newly-drawn rectangle
just after you've drawn it. Sticking as closely to the code you've
posted, I think this would be better:

Rectangle m_oldRectangle;
//in the MouseMove event
if (m_isDragging)
{
m_newX = e.X;
m_newY = e.Y;
int firstX = (m_newX < m_oldX) ? m_newX : m_oldX;
int firstY = (m_newY < m_oldY) ? m_newY : m_oldY;
m_diffX = Math.Abs(m_oldX - m_newX);
m_diffY = Math.Abs(m_oldY - m_newY);
Rectangle myRectangle =
new Rectangle(firstX, firstY, m_diffX, m_diffY);

// Invalidate the combined rectangles, to ensure that
// the old rectangle is erased and the new one is drawn
Invalidate(Rectangle.Union(m_oldRectangle, myRectangle));

//save the old rectangle
m_oldRectangle = myRectangle;
}

Then in the Paint event:

e.Graphics.DrawRectangle(m_myPen, m_oldRectangle);

Of course, you probably would want to rename m_oldRectangle so that it
more accurate reflects the "current" nature of the rectangle. :)

Pete
Aug 24 '07 #2

"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:13*************@corp.supernews.com...
RobinS wrote:
>This works great when you keep drawing the rectangle bigger.

But if you backtrack while dragging, it leaves the remnants
of the rectangles you have already drawn behind.

How do I handle that?

The biggest thing wrong that I see with your code is that you are drawing
the rectangle in the MouseMove event handler. You should only be drawing
anything, selection rectangle included, in your Paint event handler.
(replace "XXX event handler" with "OnXXX override method" as appropriate
:) ).

The second version of MouseMove handling you posted appears to me that it
would have the opposite problem, erasing the newly-drawn rectangle just
after you've drawn it. Sticking as closely to the code you've posted, I
think this would be better:

Rectangle m_oldRectangle;
//in the MouseMove event
if (m_isDragging)
{
m_newX = e.X;
m_newY = e.Y;
int firstX = (m_newX < m_oldX) ? m_newX : m_oldX;
int firstY = (m_newY < m_oldY) ? m_newY : m_oldY;
m_diffX = Math.Abs(m_oldX - m_newX);
m_diffY = Math.Abs(m_oldY - m_newY);
Rectangle myRectangle =
new Rectangle(firstX, firstY, m_diffX, m_diffY);

// Invalidate the combined rectangles, to ensure that
// the old rectangle is erased and the new one is drawn
Invalidate(Rectangle.Union(m_oldRectangle, myRectangle));

//save the old rectangle
m_oldRectangle = myRectangle;
}

Then in the Paint event:

e.Graphics.DrawRectangle(m_myPen, m_oldRectangle);

Of course, you probably would want to rename m_oldRectangle so that it
more accurate reflects the "current" nature of the rectangle. :)

Pete
Thanks for your quick response.

1) The events are actual events. I just didn't want to put the
signature in there because I was re-typing rather than copying
and pasting. I keep trying to drag text over from my desktop
(work) machine to my laptop (personal) machine, but it just won't
go past the edge of the desktop, dang it.

2) Ah, the paint event. So here's the deal. I have a picture,
and I have a bunch of attributes that are applied to the picture.
(This is all part of an image editor.) So the user can add text,
rotate, draw rectangles, crop, etc. All of those attributes are
stored, and when the picture is displayed, there is a routine
called by the Paint event that loads the picture, applies the
attributes, and returns a finished bitmap, which is displayed
by the Paint event. In this way, we can allow the user to go
back and edit the attributes w/o losing any clarity or anything
else about the original picture.

The MouseDown draws the rectangle "temporarily". After the user
lets go of the mouse, the panel is invalidated, invoking the
Paint event, which calls the routine to load the picture
and apply the attributes, one of which is the newly stored
rectangle (storing X, Y, width, and height % in case they
change the size of the image).

All of that is working great. I'm just having trouble
with the interim MouseMove drawing of the rectangle on the
picture.

Despite what you think it might do, the code in my original
post works except when you reverse direction when drawing
the rectangle.

I tried changing Invalidate(myRectangle)
or Invalidate(oldRectangle)
to
Invalidate(Rectangle.Union(m_oldRectangle, m_Rectangle));
but it didn't help.

Any other ideas? Is there a way to invalidate just that area
so the entire thing doesn't repaint? Am I really going to
have to rewrite my Paint event to handle this, and how would
I invoke it from MouseMove? I don't really want to invalidate
the whole panel if I can help it.

Thx,
Robin S.
Aug 24 '07 #3

"RobinS" <Ro****@NoSpam.yah.nonewrote in message
news:zN******************************@comcast.com. ..
>
"Peter Duniho" <Np*********@NnOwSlPiAnMk.comwrote in message
news:13*************@corp.supernews.com...
>RobinS wrote:
>>This works great when you keep drawing the rectangle bigger.

But if you backtrack while dragging, it leaves the remnants
of the rectangles you have already drawn behind.

How do I handle that?

The biggest thing wrong that I see with your code is that you are
drawing the rectangle in the MouseMove event handler. You should only
be drawing anything, selection rectangle included, in your Paint event
handler. (replace "XXX event handler" with "OnXXX override method" as
appropriate :) ).

The second version of MouseMove handling you posted appears to me that
it would have the opposite problem, erasing the newly-drawn rectangle
just after you've drawn it. Sticking as closely to the code you've
posted, I think this would be better:

Rectangle m_oldRectangle;
//in the MouseMove event
if (m_isDragging)
{
m_newX = e.X;
m_newY = e.Y;
int firstX = (m_newX < m_oldX) ? m_newX : m_oldX;
int firstY = (m_newY < m_oldY) ? m_newY : m_oldY;
m_diffX = Math.Abs(m_oldX - m_newX);
m_diffY = Math.Abs(m_oldY - m_newY);
Rectangle myRectangle =
new Rectangle(firstX, firstY, m_diffX, m_diffY);

// Invalidate the combined rectangles, to ensure that
// the old rectangle is erased and the new one is drawn
Invalidate(Rectangle.Union(m_oldRectangle, myRectangle));

//save the old rectangle
m_oldRectangle = myRectangle;
}

Then in the Paint event:

e.Graphics.DrawRectangle(m_myPen, m_oldRectangle);

Of course, you probably would want to rename m_oldRectangle so that it
more accurate reflects the "current" nature of the rectangle. :)

Pete

Thanks for your quick response.

1) The events are actual events. I just didn't want to put the
signature in there because I was re-typing rather than copying
and pasting. I keep trying to drag text over from my desktop
(work) machine to my laptop (personal) machine, but it just won't
go past the edge of the desktop, dang it.

2) Ah, the paint event. So here's the deal. I have a picture,
and I have a bunch of attributes that are applied to the picture.
(This is all part of an image editor.) So the user can add text,
rotate, draw rectangles, crop, etc. All of those attributes are
stored, and when the picture is displayed, there is a routine
called by the Paint event that loads the picture, applies the
attributes, and returns a finished bitmap, which is displayed
by the Paint event. In this way, we can allow the user to go
back and edit the attributes w/o losing any clarity or anything
else about the original picture.

The MouseDown draws the rectangle "temporarily". After the user
lets go of the mouse, the panel is invalidated, invoking the
Paint event, which calls the routine to load the picture
and apply the attributes, one of which is the newly stored
rectangle (storing X, Y, width, and height % in case they
change the size of the image).

All of that is working great. I'm just having trouble
with the interim MouseMove drawing of the rectangle on the
picture.

Despite what you think it might do, the code in my original
post works except when you reverse direction when drawing
the rectangle.

I tried changing Invalidate(myRectangle)
or Invalidate(oldRectangle)
to
Invalidate(Rectangle.Union(m_oldRectangle, m_Rectangle));
but it didn't help.

Any other ideas? Is there a way to invalidate just that area
so the entire thing doesn't repaint? Am I really going to
have to rewrite my Paint event to handle this, and how would
I invoke it from MouseMove? I don't really want to invalidate
the whole panel if I can help it.

Thx,
Robin S.
I tried out what you recommended. If I add it to the paint event,
I'm going to have to repaint the picture under the rectangle
every time, because if I don't, it only shows a black square.

I believe this will make it difficult (if not impossible) for
the user to draw a rectangle around something on the picture. ;-)

I'm afraid if I repaint the entire image as they drag, it will
flicker, and I suspect I did that first and then changed it to
do this. This is a long-standing bug that I have managed to
avoid fixing for a couple of months, but now I've fixed all
the other ones, and have only this one (that I know of) left.

Thanks,
Robin S.
Aug 24 '07 #4
"RobinS" <Ro****@NoSpam.yah.noneha scritto nel messaggio
news:EN******************************@comcast.com. ..

Any other ideas? I'd appreciate any help you can provide.
Try my graphic library:
http://www.codeproject.com/useritems...hic_engine.asp
It already does all what you need and much more.

--
Help The New .Net Site! http://www.devbox4.net
Aug 25 '07 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: sachin | last post by:
Please read the code snippets belo snippet 1: Drawing rectangle using Device Context...
4
by: Stuart Norris | last post by:
Dear Readers, I am attempting to draw box around some text using unicode on multiline label. The label is forty characters wide and 12 lines deep. I have been trying to draw a box around text...
13
by: Lars Netzel | last post by:
Hi! I have a round area which I want to be able to move the mouse over and fire off events... how do I do that? I have drawn a FillPie Graphics and I feel that there has to be a way of...
1
by: YYZ | last post by:
Sorry for the multipost, but no one was responding in the other thread. If any solution is forthcoming, I will return to the original thread and post it there as well. I've created a usercontrol...
3
by: Ivonne Riedel | last post by:
Working on an incremental drawing algorithm I am facing a problem PInvoking ScrollWindowEx: The code is as follows... C#: public static extern int ScrollWindowEx(IntPtr hWnd, int dx, int...
2
by: psmukilan | last post by:
How to draw a rectangle using Javascript on the aspx page. This is like a selector control box. from the point of Mouse down till we release th mouse, it should draw the rectangle. Just like...
6
by: A2K | last post by:
Hi, I have made an applicationa in C#(VS 2005), which allows the user to plot and zoom a graph. while zooming, the user drags the mouse to specify a rectangular area, which is then magnified. ...
2
by: qhimq | last post by:
To download source and executable: https://netfiles.uiuc.edu/qmitche2/www/mouse/ #include <windows.h> //#include <stdio.h> // Variables HWND hwndMain; // Main window HWND // Functions
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.