Don’t Be Square: Creating Non-Rectangular Windows with .NET

ne problem with creating GUIs with Microsoft Visual Studio.NET is that they all tend to look the same. It takes extra work and innovation to make your user interface stand out from the crowd, but one way to make your application distinctive is to create a non-standard shaped UI such as that used in Windows Media Player 9 (see Figure 1). You may not have realized that?thanks to the .NET framework?creating a non-rectangular UI like this is easier than it has ever been, and is well within the reach of every developer. There’s no longer any need to override Windows subclasses to add your own drawing routines! The framework does it for you. In this article you’ll find out how to create non-rectangular UIs, and build your own retro-style wooden application in the process.

The user interface of Windows Media Player 9 begins with a basic non-rectangular form, and then adds both non-traditional buttons and traditional controls, such as the TreeView on the left, and the ListBox containing the songs on the right. These are traditional, rectangular controls, placed on the form, and colored to blend in.

In this article, and in the downloadable code, you will create a basic HTML viewer similar to Windows Media Player (though not nearly as pretty, blame my artistic skills), with a non rectangular form that contains both traditional controls and some cool circular buttons.

?
Figure 1. Windows Media Player 9: Note the non-traditional (and non-rectangular) UI, which contains both standard (TreeView, ListBox) and non-standard (circular and oval buttons) controls.

You may wonder: How do you drag the form around the screen, if you can’t see its title bar? Well, you’ll learn how to do that too.

Getting Started

?
Figure 2. Mask Image: This wooden mask image defines the outline of the non-rectangular sample form.

To create a non-rectangular form, you need to create a mask that defines the outline shape of the form. You can use any image editing application to create the mask. I used the GIMP (GNU Image Manipulation Program), which is a superb open source image processing application. Figure 2 shows the mask used in the sample application. You can use this one, or create your own.

It’s important to realize that the mask picture itself is rectangular in shape. The mask image for this form, for example, is a rectangle with a white background; the parts of the background that are white now will become transparent later, when Windows draws the form, giving the impression that the form based on this picture is non rectangular.

?
Figure 3. Avoid Transparent Mask Images: The ugly transparency problems in the figure are caused by trying to use this compressed JPEG image as the background mask for the form.

Avoid using compressed images, such as JPEGs for the mask, because the compression leaves small artifacts in the background, which?when you try to make it transparent?tend to show up in a very ugly way. Figure 3 shows an example; you can see the jagged corners and edges?caused by the compression, because those pixels are no longer ‘pure’ white, which is the color that the application was programmed to treat as transparent. You’ll see more on that in the next section.

Masking the Form
After completing the mask image, you need to create your windows application. You’ll “skin” the application’s main window with the mask.

Launch Visual Studio.NET and create a new Windows Application project. Visual Studio creates a standard, simple, one-form, application with a rectangular form called Form1.

You’re going to jazz that form up a bit. First, you have to remove the borders of the form, so set the formBorderStyle property to None. That will get rid of the form outline and the sizing handles. In this case you don’t want your users to resize your form.

Next, you set the BackgroundImage property to the path to your mask file. You may need to resize your form to fit the mask. Note that setting the BackgroundImage property makes your image act as wallpaper on the form?the background image repeats as a pattern if the form is wider or taller than the image (see Figure 4).

?
Figure 4. Image Wallpaper: Your mask image acts as wallpaper on the form, repeating if the image and form sizes don’t match.

Resize your form so that you see a single instance of your mask, eliminating any repeating patterns.

Next, you need to tell the form that you want the white part to be transparent, so that you can see through it when running the application. You do this by setting the TransparencyKey property to white.

If you run your application now, you’ll see a beautiful, non rectangular wooden-looking form on the screen. But wait a minute! Because there’s no Windows title bar at the top, you can’t click ‘x’ to close it, and you can’t move it around. It’s just stuck there. Fortunately, you can close it with ALT-F4. In the next section you’ll see how to add dragging functionality as well as self-closing capability.

Adding Event Handlers
With Windows Forms, you get a lot of goodies for free, such as form closing, resizing, and dragging handling; but you lose those when using a borderless form (frmBorderstyle=None), so you have to implement your own.

To Add a Close handler to the form:

  • Drag a button control onto the form. Call it btnClose, and assign its Text the string “X”.
  • Double click this button to add a click event handler. In Visual Studio.NET, double clicking a control in design mode adds an event handler for the control’s default event. If you want to add any other events, you use the events dialog. You’ll see how to do this a little later.
  • You should now be in the code editor for the btn_Close() event. Change the event so that it looks like the following:
   private void btnClose_Click(object sender, System.EventArgs e)   {       this.Close();   }

Your form will now close when a user clicks the ‘X’ button. You can put this button anywhere on the form; you’re not limited to the top right hand corner location that you get by default with a traditional form. You could replace the button with a custom Close icon that would work the same way to close the form. If you refer back to Figure 1, you’ll see that that’s how Windows Media Player does it, too.

To Add a Drag Handler to the form:

  • First, declare a variable of type Point to track the offset of the mouse as you drag it around to move the form. You’ll see how this is used in a moment, but for now, place the following code in the declarations section of your form. You can place it just below the declaration of the button at the top of the form declaration.
   private Point ptOffset;
  • Next, add a PictureBox control that will intercept the mouse events for mousedown and mousemove so that you can perform the dragging operation. Place the PictureBox over the location that you want to have ‘sensitive’ to dragging. Many shapeless applications use a specific part of the form (often called a “thumb”) for dragging the form around. Assign the BackColor property PictureBox a color other than white (so it won’t be transparent). Your form should now look something like Figure 5, where for clarity I colored it dark blue.
?
Figure 5. Finished GUI sample: The dark blue area acts as a drag point, called a “thumb,” so users can move the form even though it doesn’t have a visible title bar.
  • Add MouseDown and MouseMove event handlers to the form. In C#, you do this by clicking on the events icon on the property editor. This icon looks like a bold of lightning. To add the event handler, find the event name and double click it. This adds the event declaration and handler to your code. Note that if you are doing this in VB.NET, the designer is a little different?you select the PictureBox control from the dropdown list at the top of the code window, and then select the appropriate events from the dropdown list at the top right of the code window.
  • Edit the MouseDown event handler code so it looks like the following:
      private void pictureBox1_MouseDown(       object sender,       System.Windows.Forms.MouseEventArgs e)   {     ptOffset = new Point(-e.X - pictureBox1.Left,        -e.Y - pictureBox1.Top);   }
  • The preceding handler keeps track of the location where the user first depresses the mouse button. That becomes your point of reference when dragging. Note that ptOffset is set relative to the position of the picture box. The MouseEventArgs argument provides X and Y properties that give you the position of the mouse relative to the top left corner of the form?so you translate the mouse location by the PictureBox coordinates to get a point relative to the picture box.
  • Next you need to edit the MouseMove event handler so that it moves the form around when you drag the mouse, as shown below.
   private void pictureBox1_MouseMove(   object sender, System.Windows.Forms.MouseEventArgs e)   {       if( e.Button==MouseButtons.Left)       {         Point mousePos = Control.MousePosition;         mousePos.Offset(ptOffset.X, ptOffset.Y);         this.Location = mousePos;       }   }
  • The code first checks to see if the left mouse button is pressed, and if so, calculates the current position of the mouse relative to the one when the mouse was first pushed down (stored in ptOffset) using the Point class’s Offset method. Doing that determines where the new location of the form should be. Finally, the code relocates the form to that position.
  • You can now drag the form around, by clicking anywhere in the PictureBox area (the drag “hotpoint”) and then dragging. The PictureBox may look ugly now, but?it’s a PictureBox; therefore, you can change the background picture to blend in with the background of the form. For example, you could use the same wooden background, but add some thumb lines and/or change the mouse cursor to indicate that it’s a hotspot. Experiment, and have fun!

You can continue to add controls to the form, and color the controls so that they match the skin of the form appropriately. The download demonstrates some of this for you.

In this article you saw how to play with some of the features of .NET that support advanced UI features such as transparency. This is just the tip of the iceberg of some of the nice things that are now available in Visual Studio.NET and the .NET framework. You are no longer bound to boring grey rectangles in your UI if you don’t want to be and if you don’t want to invest thousands of man hours in overriding them.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: