<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://cm.megasolutions.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">GDI+</title><subtitle type="html" /><id>http://cm.megasolutions.net/blogs/gdi/atom.aspx</id><link rel="alternate" type="text/html" href="http://cm.megasolutions.net/blogs/gdi/default.aspx" /><link rel="self" type="application/atom+xml" href="http://cm.megasolutions.net/blogs/gdi/atom.aspx" /><generator uri="http://communityserver.org" version="2.1.60809.935">Community Server</generator><updated>2006-10-02T10:32:00Z</updated><entry><title>Create a Screen Saver with GDI+</title><link rel="alternate" type="text/html" href="http://cm.megasolutions.net/blogs/gdi/archive/2006/10/02/Create-a-Screen-Saver-with-GDI_2B00_.aspx" /><id>http://cm.megasolutions.net/blogs/gdi/archive/2006/10/02/Create-a-Screen-Saver-with-GDI_2B00_.aspx</id><published>2006-10-02T06:37:00Z</published><updated>2006-10-02T06:37:00Z</updated><content type="html">Create a Screen Saver with GDI+ &lt;p class="normal"&gt;You might think there&amp;rsquo;s something mysterious about a &lt;span class="productname"&gt;Microsoft Windows&lt;/span&gt; screen saver, but it&amp;rsquo;s really nothing more than a Windows application in disguise. You can easily build your own screen saver by creating a regular Windows application with a form that&amp;rsquo;s displayed in dialog mode, maximized to fill the screen, and waiting for a cue to be dismissed. The cue can be a mouse click or a movement of the mouse. This sample shows you how to create and deploy a screen saver with Visual Basic .NET.&lt;/p&gt;&lt;div class="sidebar" id="uid-D13A752B-E81C-6773-5192-E174DC4A4105"&gt;&lt;div class="title"&gt;You&amp;rsquo;ll want your screen saver form not to have a title bar, not to show up in the taskbar, and not to be &amp;ldquo;touchable&amp;rdquo; in any way by the user (except to dismiss it with a mouse click or a mouse movement). So you&amp;rsquo;ll need to set the following form properties:&lt;/div&gt;&lt;/div&gt;&lt;div class="bb"&gt;&lt;ul&gt;&lt;li&gt;&lt;p class="normal"&gt;&lt;span class="programelement"&gt;FormBorderStyle = None&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class="normal"&gt;&lt;span class="programelement"&gt;ControlBox = False&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class="normal"&gt;&lt;span class="programelement"&gt;MaximizeBox = False&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class="normal"&gt;&lt;span class="programelement"&gt;MinimizeBox = False&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class="normal"&gt;&lt;span class="programelement"&gt;ShowInTaskbar = False&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class="normal"&gt;&lt;span class="programelement"&gt;SizeGripStyle = Hide&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class="normal"&gt;&lt;span class="programelement"&gt;TopMost = True&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class="normal"&gt;&lt;span class="programelement"&gt;WindowState = Maximized&lt;/span&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="tip"&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;While you&amp;rsquo;re developing the screen saver, set the form&amp;rsquo;s size to a fraction of the screen&amp;rsquo;s size, set the &lt;span class="programelement"&gt;ControlBox&lt;/span&gt; property to &lt;span class="programelement"&gt;True&lt;/span&gt;, and set the &lt;span class="programelement"&gt;WindowState&lt;/span&gt; property to &lt;span class="programelement"&gt;Normal&lt;/span&gt;. That way the form won&amp;rsquo;t cover the entire screen, you can see your code for debugging purposes, and the form will have a title bar so that you can move it around.&lt;/div&gt;&lt;/div&gt;&lt;div class="bb"&gt;&lt;div class="title"&gt;Code Walkthrough&lt;/div&gt;&lt;p class="normal"&gt;The sample solution has two projects: Create a Screensaver with GDI+.vbproj and GDI+ Screen Saver.vbproj. The second one is the screen-saver project, while the first is a small installation program to install your screen saver once you&amp;rsquo;ve completed it. The procedures we&amp;rsquo;ll describe next are in the screen-saver project, except for those in the &amp;ldquo;Deploying the Screen Saver&amp;rdquo; section. Figure 10-5 shows the screen saver form during development, small and sizeable.&lt;/p&gt;&lt;div class="exhibit"&gt;&lt;img alt="Figure 10-5 While you&amp;rsquo;re developing your screen saver, keep the form small and sizeable so that you can test and debug it easily." height="266" src="http://cm.megasolutions.net/blogs/blgimages/F10wp05.png" width="300" /&gt; &lt;div class="caption"&gt;&lt;span class="fignum"&gt;Figure 10-5.&lt;/span&gt; &lt;span class="description"&gt;While you&amp;rsquo;re developing your screen saver, keep the form small and sizeable so that you can test and debug it easily.&lt;/span&gt; &lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Application Entry Point&lt;/div&gt;&lt;p class="normal"&gt;&lt;span class="programelement"&gt;Sub Main&lt;/span&gt; is the entry point into our application, the first procedure that executes when the screen-saver program is run. The &lt;span class="programelement"&gt;STAThread&lt;/span&gt; attribute means this application will run in a single-threaded apartment, and it&amp;rsquo;s needed for COM interoperability reasons. Windows will pass parameters to this program whenever a user is setting up the screen saver using the Display Properties │ Screen Saver property screen. The parameters will be passed in an array named &lt;span class="programelement"&gt;args&lt;/span&gt;, and Windows will pass a &lt;span class="programelement"&gt;/p&lt;/span&gt;, &lt;span class="programelement"&gt;/c&lt;/span&gt;, or &lt;span class="programelement"&gt;/s&lt;/span&gt; argument, depending on how the screen saver should behave. We&amp;rsquo;ll explain each argument in the following paragraphs.&lt;/p&gt;&lt;p class="normal"&gt;First we need to determine whether an argument was passed and, if so, which one. A &lt;span class="programelement"&gt;/p&lt;/span&gt; argument means we&amp;rsquo;re being asked to show a preview of the screen saver. We haven&amp;rsquo;t implemented the preview functionality here because it involves creating and joining threads and is beyond the scope of this sample, so we&amp;rsquo;ll simply exit the application.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;lt;STAThread()&amp;gt;&amp;nbsp;Shared&amp;nbsp;Sub&amp;nbsp;Main(ByVal&amp;nbsp;args&amp;nbsp;As&amp;nbsp;String())
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;args.Length&amp;nbsp;&amp;gt;&amp;nbsp;0&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;If&amp;nbsp;args(0).ToLower&amp;nbsp;= &amp;quot;/p&amp;quot; &lt;/span&gt;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Application.Exit()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;If the screen saver should offer a form for user options, Windows passes a &lt;span class="programelement"&gt;/c&lt;/span&gt;, so we&amp;rsquo;ll create and display a &lt;span class="programelement"&gt;frmOptions&lt;/span&gt; form, and then exit when the form is closed. If the screen saver should simply execute normally, Windows passes a &lt;span class="programelement"&gt;/s&lt;/span&gt;, so we&amp;rsquo;ll create and display a &lt;span class="programelement"&gt;screenSaverForm&lt;/span&gt; and then exit when the form is closed.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;args(0).ToLower.Trim().Substring(0,&amp;nbsp;2)&amp;nbsp;= &amp;quot;&lt;span class="emphasis"&gt;/c&amp;quot; &lt;/span&gt;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;userOptionsForm&amp;nbsp;As&amp;nbsp;New&amp;nbsp;frmOptions()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;userOptionsForm.ShowDialog()&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Application.Exit()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;args(0).ToLower&amp;nbsp;= &amp;quot;&lt;span class="emphasis"&gt;/s&amp;quot; &lt;/span&gt;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;screenSaverForm&amp;nbsp;As&amp;nbsp;New&amp;nbsp;frmSceenSaver()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;screenSaverForm.ShowDialog()&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Application.Exit()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;If there are no arguments, we&amp;rsquo;ll simply execute the screen saver normally, because it means that the user double-clicked the .scr or .exe file or ran it from within Visual Studio. We know this because otherwise Windows would have passed a parameter to the application.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;screenSaverForm&amp;nbsp;As&amp;nbsp;New&amp;nbsp;frmSceenSaver()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;screenSaverForm.ShowDialog()&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Application.Exit()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Normal Operation&lt;/div&gt;&lt;p class="normal"&gt;When the screen-saver form is loaded, we initialize it by creating the &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object we&amp;rsquo;ll use for drawing, loading the user&amp;rsquo;s saved options (creating an options file if one does not exist), setting the speed based on the user-defined options, and enabling the timer. The speed setting dictates how quickly shapes will be displayed when the screen saver is active.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;frmSceenSaver_Load(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Graphics&amp;nbsp;=&amp;nbsp;Me.CreateGraphics()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Options.&lt;span class="emphasis"&gt;LoadOptions()&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Select&amp;nbsp;Case&amp;nbsp;m_Options.Speed
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Case &amp;quot;&lt;span class="emphasis"&gt;Slow&amp;quot;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Me.tmrUpdateScreen.Interval&amp;nbsp;=&amp;nbsp;500
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Case &amp;quot;&lt;span class="emphasis"&gt;Fast&amp;quot;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Me.tmrUpdateScreen.Interval&amp;nbsp;=&amp;nbsp;100
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Case&amp;nbsp;Else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Me.tmrUpdateScreen.Interval&amp;nbsp;=&amp;nbsp;200
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;Select
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Me.tmrUpdateScreen.Enabled&amp;nbsp;=&amp;nbsp;True
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;All subsequent operations are in response to events. When the timer ticks, a new shape is drawn on the screen, and this continues until a mouse button is clicked or the mouse is moved over the form.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;tmrUpdateScreen_Tick(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;DrawShape()&lt;/span&gt;End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;The &lt;span class="programelement"&gt;DrawShape&lt;/span&gt; subroutine draws a randomly colored, randomly sized shape to the screen, based on some user-defined parameters. It starts by computing the largest possible values for the screen, as indicated by the form width and height. (Remember that the form is maximized.) Note that &lt;span class="variable"&gt;x1&lt;/span&gt;, &lt;span class="variable"&gt;x2&lt;/span&gt;, &lt;span class="variable"&gt;y1&lt;/span&gt;, and &lt;span class="variable"&gt;y2&lt;/span&gt; are coordinates for random points to be generated later, &lt;span class="programelement"&gt;myRect&lt;/span&gt; is the rectangle within which the shapes will be drawn, and &lt;span class="programelement"&gt;myColor&lt;/span&gt; is the color to be used to draw the shapes.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;DrawShape()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;&lt;span class="emphasis"&gt;maxX&lt;/span&gt;&amp;nbsp;As&amp;nbsp;Integer&amp;nbsp;=&amp;nbsp;&lt;span class="emphasis"&gt;Me.Width&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;&lt;span class="emphasis"&gt;maxY&lt;/span&gt;&amp;nbsp;As&amp;nbsp;Integer&amp;nbsp;=&amp;nbsp;&lt;span class="emphasis"&gt;Me.Height&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;x1,&amp;nbsp;x2,&amp;nbsp;y1,&amp;nbsp;y2&amp;nbsp;As&amp;nbsp;Integer
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;&lt;span class="emphasis"&gt;myRect&lt;/span&gt;&amp;nbsp;As&amp;nbsp;Rectangle
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;&lt;span class="emphasis"&gt;myColor&lt;/span&gt;&amp;nbsp;As&amp;nbsp;Color&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;Next we generate some random numbers ranging between zero and the maximums we determined earlier, and we create a rectangle based on the generated coordinates.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x1&amp;nbsp;=&amp;nbsp;m_Random.Next(0,&amp;nbsp;maxX)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;x2&amp;nbsp;=&amp;nbsp;m_Random.Next(0,&amp;nbsp;maxX)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y1&amp;nbsp;=&amp;nbsp;m_Random.Next(0,&amp;nbsp;maxY)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;y2&amp;nbsp;=&amp;nbsp;m_Random.Next(0,&amp;nbsp;maxY)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myRect&amp;nbsp;=&amp;nbsp;New&amp;nbsp;Rectangle(Math.Min(x1,&amp;nbsp;x2),&amp;nbsp;Math.Min(y1,&amp;nbsp;y2),&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Math.Abs(x1&amp;nbsp;-&amp;nbsp;x2),&amp;nbsp;Math.Abs(y1&amp;nbsp;-&amp;nbsp;y2))&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;We&amp;rsquo;ll select a color at random for the shape we&amp;rsquo;re about to draw. If the user wants transparent shapes, we&amp;rsquo;ll allow the transparency to be randomly generated as well. If not, we&amp;rsquo;ll set the &lt;span class="programelement"&gt;Alpha&lt;/span&gt; to 255 (the maximum). &lt;span class="programelement"&gt;Alpha,&lt;/span&gt; which is the first argument to the &lt;span class="programelement"&gt;Color.FromArgb&lt;/span&gt; function, determines how opaque the shape will be.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;m_Options.IsTransparent&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myColor&amp;nbsp;=&amp;nbsp;Color.FromArgb(&lt;span class="emphasis"&gt;m_Random.Next(255)&lt;/span&gt;,&amp;nbsp;m_Random.Next(255),&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Random.Next(255),&amp;nbsp;m_Random.Next(255))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myColor&amp;nbsp;=&amp;nbsp;Color.FromArgb(&lt;span class="emphasis"&gt;255&lt;/span&gt;,&amp;nbsp;m_Random.Next(255),&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Random.Next(255),&amp;nbsp;m_Random.Next(255))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;Finally, we draw an ellipse or rectangle based on user-defined options.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;&lt;span class="emphasis"&gt;m_Options.Shape&amp;nbsp;= &amp;quot;Ellipses&amp;quot; &lt;/span&gt;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Graphics.&lt;span class="emphasis"&gt;FillEllipse&lt;/span&gt;(New&amp;nbsp;SolidBrush(myColor),&amp;nbsp;myRect)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Graphics.&lt;span class="emphasis"&gt;FillRectangle&lt;/span&gt;(New&amp;nbsp;SolidBrush(myColor),&amp;nbsp;myRect)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Ending the Application&lt;/div&gt;&lt;p class="normal"&gt;When the user clicks a button or moves the mouse, we want the screen saver to quit. The following routines accomplish that. The first one simply exits if any mouse button is clicked on the screen saver form.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;frmSceenSaver_MouseDown(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;Application.Exit()&lt;/span&gt;End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;The second one responds to a mouse movement. Because the &lt;span class="programelement"&gt;MouseMove&lt;/span&gt; event can sometimes be fired by very trivial moves of the mouse, we&amp;rsquo;ll verify that the mouse has actually been moved by at least a few pixels before exiting. To do that, we store the current location of the mouse, turn on a switch that shows we&amp;rsquo;re tracking the mouse movements, and exit only if the mouse has been moved at least 10 pixels.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;frmSceenSaver_MouseMove(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;Not&amp;nbsp;m_IsActive&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Me.m_MouseLocation&amp;nbsp;=&amp;nbsp;New&amp;nbsp;Point(e.X,&amp;nbsp;e.Y)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_IsActive&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;Math.Abs(e.X&amp;nbsp;-&amp;nbsp;Me.m_MouseLocation.X)&amp;nbsp;&amp;gt;&amp;nbsp;10&amp;nbsp;Or&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Math.Abs(e.Y&amp;nbsp;-&amp;nbsp;Me.m_MouseLocation.Y)&amp;nbsp;&amp;gt;&amp;nbsp;10&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Application.Exit()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Setting Options&lt;/div&gt;&lt;p class="normal"&gt;We want the user to be able to choose screen-saver options such as how fast shapes should be drawn on the screen, whether they should be rectangles or ellipses, and whether the shapes should be transparent. So we provide an Options form, which gets called when the screen-saver program is invoked with the &lt;span class="programelement"&gt;/c&lt;/span&gt; argument.&lt;/p&gt;&lt;p class="normal"&gt;We&amp;rsquo;ve defined a class named &lt;span class="programelement"&gt;Options&lt;/span&gt; (which you can see in &lt;span class="programelement"&gt;Options.vb&lt;/span&gt;) to hold the preferences as properties and provide methods for loading and saving the preferences. Creating a class makes it easy to save the options to disk in XML format by serializing the class and then later retrieving them by deserialization. (See &amp;ldquo;Application #82: Serialize Objects&amp;rdquo; for more details.)&lt;/p&gt;&lt;p class="normal"&gt;The &lt;span class="programelement"&gt;btnOK_Click&lt;/span&gt; procedure in &lt;span class="programelement"&gt;frmOptions&lt;/span&gt; creates an &lt;span class="programelement"&gt;Options&lt;/span&gt; object and sets its values to the user-selected values on the form. It then saves the choices to disk.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnOK_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;Dim&amp;nbsp;myOptions&amp;nbsp;As&amp;nbsp;New&amp;nbsp;Options()&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;Me.optEllipses.Checked&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myOptions.&lt;span class="emphasis"&gt;Shape&lt;/span&gt;&amp;nbsp;= &amp;quot;Ellipses&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myOptions.&lt;span class="emphasis"&gt;Shape&lt;/span&gt;&amp;nbsp;= &amp;quot;Rectangles&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myOptions.&lt;span class="emphasis"&gt;IsTransparent&lt;/span&gt;&amp;nbsp;=&amp;nbsp;Me.chkTransparent.Checked
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myOptions.&lt;span class="emphasis"&gt;Speed&lt;/span&gt;&amp;nbsp;=&amp;nbsp;Me.cboSpeed.Text
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myOptions.&lt;span class="emphasis"&gt;SaveOptions()&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Me.Close()
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;The &lt;span class="programelement"&gt;Form_Load&lt;/span&gt; event procedure of &lt;span class="programelement"&gt;frmOptions&lt;/span&gt; loads the current user-defined options and sets the controls on the form accordingly. The &lt;span class="programelement"&gt;Load&lt;/span&gt; method of the &lt;span class="programelement"&gt;Options&lt;/span&gt; class always returns values, even if the options file doesn&amp;rsquo;t currently exist.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;frmOptions_Load(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;Dim&amp;nbsp;myOptions&amp;nbsp;As&amp;nbsp;New&amp;nbsp;Options()&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myOptions.&lt;span class="emphasis"&gt;LoadOptions&lt;/span&gt;()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Me.cboSpeed.Text&amp;nbsp;=&amp;nbsp;myOptions.&lt;span class="emphasis"&gt;Speed&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Me.chkTransparent.Checked&amp;nbsp;=&amp;nbsp;myOptions.&lt;span class="emphasis"&gt;IsTransparent&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;myOptions.&lt;span class="emphasis"&gt;Shape&lt;/span&gt;&amp;nbsp;= &amp;quot;Ellipses&amp;quot; Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Me.optEllipses.Checked&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Me.optRectangles.Checked&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="bb"&gt;&lt;div class="title"&gt;Deploying the Screen Saver&lt;/div&gt;&lt;p class="normal"&gt;Screen savers live in the Windows System directory, which by default is C:\Windows\System32. To install your new screen saver, you simply have to copy the .exe application file to the System directory, changing the extension from .exe to .scr. In the sample solution, we&amp;rsquo;ve provided a project that copies the file to its correct location. It assumes you have a copy of &amp;ldquo;101 VB.NET Sample Applications Screensaver.scr&amp;rdquo; in the root directory of the 89 Create a Screensaver with GDI+ project.&lt;/p&gt;&lt;p class="normal"&gt;If you don&amp;rsquo;t, copy &amp;ldquo;101 VB.NET Sample Applications Screensaver.exe&amp;rdquo; from GDI+ Screen Saver\bin to the root directory of the 89 Create a Screensaver with GDI+ project and change the extension to .scr.&lt;/p&gt;&lt;p class="normal"&gt;Once you&amp;rsquo;re sure the screen-saver file is in place, the &lt;span class="programelement"&gt;btnInstall_Click&lt;/span&gt; procedure of &lt;span class="programelement"&gt;frmMain&lt;/span&gt; handles the installation for you. Notice the use of&lt;span class="emphasis"&gt; &lt;/span&gt;&lt;span class="programelement"&gt;Environment.CurrentDirectory&lt;/span&gt; (the folder where the executable is running) and &lt;span class="programelement"&gt;Environment.SystemDirectory&lt;/span&gt; (the Windows System directory).&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnInstall_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;fileName&amp;nbsp;As&amp;nbsp;String&amp;nbsp;=&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;101&amp;nbsp;VB.NET&amp;nbsp;Sample&amp;nbsp;Applications&amp;nbsp;Screensaver.scr&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;sourceFile&amp;nbsp;As&amp;nbsp;String&amp;nbsp;=&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;Environment.CurrentDirectory&lt;/span&gt;&amp;nbsp;&amp;amp; &amp;quot;\..\&amp;quot; &amp;amp;&amp;nbsp;fileName
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;destFile&amp;nbsp;As&amp;nbsp;String&amp;nbsp;=&amp;nbsp;&lt;span class="emphasis"&gt;Environment.SystemDirectory&lt;/span&gt;&amp;nbsp;&amp;amp; &amp;quot;\&amp;quot; &amp;amp;&amp;nbsp;fileName
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Try
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;File.Copy(sourceFile,&amp;nbsp;destFile,&amp;nbsp;True)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Catch&amp;nbsp;ex&amp;nbsp;As&amp;nbsp;Exception
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MsgBox(ex.ToString(),&amp;nbsp;MsgBoxStyle.Exclamation,&amp;nbsp;Me.Text)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;Try
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="bb"&gt;&lt;div class="title"&gt;Conclusion&lt;/div&gt;&lt;p class="normal"&gt;In this sample application, you&amp;rsquo;ve seen that a screen saver is simply a Windows Application in disguise. Once you change its file extension from .exe to .scr and put it in the Windows System directory, it will show up on the list of screen savers in Control Panel │ Display. You&amp;rsquo;ve seen that Windows passes &lt;span class="programelement"&gt;/p&lt;/span&gt;, &lt;span class="programelement"&gt;/c&lt;/span&gt;, or &lt;span class="programelement"&gt;/s&lt;/span&gt; arguments to the screen saver to indicate how it should behave. They indicate Preview, Set Options, and Normal, respectively. We&amp;rsquo;ve also shown you that generating random colors and even random levels of transparency is easy with the &lt;span class="programelement"&gt;Random&lt;/span&gt; class and the &lt;span class="programelement"&gt;FromArgb&lt;/span&gt; function of the &lt;span class="programelement"&gt;Color&lt;/span&gt; class.&lt;/p&gt;&lt;/div&gt;&lt;h2 style="margin:12pt 0in 3pt;"&gt;&lt;span style="color:#993366;"&gt;&lt;em&gt;About The Author&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;Saahil Khan has been a Team Lead with &lt;a href="http://www.offshoreprogrammers.net/" rel="follow" title="http://www.offshoreprogrammers.net" target="_blank"&gt;Offshore Programmers Ltd &lt;/a&gt;and freelance write with &lt;a href="http://www.megasolutions.net/" rel="follow" title="http://cm.megasolutions.net" target="_blank"&gt;Megasolutions Ltd&lt;/a&gt;. He has over 5 years of experience in industrial automation and technologies like Java, .NET, and Flash. Saahil has extensive experience in strategizing/architecting solutions in .NET. Today, Sahil is completely focused on Microsoft .NET Technologies like C#, ASP.NET, and emerging technologies like FlashRemoting.&lt;img src="http://cm.megasolutions.net/aggbug.aspx?PostID=1634" width="1" height="1"&gt;</content><author><name>admin</name><uri>http://cm.megasolutions.net/members/admin.aspx</uri></author><category term="beginning asp net" scheme="http://cm.megasolutions.net/blogs/gdi/archive/tags/beginning+asp+net/default.aspx" /><category term="asp net programming" scheme="http://cm.megasolutions.net/blogs/gdi/archive/tags/asp+net+programming/default.aspx" /><category term="asp net code" scheme="http://cm.megasolutions.net/blogs/gdi/archive/tags/asp+net+code/default.aspx" /><category term="asp net applications" scheme="http://cm.megasolutions.net/blogs/gdi/archive/tags/asp+net+applications/default.aspx" /></entry><entry><title>Work with GDI+ to Manipulate Images</title><link rel="alternate" type="text/html" href="http://cm.megasolutions.net/blogs/gdi/archive/2006/10/02/Work-with-GDI_2B00_-to-Manipulate-Images.aspx" /><id>http://cm.megasolutions.net/blogs/gdi/archive/2006/10/02/Work-with-GDI_2B00_-to-Manipulate-Images.aspx</id><published>2006-10-02T06:32:00Z</published><updated>2006-10-02T06:32:00Z</updated><content type="html">Work with GDI+ to Manipulate Images &lt;p class="normal"&gt;This sample shows you how to manipulate images using GDI+, including changing the size of an image and rotating, zooming, and cropping an image.&lt;/p&gt;&lt;div class="bb"&gt;&lt;p class="normal"&gt;GDI+ provides new ways to work with images. This example illustrates several of them.&lt;/p&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Changing the Size of an Image&lt;/div&gt;&lt;p class="normal"&gt;Once you&amp;rsquo;ve loaded your image into a &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;, you can apply one of four &lt;span class="programelement"&gt;SizeMode&lt;/span&gt; settings to the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;:&lt;/p&gt;&lt;ul class="termdefnumber"&gt;&lt;li&gt;&lt;span class="lead-in"&gt;&lt;span class="programelement"&gt;AutoSize&lt;/span&gt;&lt;/span&gt; &lt;p class="normal"&gt;The &lt;span class="programelement"&gt;PictureBox&lt;/span&gt; size is adjusted to match the size of the image in it.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="lead-in"&gt;&lt;span class="programelement"&gt;CenterImage&lt;/span&gt;&lt;/span&gt; &lt;p class="normal"&gt;The image is displayed in the center of the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;. If the image is larger than the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;, its outside edges are clipped.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="lead-in"&gt;&lt;span class="programelement"&gt;Normal&lt;/span&gt;&lt;/span&gt; &lt;p class="normal"&gt;The image is located in the upper left corner of the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;. Its right and bottom edges are clipped if it is larger than the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="lead-in"&gt;&lt;span class="programelement"&gt;StretchImage&lt;/span&gt;&lt;/span&gt; &lt;p class="normal"&gt;The opposite of &lt;span class="programelement"&gt;AutoSize&lt;/span&gt;. The image is stretched or shrunk to fit the size of the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Rotating Images&lt;/div&gt;&lt;p class="normal"&gt;The &lt;span class="programelement"&gt;Image&lt;/span&gt; class &lt;span class="programelement"&gt;RotateFlip&lt;/span&gt; method lets you rotate an image, flip it, or both. You provide the method with a &lt;span class="programelement"&gt;RotateFlipType&lt;/span&gt; argument (for example, &lt;span class="programelement"&gt;Rotate180FlipX&lt;/span&gt;) that determines how many degrees you want to rotate the image and the axis, if any, on which you want to flip it. Choices include rotation by 90, 180, and 270 degrees; flipping on the x-axis, y-axis, or both; and combinations of all these options. Rotation is always clockwise.&lt;/p&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Zooming and Cropping Images&lt;/div&gt;&lt;p class="normal"&gt;Zooming means resizing the image so that it appears that the user&amp;rsquo;s perspective has changed by being either brought closer to or moved farther away from the picture.&lt;/p&gt;&lt;p class="normal"&gt;Cropping consists of creating a new image at a size you specify and filling it with the portion of the old image that will fit the dimensions of the new one. If you want to allow the user to undo the crop, you need to create a variable that holds a copy of the bitmap before it&amp;rsquo;s cropped. Figure 10-4 shows an image that is both rotated and cropped.&lt;/p&gt;&lt;div class="exhibit"&gt;&lt;img alt="Figure 10-4 The WaterLilies.jpg, which is bigger than the PictureBox, is centered within it, and its edges are cropped. The inset shows a portion of the image after it is rotated by 90 degrees." height="252" src="http://cm.megasolutions.net/blogs/blgimages/F10wp04.png" width="300" /&gt; &lt;div class="caption"&gt;&lt;span class="fignum"&gt;Figure 10-4.&lt;/span&gt; &lt;span class="description"&gt;The WaterLilies.jpg, which is bigger than the PictureBox, is centered within it, and its edges are cropped. The inset shows a portion of the image after it is rotated by 90 degrees.&lt;/span&gt; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="bb"&gt;&lt;div class="title"&gt;Code Walkthrough&lt;/div&gt;&lt;p class="normal"&gt;Let&amp;rsquo;s examine some ways we can manipulate an image, starting with resizing it.&lt;/p&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Image Sizing&lt;/div&gt;&lt;p class="normal"&gt;All four size settings mentioned previously are represented by four Size Mode radio buttons on the sample form. The &lt;span class="programelement"&gt;SizeModeRadioButtons_CheckedChanged&lt;/span&gt; procedure handles the &lt;span class="programelement"&gt;CheckedChanged&lt;/span&gt; events of all four radio buttons, and it adjusts the &lt;span class="programelement"&gt;PictureBox.SizeMode&lt;/span&gt; property accordingly. Each radio button stores one of the values of the &lt;span class="programelement"&gt;PictureBoxSizeMode&lt;/span&gt; enumeration (whose values are 0 through 3) in its &lt;span class="programelement"&gt;Tag&lt;/span&gt; property.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;SizeModeRadioButtons_CheckedChanged(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;opt&amp;nbsp;As&amp;nbsp;RadioButton&amp;nbsp;=&amp;nbsp;CType(sender,&amp;nbsp;RadioButton)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;sm&amp;nbsp;As&amp;nbsp;PictureBoxSizeMode&amp;nbsp;=&amp;nbsp;CType(&lt;span class="emphasis"&gt;opt.Tag&lt;/span&gt;,&amp;nbsp;PictureBoxSizeMode)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;opt.Checked&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.SizeMode&amp;nbsp;=&amp;nbsp;sm&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;You must manually reset the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt; to its original size if &lt;span class="programelement"&gt;AutoSize&lt;/span&gt; has been set. It will not automatically return to the size set in the designer.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;sm&amp;nbsp;=&amp;nbsp;PictureBoxSizeMode.AutoSize&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;btnFit.Enabled&amp;nbsp;=&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;btnFit.Enabled&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;picImage.Width&amp;nbsp;=&amp;nbsp;PICTUREBOX_WIDTH
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.Height&amp;nbsp;=&amp;nbsp;PICTUREBOX_HEIGHT&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;The &lt;span class="programelement"&gt;Fit&lt;/span&gt; procedure makes the image fit properly in the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;. You might think that &lt;span class="programelement"&gt;AutoSize&lt;/span&gt; would make the image appear in the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt; according to its true aspect ratio within the fixed bounds of the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;. But &lt;span class="programelement"&gt;AutoSize&lt;/span&gt; simply expands or shrinks the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt; itself. So the &lt;span class="programelement"&gt;Fit&lt;/span&gt; procedure determines whether the image is smaller than the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;. If it is, and if &lt;span class="programelement"&gt;Fit&lt;/span&gt; was called by the Zoom In button, it centers the image.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;Fit()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;picImage.Image.Width&amp;nbsp;&amp;lt;&amp;nbsp;picImage.Width&amp;nbsp;And&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.Image.Height&amp;nbsp;&amp;lt;&amp;nbsp;picImage.Height&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;Not&amp;nbsp;&lt;span class="emphasis"&gt;IsFitForZoomIn&lt;/span&gt;&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.SizeMode&amp;nbsp;=&amp;nbsp;PictureBoxSizeMode.CenterImage
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CalculateAspectRatioAndSetDimensions()
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Image Rotation&lt;/div&gt;&lt;p class="normal"&gt;As we mentioned earlier, rotation is always clockwise when you use the &lt;span class="programelement"&gt;RotateFlip&lt;/span&gt; method, and in &lt;span class="programelement"&gt;btnRotateRight_Click &lt;/span&gt;in the following code, we&amp;rsquo;re simply rotating the image by 90 degrees. In &lt;span class="programelement"&gt;btnRotateLeft_Click&lt;/span&gt;, we&amp;rsquo;re achieving the left rotation by rotating the image by 270 degrees, which is the same as if we had rotated it counter-clockwise by 90 degrees. Note that in each case we need to refresh the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt; after the rotation.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnRotateRight_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.Image.&lt;span class="emphasis"&gt;RotateFlip(RotateFlipType.Rotate90FlipNone)&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.&lt;span class="emphasis"&gt;Refresh&lt;/span&gt;()
End&amp;nbsp;Sub

Private&amp;nbsp;Sub&amp;nbsp;btnRotateLeft_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.Image.&lt;span class="emphasis"&gt;RotateFlip(RotateFlipType.Rotate270FlipNone)&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.&lt;span class="emphasis"&gt;Refresh&lt;/span&gt;()
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Zooming&lt;/div&gt;&lt;p class="normal"&gt;To zoom, we resize the image, as shown in the following procedure. When zooming in or out, the &lt;span class="programelement"&gt;SizeMode&lt;/span&gt; controls on the sample form are disabled. Otherwise, the zooming won&amp;rsquo;t work as anticipated. The following &lt;span class="emphasis"&gt;If&lt;/span&gt; test ensures that the initial Zoom In transition is smooth. Without the test, if the &lt;span class="programelement"&gt;SizeMode&lt;/span&gt; is something other than &lt;span class="programelement"&gt;AutoSize&lt;/span&gt;, the image can appear to Zoom Out on the first click, and then Zoom In on subsequent clicks.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnZoomIn_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;&lt;span class="emphasis"&gt;grpSizeMode.Enabled&lt;/span&gt;&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.SizeMode&amp;nbsp;=&amp;nbsp;&lt;span class="emphasis"&gt;PictureBoxSizeMode.AutoSize&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;grpSizeMode.Enabled&amp;nbsp;=&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;btnFit.Enabled&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;IsFitForZoomIn&amp;nbsp;=&amp;nbsp;True&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;The &lt;span class="programelement"&gt;StretchImage&lt;/span&gt; mode works best for zooming because the image is forced to conform to the size of the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;. Zoom works best if you first fit the image according to its true aspect ratio. (See &lt;span class="programelement"&gt;CalculateAspectRatioAndSetDimensions&lt;/span&gt;.)&lt;/p&gt;&lt;p class="normal"&gt;When it&amp;rsquo;s time to actually do the zoom, you do it by simply adjusting the image&amp;rsquo;s dimensions up or down&amp;mdash;in this case, by 25 percent. You could, of course, choose any increment you want, including letting the user enter it.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.SizeMode&amp;nbsp;=&amp;nbsp;PictureBoxSizeMode.StretchImage
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Fit()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.Width&amp;nbsp;=&amp;nbsp;CInt(&lt;span class="emphasis"&gt;picImage.Width&amp;nbsp;*&amp;nbsp;1.25&lt;/span&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.Height&amp;nbsp;=&amp;nbsp;CInt(&lt;span class="emphasis"&gt;picImage.Height&amp;nbsp;*&amp;nbsp;1.25&lt;/span&gt;)
End&amp;nbsp;Sub

Private&amp;nbsp;Sub&amp;nbsp;btnZoomOut_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;grpSizeMode.Enabled&amp;nbsp;=&amp;nbsp;False
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;btnFit.Enabled&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Fit()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.SizeMode&amp;nbsp;=&amp;nbsp;PictureBoxSizeMode.StretchImage
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.Width&amp;nbsp;=&amp;nbsp;CInt(&lt;span class="emphasis"&gt;picImage.Width&amp;nbsp;/&amp;nbsp;1.25&lt;/span&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.Height&amp;nbsp;=&amp;nbsp;CInt(&lt;span class="emphasis"&gt;picImage.Height&amp;nbsp;/&amp;nbsp;1.25&lt;/span&gt;)
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;The following procedure calculates and returns the image&amp;rsquo;s aspect ratio and sets its proper dimensions. It&amp;rsquo;s used by the &lt;span class="programelement"&gt;Fit&lt;/span&gt; procedure and also for saving thumbnails of images.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Function&amp;nbsp;CalculateAspectRatioAndSetDimensions()&amp;nbsp;As&amp;nbsp;Double
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;ratio&amp;nbsp;As&amp;nbsp;Double
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;picImage.Image.Width&amp;nbsp;&amp;gt;&amp;nbsp;picImage.Image.Height&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ratio&amp;nbsp;=&amp;nbsp;picImage.Image.Width&amp;nbsp;/&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.Image.Height
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;picImage.Height&amp;nbsp;=&amp;nbsp;CInt(CDbl(picImage.Width)&amp;nbsp;/&amp;nbsp;ratio)&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ratio&amp;nbsp;=&amp;nbsp;picImage.Image.Height&amp;nbsp;/&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.Image.Width
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;picImage.Width&amp;nbsp;=&amp;nbsp;CInt(CDbl(picImage.Height)&amp;nbsp;/&amp;nbsp;ratio)&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Return&amp;nbsp;ratio
End&amp;nbsp;Function&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Cropping&lt;/div&gt;&lt;p class="normal"&gt;In our example, we accept upper left x- and y-coordinates from the user, along with the width and height of the desired new image. Then we create a rectangle defined by those coordinates (relative to the upper left corner of the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;) and the desired width and height.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnCrop_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;IsValidCropValues()&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;imgUndo&amp;nbsp;=&amp;nbsp;picImage.Image
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;btnUndo.Enabled&amp;nbsp;=&amp;nbsp;True
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;recSource&amp;nbsp;As&amp;nbsp;New&amp;nbsp;Rectangle(CInt(txtXCoord.Text),&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CInt(txtYCoord.Text),&amp;nbsp;CInt(txtWidth.Text),&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CInt(txtHeight.Text))&lt;/pre&gt;&lt;/div&gt;&lt;div class="caution"&gt;&lt;strong&gt;CAUTION&lt;/strong&gt;&lt;br /&gt;You might be tempted to create a &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object off the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt; (rather than a new &lt;span class="programelement"&gt;Bitmap&lt;/span&gt;) and then to clear the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt; and draw the cropped image onto it, like this: &lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Dim&amp;nbsp;grPicImage&amp;nbsp;As&amp;nbsp;Graphics&amp;nbsp;=&amp;nbsp;picImage.CreateGraphics
grPicImage.Clear(picImage.BackColor)
grPicImage.DrawImage(picImage.Image,&amp;nbsp;0,&amp;nbsp;0,&amp;nbsp;recSource,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GraphicsUnit.Pixel)&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;This will appear to work, but as soon as you use any of the other controls on the form you&amp;rsquo;ll see that the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt; actually still contains the original image, not the cropped one.&lt;/p&gt;&lt;/div&gt;&lt;p class="normal"&gt;Then we create a new, blank &lt;span class="programelement"&gt;Bitmap&lt;/span&gt; on which we will draw the cropped image. We get a &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object from the &lt;span class="programelement"&gt;Bitmap&lt;/span&gt; for drawing, and we draw the image in the upper left corner of the &lt;span class="programelement"&gt;Bitmap&lt;/span&gt;. Finally, we set the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt; image to the new cropped image.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;bmpCropped&amp;nbsp;As&amp;nbsp;&lt;span class="emphasis"&gt;New&amp;nbsp;Bitmap&lt;/span&gt;(CInt(txtWidth.Text),&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CInt(txtHeight.Text))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;grBitmap&amp;nbsp;As&amp;nbsp;Graphics&amp;nbsp;=&amp;nbsp;Graphics.FromImage(bmpCropped)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;grBitmap.DrawImage(picImage.Image,&amp;nbsp;0,&amp;nbsp;0,&amp;nbsp;recSource,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;GraphicsUnit.Pixel)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;picImage.Image&amp;nbsp;=&amp;nbsp;bmpCropped
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="bb"&gt;&lt;div class="title"&gt;Conclusion&lt;/div&gt;&lt;p class="normal"&gt;In this sample application, we&amp;rsquo;ve shown you that an image in a &lt;span class="programelement"&gt;PictureBox&lt;/span&gt; can be resized several ways by setting the &lt;span class="programelement"&gt;SizeMode&lt;/span&gt; property of the &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;. You&amp;rsquo;ve seen that you can rotate and flip an image at the same time, and the &lt;span class="programelement"&gt;RotateFlip&lt;/span&gt; method accepts a variety of &lt;span class="programelement"&gt;RotateFlipType&lt;/span&gt; arguments that let you turn and flip an image in any direction you want. Zooming means resizing the image. Be careful about the first user click after choosing Zoom In if the &lt;span class="programelement"&gt;SizeMode&lt;/span&gt; is something other than &lt;span class="programelement"&gt;AutoSize&lt;/span&gt;.&lt;/p&gt;&lt;/div&gt;&lt;h2 style="margin:12pt 0in 3pt;"&gt;&lt;span style="color:#993366;"&gt;&lt;em&gt;About The Author&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p&gt;Saahil Khan has been a Team Lead with &lt;a href="http://www.offshoreprogrammers.net/" rel="follow" title="http://www.offshoreprogrammers.net" target="_blank"&gt;Offshore Programmers Ltd &lt;/a&gt;and freelance write with &lt;a href="http://www.megasolutions.net/" rel="follow" title="http://cm.megasolutions.net" target="_blank"&gt;Megasolutions Ltd&lt;/a&gt;. He has over 5 years of experience in industrial automation and technologies like Java, .NET, and Flash. Saahil has extensive experience in strategizing/architecting solutions in .NET. Today, Sahil is completely focused on Microsoft .NET Technologies like C#, ASP.NET, and emerging technologies like FlashRemoting.&lt;/p&gt;&lt;img src="http://cm.megasolutions.net/aggbug.aspx?PostID=1633" width="1" height="1"&gt;</content><author><name>admin</name><uri>http://cm.megasolutions.net/members/admin.aspx</uri></author></entry><entry><title>Work with GDI+ Text</title><link rel="alternate" type="text/html" href="http://cm.megasolutions.net/blogs/gdi/archive/2006/10/02/Work-with-GDI_2B00_-Text.aspx" /><id>http://cm.megasolutions.net/blogs/gdi/archive/2006/10/02/Work-with-GDI_2B00_-Text.aspx</id><published>2006-10-02T06:22:00Z</published><updated>2006-10-02T06:22:00Z</updated><content type="html">Work with GDI+ Text &lt;p class="normal"&gt;You might find it surprising that to display text on a form, &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;, or some other surface you need to &lt;span class="emphasis"&gt;draw&lt;/span&gt; it&amp;mdash;but that&amp;rsquo;s exactly the way it is. This sample shows some of the many features available when using GDI+ to work with text.&lt;/p&gt;&lt;div class="bb"&gt;&lt;p class="normal"&gt;Fonts and text are rendered by means of GDI+, and the major method you&amp;rsquo;ll use to display text to the screen is the &lt;span class="programelement"&gt;DrawString&lt;/span&gt; method of the &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object. You need four essential items to display text using &lt;span class="programelement"&gt;DrawString&lt;/span&gt;:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p class="normal"&gt;The text to be displayed&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class="normal"&gt;A font in which you want the text displayed&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class="normal"&gt;A brush to draw with&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p class="normal"&gt;The location where it should be displayed, which can be x and y coordinates or a rectangle within which the text will be displayed&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class="normal"&gt;Whereas you use a &lt;span class="programelement"&gt;Pen&lt;/span&gt; to draw lines and curves, you need a &lt;span class="programelement"&gt;Brush&lt;/span&gt; to draw text. As always, the &lt;span class="programelement"&gt;Brush&lt;/span&gt; is a holder for characteristics of the drawing, while the &lt;span class="word"&gt;Graphics&lt;/span&gt; object provides the methods for doing the drawing.&lt;/p&gt;&lt;p class="normal"&gt;You have a variety of options when displaying text. You always display text within a bounding rectangle, within which you can use hatch brushes, texture brushes, gradient brushes, and of course, solid brushes. You must carefully measure the size of the text you intend to display, because the size of the bounding rectangle will determine whether the text is appropriately positioned on the screen and whether it will fit in the space provided. Figure 10-3 shows text reflected by the &lt;span class="programelement"&gt;TranslateTransform&lt;/span&gt; method.&lt;/p&gt;&lt;div class="exhibit"&gt;&lt;img alt="Figure 10-3 When you draw text with GDI+ brushes, you can use 
transformations to show the text in a variety of orientations." height="205" src="http://cm.megasolutions.net/blogs/blgimages/F10wp03.png" width="300" /&gt; &lt;div class="caption"&gt;&lt;span class="fignum"&gt;Figure 10-3.&lt;/span&gt; &lt;span class="description"&gt;When you draw text with GDI+ brushes, you can use transformations to show the text in a variety of orientations.&lt;/span&gt; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="bb"&gt;&lt;div class="title"&gt;Code Walkthrough&lt;/div&gt;&lt;p class="normal"&gt;We&amp;rsquo;ll examine several options for displaying text on a drawing surface, illustrating the point we made earlier&amp;mdash;that text must be drawn.&lt;/p&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Block Text&lt;/div&gt;&lt;p class="normal"&gt;Our first option creates the sample text with a block appearance. We begin by setting up the brushes we&amp;rsquo;ll use for the foreground and background. We need a font object for the text, so we create one, using the values the user has set. Notice how we&amp;rsquo;ve used the &lt;span class="programelement"&gt;CheckState&lt;/span&gt; of the &lt;span class="programelement"&gt;chkBold&lt;/span&gt; check box. &lt;span class="programelement"&gt;CheckState.Checked&lt;/span&gt; is equal to 1 and &lt;span class="programelement"&gt;Unchecked&lt;/span&gt; is 0. &lt;span class="programelement"&gt;FontStyle.Bold&lt;/span&gt; is equal to 1 and &lt;span class="programelement"&gt;Regular&lt;/span&gt; is 0. So we simply cast the check state of the check box to a font style and we&amp;rsquo;ve declared whether we want boldface type or not. Then we create a &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object from the picture box and clear the box.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnBlockText_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myForeBrush&amp;nbsp;As&amp;nbsp;Brush&amp;nbsp;=&amp;nbsp;Brushes.Aquamarine
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myBackBrush&amp;nbsp;As&amp;nbsp;Brush&amp;nbsp;=&amp;nbsp;Brushes.Black
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myStyle&amp;nbsp;As&amp;nbsp;FontStyle&amp;nbsp;=&amp;nbsp;CType(chkBold.CheckState,&amp;nbsp;FontStyle)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myFont&amp;nbsp;As&amp;nbsp;New&amp;nbsp;Font(&amp;quot;Times&amp;nbsp;New&amp;nbsp;Roman&amp;quot;,&amp;nbsp;Me.nudFontSize.Value,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myStyle)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;g&amp;nbsp;As&amp;nbsp;Graphics&amp;nbsp;=&amp;nbsp;picDemoArea.CreateGraphics()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.Clear(Color.White)&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;We need to determine the size that will be required to draw the sample text. The &lt;span class="programelement"&gt;MeasureString&lt;/span&gt; method provides the exact dimensions of the provided string, so you can determine whether it will fit in the area where you want to display it. &lt;span class="programelement"&gt;MeasureString&lt;/span&gt; returns its results in a &lt;span class="programelement"&gt;SizeF&lt;/span&gt; structure, which has &lt;span class="programelement"&gt;Width&lt;/span&gt; and &lt;span class="programelement"&gt;Height&lt;/span&gt; properties. Using those properties, we calculate the x- and y-coordinates for the starting point of our display.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;textSize&amp;nbsp;As&amp;nbsp;SizeF&amp;nbsp;=&amp;nbsp;g.&lt;span class="emphasis"&gt;MeasureString&lt;/span&gt;(Me.txtSample.Text,&amp;nbsp;myFont)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;xLocation&amp;nbsp;As&amp;nbsp;Single&amp;nbsp;=&amp;nbsp;(picDemoArea.Width&amp;nbsp;-&amp;nbsp;&lt;span class="emphasis"&gt;textSize.Width&lt;/span&gt;)&amp;nbsp;/&amp;nbsp;2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;yLocation&amp;nbsp;As&amp;nbsp;Single&amp;nbsp;=&amp;nbsp;(picDemoArea.Height&amp;nbsp;-&amp;nbsp;&lt;span class="emphasis"&gt;textSize.Height&lt;/span&gt;)&amp;nbsp;/&amp;nbsp;3&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;Now we&amp;rsquo;re ready to display the text. We&amp;rsquo;ll draw the black background first. To get the block effect, we draw the text repeatedly from the offset in the lower left up to the point where the main text will be drawn. Because people tend to think of light as coming from the upper left, we&amp;rsquo;ve subtracted the offset depth from the x dimension instead of adding it. If we had added it, the block might look more like a shadow.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;i&amp;nbsp;As&amp;nbsp;Integer
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;For&amp;nbsp;i&amp;nbsp;=&amp;nbsp;CInt(nudBlockDepth.Value)&amp;nbsp;To&amp;nbsp;0&amp;nbsp;Step&amp;nbsp;-1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.&lt;span class="emphasis"&gt;DrawString&lt;/span&gt;(txtSample.Text,&amp;nbsp;myFont,&amp;nbsp;&lt;span class="emphasis"&gt;myBackBrush&lt;/span&gt;,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xLocation&amp;nbsp;-&amp;nbsp;i,&amp;nbsp;yLocation&amp;nbsp;+&amp;nbsp;i)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Next&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;Finally, we draw the white main text over the black text. Note how we provide the &lt;span class="programelement"&gt;DrawString&lt;/span&gt; method with the text we want to display, the font to use, the brush to draw with, and the coordinates at which to draw.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.&lt;span class="emphasis"&gt;DrawString&lt;/span&gt;(txtSample.Text,&amp;nbsp;myFont,&amp;nbsp;&lt;span class="emphasis"&gt;myForeBrush&lt;/span&gt;,&amp;nbsp;xLocation,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yLocation)
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Brush Text&lt;/div&gt;&lt;p class="normal"&gt;Here we&amp;rsquo;ll display the sample text by using either a &lt;span class="programelement"&gt;Hatch&lt;/span&gt; or &lt;span class="programelement"&gt;Gradient&lt;/span&gt; brush. In creating a &lt;span class="programelement"&gt;HatchBrush&lt;/span&gt;, we must specify the style of hatch we want (in this case, Diagonal Brick), as well as foreground and background colors. Before we create the &lt;span class="programelement"&gt;LinearGradientBrush&lt;/span&gt;, we want to provide a boundary within which the gradient will be displayed. So we create a rectangle that&amp;rsquo;s the size of our text. Then we pass that rectangle as the first argument to the constructor of the &lt;span class="programelement"&gt;Linear&amp;shy;GradientBrush&lt;/span&gt;, along with the starting and ending colors of the gradient and the orientation of the gradient (in this case, Forward Diagonal).&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnBrushText_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img height="13" width="3" /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;&lt;span class="emphasis"&gt;textSize&lt;/span&gt;&amp;nbsp;As&amp;nbsp;SizeF&amp;nbsp;=&amp;nbsp;g.MeasureString(Me.txtSample.Text,&amp;nbsp;myFont)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myBrush&amp;nbsp;&lt;span class="emphasis"&gt;As&amp;nbsp;Brush&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;Me.optHatch.Checked&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myBrush&amp;nbsp;=&amp;nbsp;New&amp;nbsp;&lt;span class="emphasis"&gt;HatchBrush&lt;/span&gt;(HatchStyle.DiagonalBrick,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Color.Yellow,&amp;nbsp;Color.Blue)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;&lt;span class="emphasis"&gt;gradientRectangle&lt;/span&gt;&amp;nbsp;As&amp;nbsp;New&amp;nbsp;RectangleF(New&amp;nbsp;PointF(0,&amp;nbsp;0),&amp;nbsp;&lt;span class="emphasis"&gt;textSize&lt;/span&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myBrush&amp;nbsp;=&amp;nbsp;New&amp;nbsp;&lt;span class="emphasis"&gt;LinearGradientBrush&lt;/span&gt;(&lt;span class="emphasis"&gt;gradientRectangle&lt;/span&gt;,&amp;nbsp;Color.Blue,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Color.Yellow,&amp;nbsp;LinearGradientMode.ForwardDiagonal)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.DrawString(txtSample.Text,&amp;nbsp;myFont,&amp;nbsp;myBrush,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(picDemoArea.Width&amp;nbsp;-&amp;nbsp;textSize.Width)&amp;nbsp;/&amp;nbsp;2,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(picDemoArea.Height&amp;nbsp;-&amp;nbsp;textSize.Height)&amp;nbsp;/&amp;nbsp;3)
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Embossed Text&lt;/div&gt;&lt;p class="normal"&gt;The following procedure creates the sample text with an embossed look. To create the effect, the sample text is drawn twice. It&amp;rsquo;s drawn first in black, offset slightly from the drawing starting point, and then drawn again in white, the current background color. This gives the impression that the text is raised. To give the impression of engraving instead of embossing, simply use the negative of the offset value.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnEmboss_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myBackBrush&amp;nbsp;As&amp;nbsp;Brush&amp;nbsp;=&amp;nbsp;Brushes.Black
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myForeBrush&amp;nbsp;As&amp;nbsp;Brush&amp;nbsp;=&amp;nbsp;Brushes.White
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img height="13" width="3" /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;textSize&amp;nbsp;As&amp;nbsp;SizeF&amp;nbsp;=&amp;nbsp;g.MeasureString(Me.txtSample.Text,&amp;nbsp;myFont)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xLocation&amp;nbsp;=&amp;nbsp;(picDemoArea.Width&amp;nbsp;-&amp;nbsp;textSize.Width)&amp;nbsp;/&amp;nbsp;2
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yLocation&amp;nbsp;=&amp;nbsp;(picDemoArea.Height&amp;nbsp;-&amp;nbsp;textSize.Height)&amp;nbsp;/&amp;nbsp;3&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;We&amp;rsquo;ll draw the black background first. (Note: if you subtract the &lt;span class="programelement"&gt;nudEmbossDepth&lt;/span&gt; value instead of adding it, you&amp;rsquo;ll get an Engraved effect. Try it with the Depth control on the form.) Finally, we draw the white main text over the black text.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.DrawString(txtSample.Text,&amp;nbsp;myFont,&amp;nbsp;&lt;span class="emphasis"&gt;myBackBrush&lt;/span&gt;,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xLocation&amp;nbsp;&lt;span class="emphasis"&gt;+&amp;nbsp;Me.nudEmbossDepth.Value&lt;/span&gt;,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yLocation&amp;nbsp;&lt;span class="emphasis"&gt;+&amp;nbsp;Me.nudEmbossDepth.Value&lt;/span&gt;)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.DrawString(txtSample.Text,&amp;nbsp;myFont,&amp;nbsp;myForeBrush,&amp;nbsp;xLocation,&amp;nbsp;yLocation)
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Reflected Text&lt;/div&gt;&lt;p class="normal"&gt;This example reflects text around the baseline of the characters. It&amp;rsquo;s more advanced than most of the other examples and requires careful measurement of the text. Because we&amp;rsquo;ll be scaling, and scaling effects the entire &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object not just the text, we need to reposition the origin of the &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object from (0,0) to the (&lt;span class="variable"&gt;xLocation&lt;/span&gt;, &lt;span class="variable"&gt;yLocation&lt;/span&gt;) point. If we don&amp;rsquo;t, when we attempt to flip the text with a scaling transform, it will merely draw the reflected text at (&lt;span class="variable"&gt;xLocation&lt;/span&gt;, -&lt;span class="variable"&gt;&amp;thinsp;&amp;thinsp;yLocation&lt;/span&gt;), which is outside the viewable area.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnReflectedText_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myBackBrush&amp;nbsp;As&amp;nbsp;Brush&amp;nbsp;=&amp;nbsp;Brushes.Gray
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myForeBrush&amp;nbsp;As&amp;nbsp;Brush&amp;nbsp;=&amp;nbsp;Brushes.Black
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img height="13" width="3" /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.&lt;span class="emphasis"&gt;TranslateTransform&lt;/span&gt;(xLocation,&amp;nbsp;yLocation)&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;Reflecting around the origin still poses problems. The origin represents the upper left corner of the text&amp;rsquo;s bounding rectangle. This means the reflection will occur at the &lt;span class="emphasis"&gt;top&lt;/span&gt; of the original drawing. This is not how people are used to seeing reflected text. So we need to determine where to draw the text, and we can do that only when we&amp;rsquo;ve calculated the height required by the drawing.&lt;/p&gt;&lt;p class="normal"&gt;This is not as simple as it might seem. The &lt;span class="programelement"&gt;Height&lt;/span&gt; returned from the &lt;span class="programelement"&gt;MeasureString&lt;/span&gt; method includes some extra spacing for descenders and white space. But we want &lt;span class="emphasis"&gt;only&lt;/span&gt; the height from the &lt;span class="emphasis"&gt;baseline&lt;/span&gt; (which is the line on which all caps sit). Any characters with descenders drop below the baseline. To calculate the height above the baseline, we need to use the &lt;span class="programelement"&gt;GetCellAscent&lt;/span&gt; method. Because &lt;span class="programelement"&gt;GetCellAscent&lt;/span&gt; returns a &lt;span class="programelement"&gt;Design Metric&lt;/span&gt; value, it must be converted to pixels and scaled for the font size.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;lineAscent&amp;nbsp;As&amp;nbsp;Integer
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;lineSpacing&amp;nbsp;As&amp;nbsp;Integer
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;lineHeight&amp;nbsp;As&amp;nbsp;Single
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;textHeight&amp;nbsp;As&amp;nbsp;Single
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lineAscent&amp;nbsp;=&amp;nbsp;myFont.FontFamily.&lt;span class="emphasis"&gt;GetCellAscent&lt;/span&gt;(myFont.Style)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lineSpacing&amp;nbsp;=&amp;nbsp;myFont.FontFamily.GetLineSpacing(myFont.Style)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;lineHeight&amp;nbsp;=&amp;nbsp;myFont.GetHeight(g)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;textHeight&amp;nbsp;=&amp;nbsp;lineHeight&amp;nbsp;*&amp;nbsp;lineAscent&amp;nbsp;/&amp;nbsp;lineSpacing&lt;/pre&gt;&lt;/div&gt;&lt;div class="tip"&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;Reflection looks best with characters that can be reflected over the baseline nicely&amp;mdash;like capital letters. Characters with descenders look odd. To fix that, factor in the height of the descenders as you calculate the text height, and then you&amp;rsquo;ll reflect across the lowest descender height. Here&amp;rsquo;s how: &lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Dim&amp;nbsp;lineDescent&amp;nbsp;As&amp;nbsp;Integer
lineDescent&amp;nbsp;=&amp;nbsp;myFont.FontFamily.GetCellDescent(myFont.Style)
textHeight&amp;nbsp;=&amp;nbsp;lineHeight&amp;nbsp;*&amp;nbsp;(lineAscent&amp;nbsp;+&amp;nbsp;lineDescent)&amp;nbsp;/&amp;nbsp;lineSpacing&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p class="normal"&gt;We&amp;rsquo;ll draw the reflected text first so that we can demonstrate the use of the &lt;span class="programelement"&gt;GraphicsState&lt;/span&gt; object. A &lt;span class="programelement"&gt;GraphicsState&lt;/span&gt; object maintains the state of the &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object as it currently stands. You can then scale, resize, and otherwise transform the &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object. You can immediately go back to a previous state by using the &lt;span class="programelement"&gt;Restore&lt;/span&gt; method of the &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object. Had we drawn the main one first, we would not have needed the &lt;span class="programelement"&gt;Restore&lt;/span&gt; method or the &lt;span class="programelement"&gt;GraphicsState&lt;/span&gt; object.&lt;/p&gt;&lt;p class="normal"&gt;First we&amp;rsquo;ll save the graphics state so that we can restore it later. To draw the reflection, we&amp;rsquo;ll use the &lt;span class="programelement"&gt;ScaleTransform&lt;/span&gt; method with a negative value. Using -&amp;thinsp;&amp;thinsp;1 will reflect the text with no distortion. Then we restore the previous state and draw the main text.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;&lt;span class="emphasis"&gt;myState&lt;/span&gt;&amp;nbsp;As&amp;nbsp;GraphicsState&amp;nbsp;=&amp;nbsp;&lt;span class="emphasis"&gt;g.Save()&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.&lt;span class="emphasis"&gt;ScaleTransform&lt;/span&gt;(1,&amp;nbsp;-1.0F)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.DrawString(txtSample.Text,&amp;nbsp;myFont,&amp;nbsp;myBackBrush,&amp;nbsp;0,&amp;nbsp;-textHeight)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.&lt;span class="emphasis"&gt;Restore(myState)&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.DrawString(txtSample.Text,&amp;nbsp;myFont,&amp;nbsp;myForeBrush,&amp;nbsp;0,&amp;nbsp;-textHeight)
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Shadowed Text&lt;/div&gt;&lt;p class="normal"&gt;This example draws the sample text with a solid brush and a shadow. To create the shadow, the sample text is drawn twice. The first time it&amp;rsquo;s offset and drawn in gray, and then it&amp;rsquo;s drawn again normally in black.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnShadowText_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myShadowBrush&amp;nbsp;As&amp;nbsp;Brush&amp;nbsp;=&amp;nbsp;Brushes.Gray
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myForeBrush&amp;nbsp;As&amp;nbsp;Brush&amp;nbsp;=&amp;nbsp;Brushes.Black
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img height="13" width="3" /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.DrawString(txtSample.Text,&amp;nbsp;myFont,&amp;nbsp;myShadowBrush,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;xLocation&amp;nbsp;+&amp;nbsp;Me.nudShadowDepth.Value,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;yLocation&amp;nbsp;+&amp;nbsp;Me.nudShadowDepth.Value)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.DrawString(txtSample.Text,&amp;nbsp;myFont,&amp;nbsp;myForeBrush,&amp;nbsp;xLocation,&amp;nbsp;yLocation)
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Sheared Text&lt;/div&gt;&lt;p class="normal"&gt;The following procedure shears the text so that it appears angled. This requires the use of a &lt;span class="programelement"&gt;Matrix&lt;/span&gt;, which will define the shear. Because we&amp;rsquo;ll be scaling, and scaling affects the entire &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object and not just the text, we need to reposition the origin of the &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object from (0, 0) to the (&lt;span class="variable"&gt;xLocation&lt;/span&gt;, &lt;span class="variable"&gt;yLocation&lt;/span&gt;) point.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnShearText_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img height="13" width="3" /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.TranslateTransform(xLocation,&amp;nbsp;yLocation)&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;Now we set a reference to the &lt;span class="programelement"&gt;Transform&lt;/span&gt; object for the current &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object, &lt;span class="programelement"&gt;Shear&lt;/span&gt; it by the specified amount, and finally, draw the main text.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myTransform&amp;nbsp;As&amp;nbsp;Matrix&amp;nbsp;=&amp;nbsp;g.Transform
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myTransform.&lt;span class="emphasis"&gt;Shear&lt;/span&gt;(nudSkew.Value,&amp;nbsp;0)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.Transform&amp;nbsp;=&amp;nbsp;myTransform
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.DrawString(txtSample.Text,&amp;nbsp;myFont,&amp;nbsp;myForeBrush,&amp;nbsp;0,&amp;nbsp;0)
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;Simple Text&lt;/div&gt;&lt;p class="normal"&gt;The following procedure simply takes the lines of text in the text box and places them in the &lt;span class="programelement"&gt;picDemoArea&lt;/span&gt; &lt;span class="programelement"&gt;PictureBox&lt;/span&gt;. The text will word wrap as necessary, but it will not scroll.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;btnSimpleText_Click(...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img height="13" width="3" /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;g.DrawString(txtLongText.Text,&amp;nbsp;myFont,&amp;nbsp;myForeBrush,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;New&amp;nbsp;RectangleF(0,&amp;nbsp;0,&amp;nbsp;picDemoArea.Width,&amp;nbsp;picDemoArea.Height))
End&amp;nbsp;Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="bb"&gt;&lt;div class="title"&gt;Conclusion&lt;/div&gt;&lt;p class="normal"&gt;In this sample application, you&amp;rsquo;ve seen that you display text within a bounding rectangle, whose size you must measure with the &lt;span class="programelement"&gt;MeasureString&lt;/span&gt; method to determine whether the text is appropriately positioned on the screen and whether it will fit in the space provided. You&amp;rsquo;ve also seen that you can use any font on your system when you&amp;rsquo;re drawing text. Powerful scaling and transformation methods let you twist, bend, shear, and distort text into a variety of shapes.&lt;/p&gt;&lt;h2 style="margin:12pt 0in 3pt;"&gt;&lt;span style="color:#993366;"&gt;&lt;em&gt;About The Author&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;&lt;h2 style="margin:12pt 0in 3pt;"&gt;&lt;span style="color:#993366;"&gt;&lt;em&gt;&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;&lt;/div&gt;Saahil Khan has been a Team Lead with &lt;a href="http://www.offshoreprogrammers.net/" rel="follow" title="http://www.offshoreprogrammers.net" target="_blank"&gt;Offshore Programmers Ltd &lt;/a&gt;and freelance write with &lt;a href="http://www.megasolutions.net/" rel="follow" title="http://cm.megasolutions.net" target="_blank"&gt;Megasolutions Ltd&lt;/a&gt;. He has over 5 years of experience in industrial automation and technologies like Java, .NET, and Flash. Saahil has extensive experience in strategizing/architecting solutions in .NET. Today, Sahil is completely focused on Microsoft .NET Technologies like C#, ASP.NET, and emerging technologies like FlashRemoting.&lt;img src="http://cm.megasolutions.net/aggbug.aspx?PostID=1632" width="1" height="1"&gt;</content><author><name>admin</name><uri>http://cm.megasolutions.net/members/admin.aspx</uri></author></entry><entry><title>Work with GDI+ Brushes</title><link rel="alternate" type="text/html" href="http://cm.megasolutions.net/blogs/gdi/archive/2006/10/02/Work-with-GDI_2B00_-Brushes.aspx" /><id>http://cm.megasolutions.net/blogs/gdi/archive/2006/10/02/Work-with-GDI_2B00_-Brushes.aspx</id><published>2006-10-02T06:02:00Z</published><updated>2006-10-02T06:02:00Z</updated><content type="html">Work with GDI+ Brushes &lt;p class="normal"&gt;In the previous tutorial, we showed how .NET gives us easy access to GDI+ via a comprehensive set of classes and methods from the &lt;span class="programelement"&gt;System.Drawing&lt;/span&gt; namespace. You saw that to draw you need a &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object and a &lt;span class="programelement"&gt;Pen&lt;/span&gt;. In this sample, we&amp;rsquo;ll show you how to use the &lt;span class="programelement"&gt;Brush&lt;/span&gt; object to fill closed shapes such as rectangles and ellipses.&lt;/p&gt;&lt;div class="bb"&gt;&lt;p class="normal"&gt;Whereas you use a pen to draw the outline of a shape, you use a brush to fill the interior of such a shape. You can choose to have both a border and a fill or to have only one of the two. To fill a shape, you need a &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object and a &lt;span class="programelement"&gt;Brush&lt;/span&gt;. The &lt;span class="programelement"&gt;Graphics&lt;/span&gt; object provides methods such as &lt;span class="programelement"&gt;FillRectangle&lt;/span&gt; and &lt;span class="programelement"&gt;Fill&amp;shy;Ellipse&lt;/span&gt;, while the &lt;span class="programelement"&gt;Brush&lt;/span&gt; gives you a way to specify the color, pattern, and other properties of the fill.&lt;/p&gt;&lt;p class="normal"&gt;Five kinds of brushes are available, two in the &lt;span class="programelement"&gt;System.Drawing&lt;/span&gt; namespace and three in &lt;span class="programelement"&gt;System.Drawing.Drawing2D&lt;/span&gt;. They are as follows:&lt;/p&gt;&lt;ul class="termdefnumber"&gt;&lt;li&gt;&lt;span class="lead-in"&gt;&lt;span class="programelement"&gt;System.Drawing.SolidBrush&lt;/span&gt;&lt;/span&gt; &lt;p class="normal"&gt;A brush composed of a single color. Use this brush to fill a shape with a solid color.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="lead-in"&gt;&lt;span class="programelement"&gt;System.Drawing.TextureBrush&lt;/span&gt;&lt;/span&gt; &lt;p class="normal"&gt;A brush that uses an image as its source. Use this brush to fill a shape from an image. For example, you might fill an oval shape from a portrait to imitate the look of an old-fashioned picture.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="lead-in"&gt;&lt;span class="programelement"&gt;System.Drawing.Drawing2D.HatchBrush&lt;/span&gt;&lt;/span&gt; &lt;p class="normal"&gt;A rectangular brush composed of three elements: a foreground color, which specifies the color of the lines in the hatch; a background color, which represents the color of the spaces between the lines; and a hatch pattern, which includes such choices as checkerboards, diagonals, diamonds, and zigzags.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="lead-in"&gt;&lt;span class="programelement"&gt;System.Drawing.Drawing2D.LinearGradientBrush&lt;/span&gt;&lt;/span&gt; &lt;p class="normal"&gt;A brush that lets you create a fill that transitions smoothly from one color to another. The &lt;span class="programelement"&gt;Blend&lt;/span&gt; property of the brush lets you determine the relative intensity of the colors at each point along the gradient.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="lead-in"&gt;&lt;span class="programelement"&gt;System.Drawing.Drawing2D.PathGradientBrush&lt;/span&gt;&lt;/span&gt; &lt;p class="normal"&gt;Whereas the &lt;span class="programelement"&gt;LinearGradient&lt;/span&gt; color transition goes from one edge of the shape to the other, the shading with this brush starts in the center of the shape and transitions to the outside. It can be used on simple shapes such as rectangles and ellipses, as well as on the more complex shapes represented by &lt;span class="programelement"&gt;GraphicsPath&lt;/span&gt; objects.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p class="normal"&gt;Figure 10-2 shows a &lt;span class="programelement"&gt;TextureBrush&lt;/span&gt; being used to fill a pair of ellipses using a photograph as its drawing source.&lt;/p&gt;&lt;div class="exhibit"&gt;&lt;img alt="Figure 10-2 A TextureBrush lets you use a graphical image as the source for your drawing." height="201" style="cursor:hand;" width="300" /&gt; &lt;div class="caption"&gt;&lt;span class="fignum"&gt;Figure 10-2.&lt;/span&gt; &lt;span class="description"&gt;A TextureBrush lets you use a graphical image as the source for your drawing.&lt;/span&gt; &lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="bb"&gt;&lt;div class="title"&gt;Code Walkthrough&lt;/div&gt;&lt;p class="normal"&gt;The &lt;span class="programelement"&gt;RedrawPicture&lt;/span&gt; procedure provides the meat of the demonstration. It creates one of the five types of brushes and assigns the appropriate user-defined properties to the brush. The brush is then assigned to &lt;span class="programelement"&gt;m_Brush&lt;/span&gt;, which is used to draw one of three different shapes. There is also code to ensure that the user interface (UI) displays only the options that are appropriate for the type of brush being used. As you&amp;rsquo;ll notice, this procedure handles virtually all events fired by the UI.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;Private&amp;nbsp;Sub&amp;nbsp;RedrawPicture(ByVal&amp;nbsp;sender&amp;nbsp;As&amp;nbsp;System.Object,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ByVal&amp;nbsp;e&amp;nbsp;As&amp;nbsp;System.EventArgs)&amp;nbsp;Handles&amp;nbsp;MyBase.Activated,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cboBrushType.SelectedIndexChanged,&amp;nbsp;cboDrawing.SelectedIndexChanged,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;txtColor1.TextChanged,&amp;nbsp;cboWrapMode.SelectedIndexChanged,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cboHatchStyle.SelectedIndexChanged,&amp;nbsp;txtColor2.TextChanged,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cboGradientMode.SelectedIndexChanged,&amp;nbsp;nudRotation.ValueChanged,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nudGradientBlend.ValueChanged,&amp;nbsp;MyBase.Resize&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;After clearing the picture box and the status bar, we&amp;rsquo;re ready to get to the business of creating a brush.&lt;/p&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;&lt;span class="programelement"&gt;SolidBrush&lt;/span&gt;&lt;/div&gt;&lt;p class="normal"&gt;The first option is a solid brush, based on the user-selected color. We&amp;rsquo;ll assign it to &lt;span class="programelement"&gt;m_brush&lt;/span&gt;, our class-level brush variable, because doing that will make IntelliSense help available on the brush object.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Select&amp;nbsp;Case&amp;nbsp;cboBrushType.Text
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Case &amp;quot;Solid&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img height="13" width="3" /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;mySolidBrush&amp;nbsp;As&amp;nbsp;New&amp;nbsp;SolidBrush(m_Color1)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Brush&amp;nbsp;=&amp;nbsp;mySolidBrush&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;&lt;span class="programelement"&gt;HatchBrush&lt;/span&gt;&lt;/div&gt;&lt;p class="normal"&gt;The second option is to create a new &lt;span class="programelement"&gt;HatchBrush&lt;/span&gt; using the user-selected colors for foreground and background color settings. Because the &lt;span class="programelement"&gt;HatchStyle&lt;/span&gt; property is read-only, it must be set as we instantiate the &lt;span class="programelement"&gt;HatchBrush&lt;/span&gt;.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Case &amp;quot;Hatch&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img height="13" width="3" /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myHatchBrush&amp;nbsp;As&amp;nbsp;New&amp;nbsp;HatchBrush(&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CType(cboHatchStyle.SelectedItem,&amp;nbsp;HatchStyle),&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Color1,&amp;nbsp;m_Color2)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Brush&amp;nbsp;=&amp;nbsp;myHatchBrush&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;&lt;span class="programelement"&gt;TextureBrush&lt;/span&gt;&lt;/div&gt;&lt;p class="normal"&gt;The third option is to create a new &lt;span class="programelement"&gt;TextureBrush&lt;/span&gt; based on a bitmap picture of water lilies. The bitmap can also be a pattern you&amp;rsquo;ve created. The &lt;span class="programelement"&gt;WrapMode&lt;/span&gt; determines how the brush will be tiled if it&amp;rsquo;s not spread over the entire graphics area. The &lt;span class="programelement"&gt;RotateTransform&lt;/span&gt; method rotates the brush by the user-specified amount. We could also have used a &lt;span class="programelement"&gt;ScaleTransform&lt;/span&gt; to re-shape the brush. For example, this statement cuts the width of the brush in half and doubles the height: &lt;span class="inlinecode"&gt;myTextureBrush.ScaleTransform(0.5F, 2.0F)&lt;/span&gt;&lt;/p&gt;&lt;div class="caution"&gt;&lt;strong&gt;CAUTION&lt;/strong&gt;&lt;br /&gt;Be cautious when creating a &lt;span class="programelement"&gt;TextureBrush&lt;/span&gt;. If you define a &lt;span class="programelement"&gt;Rectangle&lt;/span&gt; larger than the bitmap, it will trigger an &lt;span class="programelement"&gt;OutOfMemory&lt;/span&gt; exception.&lt;/div&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Case &amp;quot;Texture&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img height="13" width="3" /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myTextureBrush&amp;nbsp;As&amp;nbsp;New&amp;nbsp;TextureBrush(&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;New&amp;nbsp;Bitmap(&amp;quot;..\WaterLilies.jpg&amp;quot;),&amp;nbsp;m_BrushSize)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myTextureBrush.WrapMode&amp;nbsp;=&amp;nbsp;CType(cboWrapMode.SelectedItem,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WrapMode)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myTextureBrush.RotateTransform(nudRotation.Value)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Brush&amp;nbsp;=&amp;nbsp;myTextureBrush&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;&lt;span class="programelement"&gt;LinearGradientBrush&lt;/span&gt;&lt;/div&gt;&lt;p class="normal"&gt;Our next option is to create a new &lt;span class="programelement"&gt;LinearGradientBrush&lt;/span&gt;. The brush is based on a size defined by a rectangle. In this case, we&amp;rsquo;re using the user-defined &lt;span class="programelement"&gt;m_BrushSize&lt;/span&gt;. Two colors are used, one for defining the start color of the gradient and one for defining the end color.&lt;/p&gt;&lt;div class="tip"&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;You can create more advanced gradients by using the &lt;span class="programelement"&gt;Blend&lt;/span&gt; property, which lets you specify the relative intensity of each of the colors along the gradient path.&lt;/div&gt;&lt;p class="normal"&gt;We define the &lt;span class="programelement"&gt;LinearGradientMode&lt;/span&gt; in the constructor. This controls the direction of the gradient. We could have used an angle, but for simplicity that isn&amp;rsquo;t done here. The &lt;span class="programelement"&gt;WrapMode&lt;/span&gt; determines how the gradient will be tiled if it is not spread over the entire graphics area. The &lt;span class="programelement"&gt;LinearGradientBrush&lt;/span&gt; can use all values for &lt;span class="programelement"&gt;WrapMode&lt;/span&gt; except &lt;span class="programelement"&gt;Clamp&lt;/span&gt;.&lt;/p&gt;&lt;p class="normal"&gt;To set the point where the blending will focus, you can use any value between 0 and 1. The default is 1.&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Case &amp;quot;LinearGradient&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img height="13" width="3" /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myLinearGradientBrush&amp;nbsp;As&amp;nbsp;New&amp;nbsp;LinearGradientBrush(&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_BrushSize,&amp;nbsp;m_Color1,&amp;nbsp;m_Color2,&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CType(cboGradientMode.SelectedItem,&amp;nbsp;&lt;span class="emphasis"&gt;LinearGradientMode&lt;/span&gt;))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;CType(cboWrapMode.SelectedItem,&amp;nbsp;WrapMode)&amp;nbsp;&amp;lt;&amp;gt;&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WrapMode.Clamp&amp;nbsp;Then
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myLinearGradientBrush.&lt;span class="emphasis"&gt;WrapMode&lt;/span&gt;&amp;nbsp;=&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CType(cboWrapMode.SelectedItem,&amp;nbsp;WrapMode)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Me.sbrDrawingStatus.Text&amp;nbsp;+=&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;A&amp;nbsp;Linear&amp;nbsp;Gradient&amp;nbsp;Brush&amp;nbsp;cannot&amp;nbsp;use&amp;nbsp;the &amp;quot; &amp;amp;&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;Clamp&amp;nbsp;WrapMode.&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;End&amp;nbsp;If
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myLinearGradientBrush.&lt;span class="emphasis"&gt;RotateTransform&lt;/span&gt;(nudRotation.Value)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myLinearGradientBrush.&lt;span class="emphasis"&gt;SetBlendTriangularShape&lt;/span&gt;(&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nudGradientBlend.Value)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Brush&amp;nbsp;=&amp;nbsp;myLinearGradientBrush&lt;/pre&gt;&lt;/div&gt;&lt;p class="normal"&gt;For more advanced uses, you can use the &lt;span class="programelement"&gt;SetSigmaBellShape&lt;/span&gt; method to set where the center of the gradient occurs, as in this line of code: &lt;span class="inlinecode"&gt;myLinearGradientBrush.SetSigmaBellShape(0.2)&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;div class="cc"&gt;&lt;div class="title"&gt;&lt;span class="programelement"&gt;PathGradient&lt;/span&gt;&lt;/div&gt;&lt;p class="normal"&gt;The last option lets us create a path by defining a set of points and then follow that path by using &lt;span class="programelement"&gt;PathGradient&lt;/span&gt;. In cases like this, you&amp;rsquo;ll often define and use a &lt;span class="programelement"&gt;GraphicsPath&lt;/span&gt; object instead of a set of points, but in this case, we&amp;rsquo;re using a simple triangle. Once we&amp;rsquo;ve defined the triangle, we create a new &lt;span class="programelement"&gt;PathGradient&amp;shy;Brush&lt;/span&gt; based on the path just created. Anything not bounded by the path will be transparent instead of containing coloring.&lt;/p&gt;&lt;p class="normal"&gt;The colors for the &lt;span class="programelement"&gt;PathGradient&lt;/span&gt; are defined differently than other gradients because we can use different colors for each side. In this case, we&amp;rsquo;re using only one color, but we could assign a different color to each side of the path. The &lt;span class="programelement"&gt;CenterColor&lt;/span&gt; is the color that the edges blend into. &lt;span class="programelement"&gt;SurroundColors&lt;/span&gt; is an array of colors that defines the colors around the edge. We could also set the &lt;span class="programelement"&gt;CenterPoint&lt;/span&gt; property somewhere other than the center of the path (even outside the rectangle bounding the path)&amp;mdash;for example: &lt;span class="inlinecode"&gt;myPathGradientBrush.CenterPoint = New PointF(50, 50)&lt;/span&gt;&lt;/p&gt;&lt;div class="codeblock_unnumbered"&gt;&lt;pre class="codebody"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Case &amp;quot;PathGradient&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;img height="13" width="3" /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;pathPoint()&amp;nbsp;As&amp;nbsp;Point&amp;nbsp;=&amp;nbsp;{New&amp;nbsp;Point(0,&amp;nbsp;m_BrushSize.Height),&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;New&amp;nbsp;Point(m_BrushSize.Width,&amp;nbsp;m_BrushSize.Height),&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;New&amp;nbsp;Point(m_BrushSize.Width,&amp;nbsp;0)}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Dim&amp;nbsp;myPathGradientBrush&amp;nbsp;As&amp;nbsp;New&amp;nbsp;PathGradientBrush(pathPoint)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myPathGradientBrush.&lt;span class="emphasis"&gt;CenterColor&lt;/span&gt;&amp;nbsp;=&amp;nbsp;m_Color1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myPathGradientBrush.&lt;span class="emphasis"&gt;SurroundColors&lt;/span&gt;&amp;nbsp;=&amp;nbsp;New&amp;nbsp;Color()&amp;nbsp;{m_Color2}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myPathGradientBrush.&lt;span class="emphasis"&gt;WrapMode&lt;/span&gt;&amp;nbsp;=&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CType(cboWrapMode.SelectedItem,&amp;nbsp;WrapMode)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myPathGradientBrush.&lt;span class="emphasis"&gt;RotateTransform&lt;/span&gt;(nudRotation.Value)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;myPathGradientBrush.&lt;span class="emphasis"&gt;SetBlendTriangularShape&lt;/span&gt;(&amp;nbsp;_
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;nudGradientBlend.Value)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Brush&amp;nbsp;=&amp;nbsp;myPathGradientBrush&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="bb"&gt;&lt;div class="title"&gt;Conclusion&lt;/div&gt;&lt;p class="normal"&gt;In this sample application, we&amp;rsquo;ve shown you how to use a &lt;span class="programelement"&gt;Brush&lt;/span&gt; to fill the interiors of shapes. A &lt;span class="programelement"&gt;HatchBrush&lt;/span&gt; is a brush with a variety of possible patterns. A &lt;span class="programelement"&gt;TextureBrush&lt;/span&gt; is one whose source is an image. Gradient brushes let you create fills that transition smoothly from one color to another.&lt;/p&gt;&lt;h2 style="margin:12pt 0in 3pt;"&gt;&lt;span style="color:#993366;"&gt;&lt;em&gt;About The Author&lt;/em&gt;&lt;/span&gt;&lt;/h2&gt;&lt;/div&gt;Saahil Khan has been a Team Lead with &lt;a href="http://www.offshoreprogrammers.net/" rel="follow" title="http://www.offshoreprogrammers.net" target="_blank"&gt;Offshore Programmers Ltd &lt;/a&gt;and freelance write with &lt;a href="http://www.megasolutions.net/" rel="follow" title="http://cm.megasolutions.net" target="_blank"&gt;Megasolutions Ltd&lt;/a&gt;. He has over 5 years of experience in industrial automation and technologies like Java, .NET, and Flash. Saahil has extensive experience in strategizing/architecting solutions in .NET. Today, Sahil is completely focused on Microsoft .NET Technologies like C#, ASP.NET, and emerging technologies like FlashRemoting.&lt;img src="http://cm.megasolutions.net/aggbug.aspx?PostID=1631" width="1" height="1"&gt;</content><author><name>admin</name><uri>http://cm.megasolutions.net/members/admin.aspx</uri></author></entry><entry><title>Work with GDI+ Pens</title><link rel="alternate" type="text/html" href="http://cm.megasolutions.net/blogs/gdi/archive/2006/10/02/Work-with-GDI_2B00_-Pens.aspx" /><id>http://cm.megasolutions.net/blogs/gdi/archive/2006/10/02/Work-with-GDI_2B00_-Pens.aspx</id><published>2006-10-02T05:32:00Z</published><updated>2006-10-02T05:32:00Z</updated><content type="html">&lt;p class="MsoNormal" style="margin:0in 0in 0pt;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;This sample demonstrates most of the features available when using the GDI+ &lt;span class="programelement"&gt;&lt;em&gt;Pen&lt;/em&gt;&lt;/span&gt; object, which you use to draw lines and shapes. In succeeding samples, we&amp;rsquo;ll look at working with brushes, text, images, screen savers, and animation.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;&lt;em&gt;&lt;span class="programelement"&gt;&lt;/span&gt;&lt;/em&gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt;"&gt;&lt;span style="font-size:15pt;color:black;"&gt;&lt;font face="Times New Roman"&gt;&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt;"&gt;&lt;span style="font-size:15pt;color:black;"&gt;&lt;font face="Times New Roman"&gt;New Concepts&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;To draw lines or curves, you need two objects: a &lt;span class="programelement"&gt;&lt;em&gt;Graphics&lt;/em&gt;&lt;/span&gt; object and a &lt;span class="programelement"&gt;&lt;em&gt;Pen&lt;/em&gt;&lt;/span&gt; object. The &lt;span class="programelement"&gt;&lt;em&gt;Graphics&lt;/em&gt;&lt;/span&gt; object has methods such as &lt;span class="programelement"&gt;&lt;em&gt;DrawLine&lt;/em&gt;&lt;/span&gt;, &lt;span class="programelement"&gt;&lt;em&gt;DrawEllipse&lt;/em&gt;&lt;/span&gt;, &lt;span class="programelement"&gt;&lt;em&gt;DrawRectangle&lt;/em&gt;&lt;/span&gt;, and others. A &lt;span class="programelement"&gt;&lt;em&gt;Graphics&lt;/em&gt;&lt;/span&gt; object is always associated with a specific object&amp;mdash;such as a form or a &lt;span class="programelement"&gt;&lt;em&gt;PictureBox&lt;/em&gt;&lt;/span&gt;&amp;mdash;that you can think of as the canvas on which it draws. You can think of the &lt;span class="programelement"&gt;&lt;em&gt;Graphics&lt;/em&gt;&lt;/span&gt; object as something like your hand, which you use to draw lines and shapes.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;Like your hand, a &lt;span class="programelement"&gt;&lt;em&gt;Graphics&lt;/em&gt;&lt;/span&gt; object needs a drawing instrument to actually do a drawing. That&amp;rsquo;s where the &lt;span class="programelement"&gt;&lt;em&gt;Pen&lt;/em&gt;&lt;/span&gt; object comes in. It has properties that let you determine its width, its color, the style of line it draws, how intersecting lines should be joined, and much more. Some key properties of the &lt;span class="programelement"&gt;&lt;em&gt;Pen&lt;/em&gt;&lt;/span&gt; object include the following:&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt 0.5in;text-indent:-0.25in;tab-stops:list .5in;"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="font-size:10pt;font-family:Wingdings;"&gt;&lt;span&gt;&lt;font size="3"&gt;&lt;img alt="*" height="13" src="http://cm.megasolutions.net/tiny_mce/jscripts/tiny_mce/PicExportError" width="13" /&gt;&lt;/font&gt;&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;span class="programelement"&gt;&lt;em&gt;Alignment&lt;/em&gt;&lt;/span&gt; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in auto 0.5in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;Determines which side of the designated line the pen should draw on. For instance, Inset will cause the pen to draw on the inside of a circle.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt 0.5in;text-indent:-0.25in;tab-stops:list .5in;"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="font-size:10pt;font-family:Wingdings;"&gt;&lt;span&gt;&lt;font size="3"&gt;&lt;img alt="*" height="13" src="http://cm.megasolutions.net/tiny_mce/jscripts/tiny_mce/PicExportError" width="13" /&gt;&lt;/font&gt;&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;span class="programelement"&gt;&lt;em&gt;DashCap&lt;/em&gt;&lt;/span&gt; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in auto 0.5in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;Determines the cap that should be put on both ends of any dashes in a line drawn by the pen. For example, caps can be round, flat, or triangular.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt 0.5in;text-indent:-0.25in;tab-stops:list .5in;"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="font-size:10pt;font-family:Wingdings;"&gt;&lt;span&gt;&lt;font size="3"&gt;&lt;img alt="*" height="13" src="http://cm.megasolutions.net/tiny_mce/jscripts/tiny_mce/PicExportError" width="13" /&gt;&lt;/font&gt;&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;span class="programelement"&gt;&lt;em&gt;DashStyle&lt;/em&gt;&lt;/span&gt; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in auto 0.5in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;Determines the look of the line. It can be solid, dashes, dots and dashes, or even custom.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt 0.5in;text-indent:-0.25in;tab-stops:list .5in;"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="font-size:10pt;font-family:Wingdings;"&gt;&lt;span&gt;&lt;font size="3"&gt;&lt;img alt="*" height="13" src="http://cm.megasolutions.net/tiny_mce/jscripts/tiny_mce/PicExportError" width="13" /&gt;&lt;/font&gt;&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;span class="programelement"&gt;&lt;em&gt;EndCap&lt;/em&gt;&lt;/span&gt; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in auto 0.5in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;Determines the cap that should be put on the end of a line drawn by the pen.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt 0.5in;text-indent:-0.25in;tab-stops:list .5in;"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="font-size:10pt;font-family:Wingdings;"&gt;&lt;span&gt;&lt;font size="3"&gt;&lt;img alt="*" height="13" src="http://cm.megasolutions.net/tiny_mce/jscripts/tiny_mce/PicExportError" width="13" /&gt;&lt;/font&gt;&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;span class="programelement"&gt;&lt;em&gt;LineJoin&lt;/em&gt;&lt;/span&gt; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in auto 0.5in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;Determines how two adjacent lines should be joined. For instance, the join can be rounded, beveled, or mitered.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt 0.5in;text-indent:-0.25in;tab-stops:list .5in;"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="font-size:10pt;font-family:Wingdings;"&gt;&lt;span&gt;&lt;font size="3"&gt;&lt;img alt="*" height="13" src="http://cm.megasolutions.net/tiny_mce/jscripts/tiny_mce/PicExportError" width="13" /&gt;&lt;/font&gt;&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;span class="programelement"&gt;&lt;em&gt;MiterLimit&lt;/em&gt;&lt;/span&gt; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in auto 0.5in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;Determines when the miter edge of two adjacent lines should be clipped. The default is 10.0.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt 0.5in;text-indent:-0.25in;tab-stops:list .5in;"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="font-size:10pt;font-family:Wingdings;"&gt;&lt;span&gt;&lt;font size="3"&gt;&lt;img alt="*" height="13" src="http://cm.megasolutions.net/tiny_mce/jscripts/tiny_mce/PicExportError" width="13" /&gt;&lt;/font&gt;&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;span class="programelement"&gt;&lt;em&gt;StartCap&lt;/em&gt;&lt;/span&gt; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in auto 0.5in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;Determines the cap that should be put on the start of a line drawn by the pen.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt 0.5in;text-indent:-0.25in;tab-stops:list .5in;"&gt;&lt;font face="Times New Roman"&gt;&lt;span style="font-size:10pt;font-family:Wingdings;"&gt;&lt;span&gt;&lt;font size="3"&gt;&lt;img alt="*" height="13" src="http://cm.megasolutions.net/tiny_mce/jscripts/tiny_mce/PicExportError" width="13" /&gt;&lt;/font&gt;&lt;span style="font:7pt 'Times New Roman';"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;font size="3"&gt;&lt;span class="programelement"&gt;&lt;em&gt;Width&lt;/em&gt;&lt;/span&gt; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in auto 0.5in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;The width of the pen, in pixels.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;One other object that will figure largely in your GDI+ work is the &lt;span class="programelement"&gt;&lt;em&gt;Point&lt;/em&gt;&lt;/span&gt; object. It represents a single point on the drawing surface, indicated by x- and y-coordinates, expressed as integers. A companion object, &lt;span class="programelement"&gt;&lt;em&gt;PointF&lt;/em&gt;&lt;/span&gt;, accepts floating-point numbers for its coordinates. Figure 10-1 shows three lines drawn using several of these key properties.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt;"&gt;&lt;font face="Times New Roman" size="3"&gt;&lt;/font&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt; &lt;img height="336" src="http://cm.megasolutions.net/blogs/blgimages/f10wp01.png" style="width:527px;height:336px;" width="527" /&gt; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;&lt;span class="fignum"&gt;&lt;strong&gt;Figure 10-1.&lt;/strong&gt;&lt;/span&gt; &lt;span class="description"&gt;&lt;em&gt;With GDI+ pens, you can choose from a wide variety of line styles, start and end caps, and more.&lt;/em&gt;&lt;/span&gt; &lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="margin:0in 0in 0pt;"&gt;&lt;span style="font-size:15pt;color:black;"&gt;&lt;font face="Times New Roman"&gt;Code Walkthrough&lt;/font&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;The heart of the sample is the &lt;span class="programelement"&gt;&lt;em&gt;RedrawPicture&lt;/em&gt;&lt;/span&gt; procedure, which collects all the user-defined information and uses it to create a &lt;span class="programelement"&gt;&lt;em&gt;Pen&lt;/em&gt;&lt;/span&gt; object. The &lt;span class="programelement"&gt;&lt;em&gt;Pen&lt;/em&gt;&lt;/span&gt; object is then used to draw one of three different kinds of drawings. As you can see in the following code, this procedure handles almost all events triggered by the user interface, specifically the change events of combo boxes and other controls for which the user makes choices.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;Private&amp;nbsp;Sub&amp;nbsp;RedrawPicture(ByVal&amp;nbsp;sender&amp;nbsp;As&amp;nbsp;System.Object,&amp;nbsp;_&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ByVal&amp;nbsp;e&amp;nbsp;As&amp;nbsp;System.EventArgs)&amp;nbsp;_&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Handles&amp;nbsp;MyBase.Activated,&amp;nbsp;comboShape.SelectedIndexChanged,&amp;nbsp;_&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;updownWidth.ValueChanged,&amp;nbsp;txtColor.TextChanged,&amp;nbsp;_&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;comboAlignment.SelectedIndexChanged,&amp;nbsp;_&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;comboStartCap.SelectedIndexChanged,&amp;nbsp;comboEndCap.SelectedIndexChanged,&amp;nbsp;_&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;comboDashCap.SelectedIndexChanged,&amp;nbsp;_&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;comboLineJoin.SelectedIndexChanged,&amp;nbsp;_&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;comboLineStyle.SelectedIndexChanged,&amp;nbsp;updownMiterLimit.ValueChanged,&amp;nbsp;_&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;comboTransform.SelectedIndexChanged,&amp;nbsp;comboBrush.SelectedIndexChanged&lt;/font&gt;&lt;/pre&gt;&lt;p class="normal" style="margin:auto 0in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;To draw, we must first create the &lt;span class="programelement"&gt;&lt;em&gt;Graphics&lt;/em&gt;&lt;/span&gt; object that we&amp;rsquo;ll use to draw on the &lt;span class="programelement"&gt;&lt;em&gt;PictureBox&lt;/em&gt;&lt;/span&gt; (which is named &lt;span class="emphasis"&gt;&lt;em&gt;pbLines&lt;/em&gt;&lt;/span&gt;). Then we use the &lt;span class="programelement"&gt;&lt;em&gt;Graphics&lt;/em&gt;&lt;/span&gt; object &lt;span class="programelement"&gt;&lt;em&gt;Clear&lt;/em&gt;&lt;/span&gt; method to remove anything that might already be in the picture box. Next, we get rid of any current transform on the &lt;span class="programelement"&gt;&lt;em&gt;Pen&lt;/em&gt;&lt;/span&gt; object, and we set the &lt;span class="programelement"&gt;&lt;em&gt;DashPattern&lt;/em&gt;&lt;/span&gt; that will be implemented when the user selects a custom line style.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_graphic&amp;nbsp;=&amp;nbsp;pbLines.CreateGraphics()&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_graphic.Clear(pbLines.BackColor)&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pbLines.Refresh()&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Pen.ResetTransform()&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Pen.DashPattern&amp;nbsp;=&amp;nbsp;New&amp;nbsp;Single()&amp;nbsp;{0.5,&amp;nbsp;0.25,&amp;nbsp;0.75,&amp;nbsp;1.5}&lt;/font&gt;&lt;/pre&gt;&lt;p class="normal" style="margin:auto 0in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;A pen can have either a color or a brush assigned to it, but not both. We determine which of the two to use depending on the user&amp;rsquo;s choice in the &lt;span class="programelement"&gt;&lt;em&gt;radio&amp;shy;Color&lt;/em&gt;&lt;/span&gt; check box. If Brush is checked, we&amp;rsquo;ll select the kind of brush the user indicated in the Brush combo box. There are four choices, which are described in the following paragraph.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="normal" style="margin:auto 0in;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;A Solid brush is just what it sounds like. A Hatch brush can have a variety of styles, including &lt;span class="programelement"&gt;&lt;em&gt;Horizontal&lt;/em&gt;&lt;/span&gt; (a pattern of horizontal lines), &lt;span class="programelement"&gt;&lt;em&gt;ZigZag&lt;/em&gt;&lt;/span&gt; (horizontal lines composed of zigzags), and &lt;span class="programelement"&gt;&lt;em&gt;Plaid&lt;/em&gt;&lt;/span&gt; (the style used in our sample application). The Texture brush &amp;ldquo;paints&amp;rdquo; using an image as its base &amp;ldquo;pigment.&amp;rdquo; The Gradient brush in this example contains Alice Blue in the upper left corner of the &lt;span class="programelement"&gt;&lt;em&gt;PictureBox&lt;/em&gt;&lt;/span&gt; and ends with Dark Blue in the lower right, with a gradual transition in between.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;p class="MsoNormal" style="background:#99ccff;margin:0in 0in 0pt;"&gt;&lt;font size="3"&gt;&lt;font face="Times New Roman"&gt;&lt;strong&gt;TIP&lt;/strong&gt;&lt;br /&gt;Assigning a &lt;span class="programelement"&gt;&lt;em&gt;Color&lt;/em&gt;&lt;/span&gt; to a pen is identical to assigning it a &lt;span class="programelement"&gt;&lt;em&gt;SolidBrush&lt;/em&gt;&lt;/span&gt;.&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;If&amp;nbsp;radioColor.Checked&amp;nbsp;Then&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;m_Pen.Color&amp;nbsp;=&amp;nbsp;m_penColor&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Else&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Select&amp;nbsp;Case&amp;nbsp;comboBrush.Text&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Case &amp;quot;Solid&amp;quot;&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;&lt;em&gt;m_penBrush&amp;nbsp;=&amp;nbsp;New&amp;nbsp;SolidBrush(m_penColor)&lt;/em&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Case &amp;quot;Hatch&amp;quot;&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;&lt;em&gt;m_penBrush&amp;nbsp;=&amp;nbsp;New&amp;nbsp;HatchBrush(HatchStyle.Plaid,&amp;nbsp;m_penColor)&lt;/em&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;Case &amp;quot;Texture&amp;quot;&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;&lt;em&gt;m_penBrush&amp;nbsp;=&amp;nbsp;New&amp;nbsp;TextureBrush(&amp;nbsp;_&lt;/em&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&lt;span class="emphasis"&gt;&lt;em&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;New&amp;nbsp;Bitmap(&amp;quot;..\WaterLilies.jpg&amp;quot;),&amp;nbsp;WrapMode.Tile)&lt;/em&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Case &amp;quot;Gradient&amp;quot;&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="emphasis"&gt;&lt;em&gt;m_penBrush&amp;nbsp;=&amp;nbsp;New&amp;nbsp;LinearGradientBrush(&amp;nbsp;_&lt;/em&gt;&lt;/span&gt;&lt;/font&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;span class="emphasis"&gt;&lt;em&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;New&amp;nbsp;Point(0,&amp;nbsp;0),&amp;nbsp;_&lt;/font&gt;&lt;/em&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;span class="emphasis"&gt;&lt;em&gt;&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;New&amp;nbsp;Point(pbLines.Width,&amp;nbsp;pbLines.Height),&amp;nbsp;_&lt;/font&gt;&lt;/em&gt;&lt;/span&gt;&lt;/pre&gt;&lt;pre style="margin-top:3.75pt;background:#eeeeee;"&gt;&lt;font face="Courier New"&gt;&lt;span class="emphasis"&gt;&lt;em&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Color.AliceBlue,&amp;nbsp;Color.DarkBlue)&lt;/em&gt;&lt;/span&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp