Xtreme Visual Basic Talk

Xtreme Visual Basic Talk (http://www.xtremevbtalk.com/)
-   Tutors' Corner (http://www.xtremevbtalk.com/tutors-corner/)
-   -   GDI+ - What's That? (http://www.xtremevbtalk.com/tutors-corner/147590-gdi-whats.html)

MikeJ 02-24-2004 03:27 PM

GDI+ - What's That?
 
1 Attachment(s)
GDI/GDI+ in Visual Basic .Net - Part 1

Introduction
Well, if you are like me, you’ve wondered what the heck is GDI and what does it have to do with me? Personally, I’ve spent more than my fair share of time staring at MSDN going huh? Well, hopefully this tutorial will explain the basics of GDI, and how to use it in your VB.Net applications.

Some basic assumptions before starting this tutorial:
  • Basic knowledge of VB.Net syntax
  • Some knowledge of graphics in VB6 (as in enough to know what a line/shape control was) because I will be making some comparisons with them.
  • An open mind to .Net concepts

Well, I guess the first question is What Is GDI+? GDI+ stands for Graphic Device Interface. This is fancy-talk for a way to draw directly to forms or windows. (For the sake of this tutorial, we will be working with forms.)

Now how is GDI+ in .Net different than GDI in VB6? In .Net, it is much, much easier to work with GDI+. In VB6, GDI was a pain. Just looking at GDI tutorials can tell you this. I personally shied away from GDI in VB6, just out of fear. But with the advent of .Net, we programmers have a much easier way to deal with GDI, in the form of GDI+. I also should add that GDI+ is only available natively in .Net, as it is the System.Drawing.dll, but if you haven’t made the upgrade, you can use OnErr0r’s class wrappers, which you can find here and here. Also, you can also use GDI in .Net as well as GDI+. (But why would you want to? ;)).

The Namespaces Involved
Well, you can’t use GDI+ without declaring the namespaces. So, at the very top of the code window, you need to include the namespaces that you will need. They are:
  • System.Drawing – This contains the basic GDI classes. This part of the tutorial will focus on this.
  • System.Drawing.Design – This class extends drawing functionality and adds classes for tailoring toolboxes/editors.
  • System.Drawing.Drawing2D - This namespace consists of classes and enumerations for advanced 2D and vector graphics functionality.
  • System.Drawing.Imaging - This namespace provides advanced GDI+ imaging functionality. This is where metafiles live, and encoding for practically any file types.
  • System.Drawing.Printing – As the name of the namespace says, this deals with printing.
  • System.Drawing.Text – Since most of the text functionality is contained System.Drawing, this one stumped me. As far as I can figure out, this is mostly for collection of fonts.

Making the Graphics Object
Now, we’ve decided which namespaces we need, but now what? We need to get us a graphics object for us to paint on. For this, we will use the OnPaint event.
Code:
Imports System.Drawing Public Class Form1 Inherits System.Windows.Forms.Form 'The windows generated form code region is here Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) 'This is the declare of the Graphics object Dim g As Graphics = e.Graphics End Sub End Class
Now we have our graphics object! We can do any thing we want such as use fonts, make pens/lines/paths/polygons, draw images and ellipses and so on! Here are some of the more common methods that we can use (don’t worry, most are really apparent):
Code:

DrawArc
DrawCurve
DrawEllipse
DrawImage
DrawLine
DrawPath
DrawPie
DrawPolygon
DrawRectangle
DrawString
FillEllipse
FillPath
FillPie
FillPolygon
FillRectangle
FillRectangles
FillRegion

Pens, DrawLine, Rectangles, Brushes, DrawRectangle, and FillRectangle
What is a Pen? A pen draws a line of specified width and style. I declare them as separate variables, but they can also be declared inside a line of code.
Code:
Dim pPen As Pen = New Pen(Color.Black, 4)
The first parameter is the color, you can change it by typing Color. The intellisense will pick up, and you will see a combo-box listing all the colors that you have available. The other thing you will probably use here is Color.FromARGB. This function will let you take an RGB value and use it as your color. The second parameter is the width of the pen. Simple enough, isn’t it?

The DrawLine method is as straightforward as it appears, but is really easy to use. Since .Net doesn’t include a line control as VB6 did, we have to draw our lines the same way. MSDN even recommends that we use a Label control to achieve the same effect (full article). However, this will only work with horizontal and vertical lines, and really isn’t a good method to start with. Well, here’s how to use it (I’m using the basic code from above, but only will include the OnPaint event:
Code:
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) 'This is the declare of the Graphics object Dim g As Graphics = e.Graphics 'Declare the pen Dim pPen As Pen = New Pen(Color.Maroon, 4) 'Let's draw us a line g.DrawLine(pPen, 10, 10, 110, 110) End Sub
The parameters here are again pretty explanatory. The first one is referencing our pen that we declared, while the last four are just the positions of the points of the line. They are X1, X2, Y1, Y2 respectively.

What is a Rectangle? In VB6 we had RECT, and it’s not that different in .Net. A Rectangle can be used for almost all of the System.Drawing methods, and I’ll just use Draw/Fill Rectangle in this tutorial. To declare a Rectangle:
Code:
'Declare the Rectangle, the parameters are X, Y, Width, Height Dim rRect As Rectangle = New Rectangle(150, 150, 100, 100)
Notice that the declare for it is similar to the declare for a pen; we have to declare it, then use the New sub to make it an object that we can use. Now that we have our rectangle what do we do? We can use the DrawRectangle to draw the outline of the rectangle.
Code:
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) 'Declare the Rectangle Dim rRect As Rectangle = New Rectangle(150, 150, 100, 100) 'Let's draw us a rectangle! g.DrawRectangle(pPen, rRect) End Sub
We now have the outline of the rectangle. Our declare includes the pen (which is the color maroon), and the rectangle that we have just declared. You don’t need to declare the rectangle like this, but in my opinion, it just makes it easier to read.

What happens though, if we want to draw a filled rectangle? We can use the FillRectangle.
Code:
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) 'Let's draw us a rectangle! g.DrawRectangle(pPen, rRect) 'Fill it! g.FillRectangle(New SolidBrush(Color.Blue), rRect) End Sub
Woah! What’s this SolidBrush? If you read the parameter information provided by Intellisense/MSDN, you will see that we need a Brush. Well, what are brushes? Brushes are what we use to make fills. The ones we can get just from System.Drawing are SolidBrush and TextureBrush. The SolidBrush does what it says, it makes a solid brush of the color specified. The TextureBrush, however, uses a bitmap. Well now, it’s almost covered up our rectangle’s outline! What should we do to fix it? Just flip them, like so:
Code:
'Fill it! g.FillRectangle(New SolidBrush(Color.Blue), rRect) 'Let's draw us a rectangle! g.DrawRectangle(pPen, rRect)
MSDN references for this section:
DrawString and the Font Class
Well, we can draw a string, but what do we do without fonts? This is where the Font Class comes into place. So:
Code:
'Declare the font Dim fFont As Font = New Font("Verdana", 10, FontStyle.Bold)
We now have a font called ‘fFont’ that is Verdana, size 10pt, and bold. We can use the DrawString method now, to make a nice little caption for our form:
Code:
'Draw some text g.DrawString("Hello World! I'm GDI!", fFont, New SolidBrush(Color.Orange), 30, 10)
MSDN references for this section:

MikeJ 02-24-2004 03:29 PM

An Introduction to GDI+ in .Net, Part 2
 
1 Attachment(s)
GDI+ in Visual Basic .Net - Part 2

Final Recap from Part 1
Here is the final product from Part 1:
Code:
Imports System.Drawing Public Class Form1 Inherits System.Windows.Forms.Form 'The Windows-Designer code region would be here Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) 'This is the declare of the Graphics object Dim g As Graphics = e.Graphics 'Declare the pen Dim pPen As Pen = New Pen(Color.Maroon, 4) 'Let's draw us a line g.DrawLine(pPen, 10, 10, 110, 110) 'Declare the Rectangle Dim rRect As Rectangle = New Rectangle(150, 150, 100, 100) 'Fill it! g.FillRectangle(New SolidBrush(Color.Blue), rRect) 'Let's draw us a rectangle! g.DrawRectangle(pPen, rRect) 'Dim the font Dim fFont As Font = New Font("Verdana", 10, FontStyle.Bold) 'Draw some text g.DrawString("Hello World! I'm GDI!", fFont, New SolidBrush(Color.Orange), 30, 10) End Sub End Class

The Invalidate() Method and Its Practical Application
What is Invalidate()? Invalidate() will call the OnPaint event of the form again. This way, you can make an update on anything you have draw. Consider it as a way to redraw the form. Now what could one practical application of this be? How about a clock that is directly drawn onto the form? We can accomplish this with a timer created from System.Threading, and use the Invalidate() method every second.

Here’s what that would look like:
Code:
Imports System.Drawing Imports System.Threading Public Class Form1 Inherits System.Windows.Forms.Form Dim ThreadedTimer As System.Threading.Timer 'Windows designer code would be here #Region " Timer Code " 'This starts the timer Private Sub EnableTimer(ByVal iInterval As Integer) 'Declare the callback Dim tCallBack As New Threading.TimerCallback(AddressOf TimerTick) 'Create the timer ThreadedTimer = New System.Threading.Timer(tCallBack, Nothing, 0, iInterval) End Sub 'This will get rid of the timer Private Sub DisableTimer() 'Dispose of the timer and set the object to nothing ThreadedTimer.Dispose() ThreadedTimer = Nothing End Sub 'The timer callback sub Private Sub TimerTick(ByVal State As Object) 'This will cause us to redraw the form Me.Invalidate() End Sub Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load 'Enable the timer EnableTimer(1000) End Sub Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing 'Disable the timer DisableTimer() End Sub #End Region Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) 'This is the declare of the Graphics object Dim g As Graphics = e.Graphics 'Declare the font Dim fFont As Font = New Font("Verdana", 10, FontStyle.Bold) 'Draw the text to the form g.DrawString(Now.Now, fFont, New SolidBrush(Color.DarkOrange), 10, 10) End Sub End Class
All this does is create a timer and a callback. In the form load, I set the interval to 1000 milliseconds, so our timer will tick once each second. And, when it will Tick, we Invalidate() the form. If you run this code, you will see that it clears the form, and draws the new time on it. This lets us make a clock without any controls!

This seems like such a simple method, but can really be helpful whenever we need to make our form redraw itself. If you have any questions regarding this tutorial, or any technical issues arise, just contact me through the forum’s PM system, or if I happen to be online (MSN) then just feel free to talk to me there.

MikeJ 03-17-2004 09:50 PM

GDI+ in .Net - Part 3: Bitmaps and TextureBrushes
 
1 Attachment(s)
GDI+ in .Net - Part 3: Bitmaps and TextureBrushes

What are these pesky bitmaps? MSDN says it "encapsulates a GDI+ bitmap, which consists of the pixel data for a graphics image and its attributes." Now, if you are like me, you might be thinking, huh? Well, basically this means that you can store pixel data onto it. (And, by association, you could call a Bitmap a raster image.)
Now, how do we make a bitmap? It is rather simple, it's like any other variable:

Code:

Dim bBackground As Bitmap = New Bitmap(Application.StartupPath & "\background.bmp")
Woah! What did we just do? We created a new bitmap (called bBackground) and set its content from the file background.bmp which can be found in the startup directory for our application. Now that we have our background Bitmap, what can we do with it? We can use the TextureBrush to apply a texture to our form!

Before we do that though, we will need to create a TextureBrush. Remember from Part 1 that SolidBrushes will let you create a brush that is a solid color. On the other hand, TextureBrushes let you create a brush that uses a Bitmap or an Image to fill something created by the graphics object. In the following example, I'll use the bBackground bitmap that we have already created to create a TextureBrush that contains background.bmp.

Code:

Dim bBGBrush As TextureBrush = New TextureBrush(bBackground)
Now we have our TextureBrush that is made from background.bmp, we can create a background texture for our form.

[ MSDN article on Texture Brushes ]



Creating a Texturized Form
In order to create a texturized form, we will need a rectangle that is the entire size of the form.
Code:

Dim bgRECT As Rectangle = New Rectangle(0, 0, Me.Width, Me.Height)
As you remember from Part 1, this creates a rectangle that will fill the whole form. Now, we can use the FillRectangle (see Part 1) method to fill the form.
Code:

g.FillRectangle(bBGBrush, bgRECT)
Here is the complete project:
Code:

Imports System.Drawing

Public Class Form1
    Inherits System.Windows.Forms.Form

    'Windows Form Designer generated code

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        'Declare the graphics object
        Dim g As Graphics = e.Graphics

        'Declare the background object
        Dim bBackground As Bitmap = New Bitmap(Application.StartupPath & "\background.bmp")

        'Declare the brush
        Dim bBGBrush As TextureBrush = New TextureBrush(bBackground)

        'Declare the rectangle
        Dim bgRECT As Rectangle = New Rectangle(0, 0, Me.Width, Me.Height)

        'Fill bgRECT
        g.FillRectangle(bBGBrush, bgRECT)
    End Sub
End Class

This seems really simple, but can produce stunning effects when you have a good background texture and apply it to the form using this method. Also, keep watching, as the next addition to this ongoing series will be on the Gradient Brushes.

P.S.
I've included in the ZIP attachment a sample background.bmp.


All times are GMT -6. The time now is 12:31 PM.

Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Search Engine Optimisation provided by DragonByte SEO v2.0.15 (Lite) - vBulletin Mods & Addons Copyright © 2017 DragonByte Technologies Ltd.
All site content is protected by the Digital Millenium Act of 1998. Copyright©2001-2011 MAS Media Inc. and Extreme Visual Basic Forum. All rights reserved.
You may not copy or reproduce any portion of this site without written consent.