Changing the Shapes of Your Forms
Learn how to change your form's shapes!
AI
AI Summary: This codebase represents a historical implementation of the logic described in the metadata. Our preservation engine analyzes the structure to provide context for modern developers.
Source Code
<font size="5" face="Geneva, Arial, Helvetica, sans-serif">Changing
the Shapes of Your Forms</font></blockquote>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">Are you tired
of your square or rectangle forms? Would you like to create a splash screen
that actually looks like a splash? Would you like to create an About Us
screen in the shape of a circle or a star? Well, this is the tutorial
for you. In this tutorial, you will learn how to use the Win32 API to
change the shapes of your forms. </font></p>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">Only one
pre-requisite is required for this tutorial. You must know the 2D cartesian
coordinate system. To plot a shape like a star or a triangle, you must
know the coordinates of the points of the star or the three vertexes of
the triangle. Other than the knowledge of cartesian plotting, you will
need nothing more than a VB compiler and some time.</font></p>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">Let's get
started, shall we? To begin, create a new Standard EXE project and add
a Module (right-click on the Project Explorer, select "New"
and select "Module.") Save your project right off the bat. You
can name the form, project, and module files anything you want. </font></p>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">Double-click
on the module in the Project Explorer window. Add in the following code.
We shall explain what it does in more detail a little later in the tutorial:</font></p>
<blockquote>
<p><font size="2" face="Courier New, Courier, mono">Public Declare Function
CreatePolygonRgn Lib "gdi32" (lpPoint As POINTAPI, ByVal nCount
As Long, ByVal_ nPolyFillMode As Long) As Long</font></p>
<p><font size="2" face="Courier New, Courier, mono">Public Declare Function
SetWindowRgn Lib "user32" _<br>
(ByVal hWnd As Long, ByVal hRgn As Long, _<br>
ByVal bRedraw As Boolean) As Long</font></p>
<p><font size="2" face="Courier New, Courier, mono">Public Type POINTAPI<br>
x As Long<br>
y As Long<br>
End Type</font></p>
</blockquote>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">Now let's
take a closer look at the functions. The first API function, CreatePolygonRgn()
creates a <strong>region</strong> or a set of points that describes a
separate entity. SetWindowRgn() sets your form to abide by the shape and
characteristics of a certain region. In other words, you would use CreatePolygonRgn()
to create a star shape and then use SetWindowRgn() to make your form's
shape a star. The declaration of the type POINTAPI simply allows you to
declare a variable that can hold the set of points that will define the
region created with the CreatePolygonRgn() function.</font></p>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">Note, though,
that creating a perfect circle using the CreatePolygonRgn() function is
completely impossible. Therefore, to create a circle, we declare a second
region-creating function called CreateEllipticRgn(). The code for a circle-shaped
form will be shown later in the tutorial.</font></p>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">Now that
you have your functions, it is time to create a star out of your form.
In the Options Explicit section of your form, we must create a variable
of type POINTAPI. Note that a POINTAPI variable can hold two values: x
and y. To create a star, therefore, we must make an array with type POINTAPI
to hold the x and y coordinates for multiple points. To do this, we declare
the variable p (for points) in the Options Explicit section of form1:</font></p>
<blockquote>
<p><font size="2" face="Courier New, Courier, mono">Dim p(20) As POINTAPI</font></p>
</blockquote>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">A star only
requires 14 unique points, but we shall declare 20 in case you want to
mess around with the points and turn your form into a deformed star or
a triangle, etc. Now that we have a variable, it is time to declare the
points (I.E. give p(20) values.) It is difficult to explain in text why
the following points are why they are, but if you were to plot them on
a 2D cartesian graph, they would form a star. When you create your own
shapes, you must first lay out all of your points. The following code
must be put in the _Load() event of Form1.</font></p>
<blockquote>
<p> <font size="2" face="Courier New, Courier, mono">p(1).x = 100<br>
p(1).y = 0<br>
<br>
p(2).x = 120<br>
p(2).y = 40<br>
<br>
p(3).x = 180<br>
p(3).y = 40<br>
<br>
p(4).x = 140<br>
p(4).y = 80<br>
<br>
p(5).x = 180<br>
p(5).y = 120<br>
<br>
p(6).x = 120<br>
p(6).y = 120<br>
<br>
p(7).x = 100<br>
p(7).y = 160<br>
<br>
p(8).x = 80<br>
p(8).y = 120<br>
<br>
p(9).x = 20<br>
p(9).y = 120<br>
<br>
p(10).x = 60<br>
p(10).y = 80<br>
<br>
p(11).x = 20<br>
p(11).y = 40<br>
<br>
p(12).x = 80<br>
p(12).y = 40<br>
<br>
p(13).x = 100<br>
p(13).y = 0</font></p>
</blockquote>
<p><font size="2" face="Arial, Helvetica, sans-serif">Now, create a command
button, named cmdChangeShape, and in its _Click() event, put the following
code:</font></p>
<blockquote>
<p><font size="2" face="Courier New, Courier, mono">SetWindowRgn hWnd,
CreatePolygonRgn(p(1), 13, 1), True</font></p>
</blockquote>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">The SetWindowRgn()
function is used to set the window's shape to the region created with
the function CreatePolygonRgn(). Let's look at the two function's arguments.
SetWindowRgn takes the handle of the window whose shape it will change,
i.e. form1. hWnd, therefore, represents form1's handle as a long value.
After the window handle, the function takes the long value of the region
by which it shall change the window's shape. This value is determined
in this example by the function CreatePolygonRgn(). After the region,
it takes a boolean (true, false,) value of fwhether it should refresh
the window. If this is false, then the window shall do nothing until it
is unloaded and reloaded. When set to true, the window will instantaneously
change shape. </font></p>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">The CreatePolygonRgn()
function takes first the POINTAPI variable that holds the points for the
region. In this example, it is p(). Since p is an array, we must tell
it which array entry to start with, hence the p(1). After the POINTAPI
variable, it takes the number of entries of the array to consider. Since
we only give values to entries less than p(13), we put a "13"
for this argument. Finally, the CreatePolygonRgn function takes a fillmode.
The fillmode tells the SetWindowRgn() function what to put in the shaped
form once the shaped form is shaped. 1 tells the function to add the contents
of the window before it was shaped. It is recommended that you use either
1 or 2 as a default for this argument.</font></p>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">Now, run
the program. Click on the command button and watch your form turn into
a star.</font></p>
<p> </p>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">As promised
above, we shall take a look at the CreateEllipticRgn() function. The declaration
syntax is below. Put this in the module along with the CreatePolygonRgn()
and the SetWindowrgn():</font></p>
<blockquote>
<p><font size="2" face="Courier New, Courier, mono">Declare Function CreateEllipticRgn
lib "gdi32.dll" (ByVal X1 as long, ByVal Y1 as Long, _</font></p>
<p><font size="2" face="Courier New, Courier, mono">ByVal X2 as Long,
ByVal Y2 as Long)</font></p>
</blockquote>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">X1 and Y1
are the coordinates for the upper-left hand corner of the square that
contains the circle. X2 and Y2 are the coordinates for the lower-right
hand corner of the square that contains the circle. To create a circle,
simply replace the CreatePolygonRgn(p(1), 13, 1) in the SetWindowRgn()
function to: CreateEllipticRgn(-1, 1, 1, -1) With this change, the line
in cmdChangeShape_Click() event would be:</font></p>
<blockquote>
<p><font size="2" face="Courier New, Courier, mono">SetWindowRgn hWnd,
CreateEllipticRgn(-1, 1, 1, -1), True</font></p>
</blockquote>
<p><strong><font size="2" face="Verdana, Arial, Helvetica, sans-serif">WHERE
TO GO FROM HERE<br>
</font></strong></p>
<p><font size="2" face="Verdana, Arial, Helvetica, sans-serif">Now, all
you can do is simply try different sets of points for CreatePolygonRgn()
and see what shapes you can make!</font>
Original Comments (3)
Recovered from Wayback Machine