15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

OC42 ❘ ChaPTer 48 GrAphics with Gdi+<br />

In most cases, this will work. However, there could be a problem if your application (or even some other<br />

application with a high priority) is doing some computationally intensive work at the moment the user<br />

double-clicks. It just might happen in that case that the OnDoubleClick() event h<strong>and</strong>ler does not get called<br />

until perhaps half a second or so after the user has double-clicked. You do not want such delays because<br />

they usually annoy users intensely, but even so, occasionally it does happen <strong>and</strong> sometimes for reasons<br />

beyond the control of your application (a slow computer, for instance). The trouble is that half a second<br />

is easily enough time for the mouse to be moved halfway across the screen, in which case your call to<br />

Control.MousePosition will return the completely wrong location!<br />

A better approach here is to rely on one of the many overlaps between mouse event meanings. The first part<br />

of double-clicking a mouse involves pressing the left button down. This means that if OnDoubleClick() is<br />

called, you know that OnMouseDown() has also just been called, with the mouse at the same location. You<br />

can use the OnMouseDown() override to record the position of the mouse, ready for OnDoubleClick(). This<br />

is the approach taken in CapsEditor:<br />

protected override void OnMouseDown(MouseEventArgs e)<br />

{<br />

base.OnMouseDown(e);<br />

mouseDoubleClickPosition = new Point(e.X, e.Y);<br />

}<br />

Now look at the OnDoubleClick() override. There is quite a bit more work to do here:<br />

protected override void OnDoubleClick(EventArgs e)<br />

{<br />

int i = PageCoordinatesToLineIndex(mouseDoubleClickPosition);<br />

if (i >= 0)<br />

{<br />

TextLineInformation lineToBeChanged =<br />

(TextLineInformation)documentLines[i];<br />

lineToBeChanged.Text = lineToBeChanged.Text.ToUpper();<br />

Graphics dc = this.CreateGraphics();<br />

uint newWidth =(uint)dc.MeasureString(lineToBeChanged.Text,<br />

mainFont).Width;<br />

if (newWidth > lineToBeChanged.Width)<br />

lineToBeChanged.Width = newWidth;<br />

if (newWidth+2*margin > this.documentSize.Width)<br />

{<br />

documentSize.Width = (int)newWidth;<br />

AutoScrollMinSize = this.documentSize;<br />

}<br />

Rectangle changedRectangle = new Rectangle(<br />

LineIndexToPageCoordinates(i),<br />

new Size((int)newWidth,<br />

(int)this.lineHeight));<br />

Invalidate(changedRectangle);<br />

}<br />

base.OnDoubleClick(e);<br />

}<br />

code download CapsEditor.sln<br />

You start off by calling PageCoordinatesToLineIndex() to work out which line of text the mouse pointer<br />

was hovering over when the user double-clicked. If this call returns -1, then you weren’t over any text, so<br />

there is nothing to do — except, of course, call the base class version of OnDoubleClick() to let Windows<br />

do any default processing.<br />

Assuming that you have identified a line of text, you can use the string.ToUpper() method to convert<br />

it to uppercase. That was the easy part. The hard part is figuring out what needs to be redrawn where.<br />

Fortunately, because this example is simple, there are not too many combinations. You can assume that<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!