Drawing Graphics using PowerShell 1.0 and GDI+
Previous | Table of Contents | Next |
Creating GUIs in Windows PowerShell 1.0 with WinForms | Using COM with Windows PowerShell |
Purchase and download the full PDF version of this PowerShell eBook for only $8.99 |
Windows PowerShell leverages the GDI+ library to provide graphics drawing capabilities. In fact, PowerShell provides the same level of drawing capabilities through GDI+ as those available in other programming languages such as C# and Visual Basic. In fact, those familiar with GDI+ in the context of other programming languages will find the learning curve to be extremely shallow. Those with no previous experience of GDI+ graphics drawing will quickly find that it is both intuitive and easy to learn.
An Overview of GDI+
Loading the GDI+ and WinForms .NET Assemblies
As previously mentioned, Windows PowerShell GDI+ development is typically performed in conjunction with WinForms. Neither the GDI+, nor the WinForms .NET assemblies are loaded into the Windows PowerShell environment by default. It is necessary, therefore, to load these assemblies before beginning the development process. GDI+ and Winforms reside in the [Windows.Drawing] and [Windows.Windows.Forms] assemblies respectively. These can be loaded using the following commands:
[reflection.assembly]::LoadWithPartialName( "System.Windows.Forms") [reflection.assembly]::LoadWithPartialName( "System.Drawing")
Creating Drawing Objects
Once the appropriate .NET assemblies are loaded, the next step is to create objects with which to draw graphics. The example in this chapter will focus on the Pen and SolidBrush objects. GDI+ provides a range of other drawing objects, details of which are covered in the MSDN .NET documentation.
The following example creates SolidBrush and Pen objects which will be used later in this chapter to perform drawing operations:
$myBrush = new-object Drawing.SolidBrush green $mypen = new-object Drawing.Pen black
Setting Properties of a GDI+ Drawing Object
Just as with any other object, each GDI+ drawing object contains a set of methods and properties which are accessible from within Windows PowerShell. A full list of available methods and properties of an object may be obtained using the get-member cmdlet. For example,the following command lists all the methods and properties of the $mypen object created in the previous section:
PS C:\tmp> $pen | get-member TypeName: System.Drawing.Pen Name MemberType Definition ---- ---------- ---------- Clone Method System.Object Clone() CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(Type requestedT... Dispose Method System.Void Dispose() . . . Alignment Property System.Drawing.Drawing2D.PenAlignment Alignment {get;set;} Brush Property System.Drawing.Brush Brush {get;set;} Color Property System.Drawing.Color Color {get;set;} CompoundArray Property System.Single[] CompoundArray {get;set;} CustomEndCap Property System.Drawing.Drawing2D.CustomLineCap CustomEndCap {get;set;} CustomStartCap Property System.Drawing.Drawing2D.CustomLineCap CustomStartCap {get;... DashCap Property System.Drawing.Drawing2D.DashCap DashCap {get;set;} DashOffset Property System.Single DashOffset {get;set;} DashPattern Property System.Single[] DashPattern {get;set;} DashStyle Property System.Drawing.Drawing2D.DashStyle DashStyle {get;set;} EndCap Property System.Drawing.Drawing2D.LineCap EndCap {get;set;} LineJoin Property System.Drawing.Drawing2D.LineJoin LineJoin {get;set;} MiterLimit Property System.Single MiterLimit {get;set;} PenType Property System.Drawing.Drawing2D.PenType PenType {get;} StartCap Property System.Drawing.Drawing2D.LineCap StartCap {get;set;} Transform Property System.Drawing.Drawing2D.Matrix Transform {get;set;} Width Property System.Single Width {get;set;}
With knowledge of these methods and properties, it is possible to change characteristics of an object. For example, the color and width properties of the $mypen object may be modified as follows:
$mypen.color = "red" $mypen.width = 10
Creating the WinForms Form and the Graphics Object
Having defined the GDI+ drawing objects, the next step is to create a canvas on which to draw. For the purposes of this example, a Winforms Form will act as the drawing canvas. To create this form it is necessary to make use of the WinForms API:
$form = New-Object Windows.Forms.Form
Once the Form has been created, the next step is to create a graphics object on which to draw using the createGraphics() method of the Form object:
$formGraphics = $form.createGraphics()
The Paint Event Handler
Applications with graphical user interfaces are primarily event driven. This means that event handlers must be written to define what actions are to be performed when certain activities occur with regard to the user interface. When a user clicks a button, for example, an event handler performs the necessary tasks associated with that button being pressed (if the button was a Close button, the event handler would be responsible for exiting the application).
In terms of graphics drawing, when a form is displayed a paint event is triggered. Similarly, when a form needs to be repainted (for example because all or part of the form was obscured and then uncovered by another window), the paint event is also triggered. It is, therefore, the job of the paint handler to perform the graphics drawing tasks. A paint event handler is declared in Windows PowerShell via a call to add_paint():
$form.add_paint( { # code or call to a function to perform graphics drawing } )
Drawing Graphics with Windows PowerShell and GDI+
As outlined in the preceding section, the code to draw the graphics is contained in the paint event handler. In this section we will look at some basic drawing methods.
The following example draws a line from the point at co-ordinates x=10, y=10 to the point at x=190, y=190. It does so using the previously created $myPen object.
$formGraphics.DrawLine($pen, 10, 10, 190, 190)
A filled ellipse is drawn by calling the FillEllipse() method of the graphics object, passing through a suitable drawing object (e.g a brush or a pen) and defining a rectangle into which the ellipse is to fit:
$formGraphics.FillEllipse($myBrush, 20, 20, 180, 180)
Similarly, a filed rectangle can be drawn using the FillRectange() method, once again passing through a pen or brush and defining the rectangle:
$formGraphics.FillRectangle($myBrush, 0,0,200,200)
In the above example, rectangles were defined by passing co-ordinates directly through as arguments to the drawing methods. It is also possible to create Rectangle objects:
$rect = new-object Drawing.Rectangle 0, 0, 200, 200 $formGraphics.FillRectangle($myBrush, $rect)
No graphics drawing tutorial would be complete without a single bezier spline, and this chapter is no exception. The following example defines the start, end and two control points of a bezier spline and passes them through, along with a pen object, to the DrawBezier() method of the graphics object:
$p1 = new-object Drawing.Point 10, 100 $p2 = new-object Drawing.Point 100, 10 $p3 = new-object Drawing.Point 170, 170 $p4 = new-object Drawing.Point 200, 100 $formGraphics.DrawBezier($mypen, $p1, $p2, $p3, $p4)
The above script will result in the following:
Bringing it All Together
Now that we have covered the basic requirements for displaying graphics using Windows PowerShell and GDI+ it is time to bring it all together in a working example. The following script, when executed, will draw a filled green circle and two red lines:
#Load the GDI+ and WinForms Assemblies [reflection.assembly]::LoadWithPartialName( "System.Windows.Forms") [reflection.assembly]::LoadWithPartialName( "System.Drawing") # Create pen and brush objects $myBrush = new-object Drawing.SolidBrush green $mypen = new-object Drawing.Pen black # Create a Rectangle object for use when drawing rectangle $rect = new-object Drawing.Rectangle 10, 10, 180, 180 # Create a Form $form = New-Object Windows.Forms.Form # Get the form's graphics object $formGraphics = $form.createGraphics() # Define the paint handler $form.add_paint( { $formGraphics.FillEllipse($myBrush, $rect) # draw an ellipse using rectangle object $mypen.color = "red" # Set the pen color $mypen.width = 5 # ste the pen line width $formGraphics.DrawLine($mypen, 10, 10, 190, 190) # draw a line $formGraphics.DrawLine($mypen, 190, 10, 10, 190) # draw a line } ) $form.ShowDialog() # display the dialog
When run, the resulting dialog will appear as follows:
<google>BUY_WPS_BOTTOM</google>