Focusing on Forms and Menus in Visual Basic

In this final article in a four-part series, we take a closer look at what you can do with forms and menus. It is excerpted from chapter four of the Visual Basic 2005 Cookbook, written by Tim Patrick and John Clark Craig (O'Reilly; ISBN: 0596101775). Copyright © 2006 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 10
March 01, 2007
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

4.14 Centering a Form

Problem

You want a form to be in the center of the display when it first appears.

Solution

Set the form’s StartPosition property to CenterScreen.

Discussion

That was easy, but there may be cases where you need to set this property to Manual, but you still want the form to appear centered sometimes. To accomplish this, add the following code to the Loadevent handler for your form:

  Me.Location = New Point((_
     Screen.PrimaryScreen.Bounds.Width - Me.Width) / 2, _
     (Screen.PrimaryScreen.Bounds.Height - Me.Height) / 2)

4.15   Creating and Moving a Borderless Form

Problem

You want to display a form without any of the typical window border elements. Also, you want the user to be able to move the window around by clicking and dragging a PictureBox control.

Solution

Sample code folder: Chapter 04\MoveBorderlessForm

Turning off the border elements is easy:set the form’sFormBorderStyleproperty to None. Then you can manage the drawing of the form elements yourself.

Creating a fake titlebar that moves the form is a little more involved. Create a new Windows Forms application, and add two controls: aButtoncontrol namedActCloseand aPictureBox control namedDragBar. Change the button’sTextproperty toClose. Change the picture box’sBackColorproperty toActiveCaption, one of the system colors. Also, change the form’sFormBorderStyle property toNone. The form should look something like Figure 4-17.


Figure 4-17.  A borderless form with a pretend titlebar  

Now, add the following source code to the form’s code template:

  Const HT_CAPTION As Integer = &H2
  Const WM_NCLBUTTONDOWN As Integer = &HA1

  Private Sub DragBar_MouseDown(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.MouseEventArgs) _
        Handles DragBar.MouseDown
     ' ----- When the user clicks the left mouse button, act
     '       as if the user actually clicked on the form's
     '       title bar.
     If (e.Button = Windows.Forms.MouseButtons.Left) Then
       
' ----- Don't hold on to the mouse locally.
        DragBar.Capture = False

        ' ----- Trick the form into thinking it received a
        '       title click.
        Me.WndProc(Message.Create(Me.Handle, WM_NCLBUTTONDOWN, _
           CType(HT_CAPTION, IntPtr), IntPtr.Zero))
     End If
  End Sub

  Private Sub ActClose_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles ActClose.Click
     Me.Close()
  End Sub

Run the program, and drag the colored picture box control to move the form around the display.

Discussion

All of the activity within a Windows form happens through messages being processed through a Windows procedure, or WndProc. This method has existed since the introduction of Windows. The .NET Framework put a bunch of pretty classes around the messy parts of this messaging system, but it’s still there, and you can interact with it to suit your needs.

Normally, when you left-click on a form window (or a control, which is just a different type of window), aWM_LBUTTONDOWNmessage is passed to the relevant Windows procedure. That message ultimately triggers a call to one of your form’sMouseDownevent handlers.

Your application includes a “message pump” that makes calls to each form’sWndProcprocedure for message processing. But there is nothing to stop you from calling that procedure yourself. In fact, it’s exposed as a form class member.

When theDragBar picture box control receives the mouse down event, it says, “Hey, I’ll just send a fake message to my window’sWndProcroutine so that it thinks the user clicked on the titlebar.” And that’s what the code does. It sends aWM_NCLBUTTONDOWNmessage to the form. The “NCL” part of that code means “Non-Client,” the area that contains the titlebar and borders. The HT_CAPTION flag tells the message that the click occurred in the caption area (the titlebar). This is all that’s needed to trick the form.

4.16 Creating a Fading Form

 

Problem

You want a form to fade out and disappear.

Solution

Sample code folder: Chapter 04\FadingForm

Use the form’sOpacityproperty to slowly fade it out. Create a new Windows Forms application, and add aButtoncontrol namedActCloseto the form. Change the button’sTextproperty toClose. Then add the following source code to the form’s code template:

  Private Sub ActClose_Click(ByVal sender As Object, _
       
ByVal e As System.EventArgs) Handles ActClose.Click
     ' ----- Fade out the form.
     Dim counter As Integer

     For counter = 90 To 10 Step -20
        Me.Opacity = counter / 100
        Me.Refresh()
        Threading.Thread.Sleep(50)
     Next counter

     Me.Close()
  End Sub

Run the program, and click on theClosebutton to see the form fade away.

Discussion

You’ll find that on some systems, the form momentarily blinks to black right when it makes the transition from an opacity of 1.0 to any other opacity value. On such systems, setting the Opacity property to a non-1.0 value during the Loadevent handler still causes a blink, but it does so when the form first opens, not during the cool fadeout.

  Private Sub AboutProgram_Load(ByVal sender As Object, _
       
ByVal e As System.EventArgs) Handles Me.Load
     ' ----- Prepare the form for later fade-out.
     Me.Opacity = 0.99
 
End Sub

4.17 Creating a Nonrectangular Form

Problem

You want to display a form that is nonrectangular; that is, you want some of the form to be invisible.

Solution

Sample code folder: Chapter 04\PartialInvisibility

Use the form’sTransparencyKeyproperty to identify a color that will be invisible. The sample code in this recipe uses fuchsia for its “invisible color,” but you can choose any color that meets your display requirements.

Create a new Windows Forms application. ChangeForm1’sFormBorderStyleproperty toNone, itsStartPositionproperty toCenterScreen, and itsTransparencyKeyproperty toFuchsia. Then add the following source code to the form’s code template:

  Private Sub Form1_Click(ByVal sender As Object, _
       
ByVal e As System.EventArgs) Handles Me.Click
     ' ----- Any click closes the form.
     Me.Close()

  End Sub

  Private Sub Form1_Paint(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.PaintEventArgs) _
        Handles Me.Paint
     ' ----- Draw a nice logo form.
     e.Graphics.Clear(Color.Fuchsia)
     e.Graphics.FillRectangle(Brushes.Gold, 0.0F, _
       
Me.ClientRectangle.Height / 3.0F, _
        CSng(Me.ClientRectangle.Width), _
        Me.ClientRectangle.Height / 3.0F)
     e.Graphics.FillPolygon(Brushes.Gold, New PointF() { _
        New Point(Me.ClientRectangle.Width / 4, 0), _
        New Point
(Me.ClientRectangle.Width / 2, _
        Me.ClientRectangle.Height / 2), _
        New Point(Me.ClientRectangle.Width / 4, _
        Me.ClientRectangle.Height), _
        New Point(0, Me.ClientRectangle.Height / 2)})
    
Dim largerFont = New Font(Me.Font.Name, 20)
    
e.Graphics.DrawString("My Nice Program", _
        largerFont, Brushes.Black, 20, _
        (Me.ClientRectangle.Height / 2) - _
        (largerFont.Height / 2))
  End Sub

When you run the program, it appears similar to the display in Figure 4-18. (We left the development environment behind the form so that you could see the invisibility.)

Figure 4-18.  A Form with transparent portions

Discussion

The initial release of Visual Basic 2005 included a bug that prevented the transparency color from properly appearing as transparent in some cases. Specifically, if your form included an image that contained the transparency color, and the workstation was using more than 24 bits of color for its display, the image appeared as opaque. To get around this problem, you need to set transparency on the image manually before you draw it:

  Private Sub Form1_Paint(ByVal sender As Object,_
        ByVal e As System.Windows.Forms.PaintEventArgs) _
        Handles Me.Paint
     ' ----- This code assumes that the form's
     '       TransparencyKey property is "Fuchsia".
     Dim logoImage As Bitmap = Bitmap.FromFile( _
       
"C:\MyLogo.bmp")
     logoImage.MakeTransparent(Color.Fuchsia)
     e.Graphics.DrawImage(logoImage, 0, 0)
  End Sub

The Microsoft Knowledge Base number for this article is 822495.

See Also

Recipe 9.10 discusses invisibility colors and the TransparencyKey property in more detail.

4.18 Changing Menus at Runtime

Problem

You want to customize the menu structure in your main form at runtime. The structure should be based on settings made available by some user-configurable method.

Solution

Sample code folder: Chapter 04\RuntimeMenus

The menu-specific classes included in the Windows Forms library can be created at either design time or runtime. This recipe’s code adds a basic menu to a form at design time and enhances it at runtime by adding the user’s Internet Explorer “Favorites” to one of the menus.

Create a new Windows Forms application, and add aMenuStripcontrol namedMainMenuto the form. Perform the following actions on this menu:

  1. Add a top-level menu namedMenuFile, using&Filefor itsTextproperty.
  2. Add a top-level menu namedMenuFavorites, usingFa&voritesfor itsTextproperty.
  3. Add a menu item namedMenuExitProgramthat is subordinate toMenuFile, usingE&xitfor itsTextproperty. Set itsShortcutKeysproperty toAlt+F4.
  4. Add a menu item namedMenuNoFavoritesthat is subordinate toMenuFavorites, using(empty)for itsTextproperty. Set itsEnabledproperty toFalse.

Figure 4-19 shows a partial look at this form’s menu structure in design mode.


Figure 4-19.  The initial menus for the runtime menu sample

Next, replace the form’s code template with the following code. I’ve highlighted the lines that do the actual adding of menu items:

  Imports MVB = Microsoft.VisualBasic

  Public Class Form1
    
Private Declare Auto Function GetPrivateProfileString_
        Lib "kernel32" _
        (ByVal AppName As String, _
       
ByVal KeyName As String, _
        ByVal DefaultValue As String, _
        ByVal ReturnedString As System.Text.StringBuilder, _
        ByVal BufferSize As Integer, _
        ByVal FileName As String) As Integer

     Private Sub MenuExitProgram_Click( _
           ByVal sender As System.Object, _
           ByVal e As System.EventArgs) _
           Handles MenuExitProgram.Click
        
' ----- Exit the program.
        Me.Close()
     End Sub

     Private Sub Form1_Load(ByVal sender As Object, _
          
ByVal e As System.EventArgs) Handles Me.Load
        ' ----- Scan through the user's "Favorites" and
        '       add them as menu items.
        Dim favoritesPath As String

        ' ----- Determine the location of the "Favorites"
        '       folder.
        favoritesPath = Environment.GetFolderPath( _ 

        Environment.SpecialFolder.Favorites)
        If (favoritesPath = "") Then Return
        If (My.Computer.FileSystem.DirectoryExists( _
           favoritesPath) = False) Then Return

        ' ----- Call the recursive routine that builds the menu.
        BuildFavorites(MenuFavorites, favoritesPath)

        ' ----- If favorites were added, hide the
        '       "no favorites" item.
        If (MenuFavorites.DropDownItems.Count > 1) Then _ 
         
MenuNoFavorites.Visible = False  
     End Sub

     Private Sub BuildFavorites(ByVal whichMenu As _
          
ToolStripMenuItem, ByVal fromPath As String)
        ' ----- Given a starting directory, add all files
        '       and directories in it to the specified menu.
        '       Recurse for suborindate directories.
        Dim oneEntry As String
        Dim menuEntry As ToolStripMenuItem
        Dim linkPath As String
        Dim displayName As String

        ' ----- Start with any directories.
        For Each oneEntry In My.Computer.FileSystem. _
             
GetDirectories(fromPath)
           ' ----- Create the parent menu, but don't
           '       attach it yet.
          
menuEntry = New ToolStripMenuItem( _ 
         My.Computer.FileSystem.GetName(oneEntry))

           ' ----- Recurse to build the sub-directory branch.
           BuildFavorites(menuEntry, oneEntry)
 

           ' ----- If that folder contained items,
           '       then attach it.
          If (menuEntry.DropDownItems.Count > 0) Then _
           whichMenu.DropDownItems.Add(menuEntry) 
       Next oneEntry 

       ' ---- Next, build the actual file links. Only
       '      look at ".url" files.
       For Each oneEntry In My.Computer.FileSystem. _
            
GetFiles(fromPath, FileIO.SearchOption. _
            
SearchTopLevelOnly, "*.url")
          ' ----- Build a link based on this file. These
          '       files are old-style INI files.
          linkPath = GetINIEntry("InternetShortcut", _
             "URL", oneEntry)
         
If (linkPath <> "") Then
             ' ----- Found the link. Add it to the menu.
             displayName = My.Computer.FileSystem. _
               
GetName(oneEntry)
             displayName = MVB.Left(displayName, _
                displayName.Length - 4)

           menuEntry = New ToolStripMenuItem(displayName)
            menuEntry.Tag = linkPath
           
whichMenu.DropDownItems.Add(menuEntry)

            ' ----- Connect this entry to the event handler.
            AddHandler menuEntry.Click, _
               AddressOf RunFavoritesLink
         End If
      Next oneEntry
   End Sub

   Private Sub RunFavoritesLink( _
         ByVal sender As System.Object, _
         ByVal e As System.EventArgs)
     
' ----- Run the link.
      Dim whichMenu As ToolStripMenuItem

      whichMenu = CType(sender, ToolStripMenuItem)
      Process.Start(whichMenu.Tag)
   End Sub

   Private Function GetINIEntry(ByVal sectionName As String, _
         ByVal keyName As String, _
         ByVal whichFile As String) As String
     
' ----- Extract a value from an INI-style file.
      Dim resultLength As Integer
      Dim targetBuffer As New System.Text.StringBuilder(500)

      resultLength = GetPrivateProfileString(sectionName, _
         keyName, "", targetBuffer, targetBuffer.Capacity, _

         whichFile)
     
Return targetBuffer.ToString()
   
End Function
 
End Class

Run the program, and access its Favorites menu to browse and open the current user’s Internet Explorer favorites.

Discussion

The bulk of this recipe’s code deals with scanning through a directory structure and examining each file and subdirectory. Most of the files in the “Favorites” folder have a .url extension and contain data in an “INI file” format.

Here’s a sample link to a popular search engine:

  [DEFAULT]
  BASEURL=http://www.google.com/
  [InternetShortcut]
  URL=http://www.google.com/

The last “URL=” line provides the link we need to enable favorites support in our program.

The important part of the program is the building of the menu structure. Each menu item attached to the form’s main menuMenuStrip control is a relatedToolStripMenuItemclass instance. These can be attached to the menu at any time through itsDropDownItemscollection. Each menu item in turn has its ownDropDownItemscollection that manages subordinate menu items.

To make each new menu item do something, as you add them, connect them to the previously writtenRunFavoritesLinkmethod:

  AddHandler menuEntry.Click, AddressOf RunFavoritesLink

4.19 Creating Shortcut Menus

Problem

You want to display a custom shortcut menu to users when they right-click on a form or one of its controls.

Solution

Sample code folder: Chapter 04\ShortcutMenus 

Use theContextMenuStrip control to design a shortcut menu (also called a context or pop-up menu) that you can attach to the controls (or form) of your choice.

Create a new Windows Forms application, and add aContextMenuStripcontrol namedMainShortcutMenu to the form. When you select that control, it adds a temporary standard menu to the control that you can use to add new menu items (see Figure 4-20).


Figure 4-20.  Shortcut menus in design mode

Add two menu items to this shortcut menu:

  • A menu item namedMenuHello, usingSay Hellofor itsText property
  • A menu item namedMenuGoodbye, usingSay Goodbyefor itsTextproperty

Select the form itself, and then change itsContextMenuStripproperty toMainShortcutMenu.

Now, add the following source code to the form’s code template:

  Private Sub MenuHello_Click(ByVal sender As System.Object,_
        ByVal e As System.EventArgs) Handles MenuHello.Click
     MsgBox("Hello")
  End Sub

  Private Sub MenuGoodbye_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MenuGoodbye.Click
     MsgBox("Goodbye")
  End Sub

Run the program, and right-click on the form. The shortcut menu will present itself, as shown in Figure 4-21. Clicking on the items puts up a message box saying “Hello” or “Goodbye.”


Figure 4-21.  The shortcut menu in use

Discussion

Each form and control includes a ContextMenuStrip property that you can assign to any ContextMenuStrip control included with your form. You can create as many shortcut menus as needed for your controls.

Some controls, such as theTextBoxcontrol, already include default shortcut menus. If you wish to enhance one of these menus, you will have to design your own menu from scratch and provide your own implementations for menu items previously found in that control’s shortcut menu.

blog comments powered by Disqus
VISUAL BASIC.NET ARTICLES

- Basic Form Properties and Modality in VB.NET
- Multiple Document Interfaces in Visual Basic
- Visual Basic for Beginners
- ASP.NET Image to PDF with VB.Net
- MySQL in ASP.NET: Mono using VB.NET
- AsyncFileUpload File Type and File Size Vali...
- Visual Studio: Adding Functionality and Style
- Clocks and Countdowns
- User-defined Functions using Visual Basic Ap...
- Understanding Object Binding in VBA
- Mastering the Message Box
- Testing a Windows Forms Application
- Using Visual Basic.NET Features to Code a Wi...
- Correcting Code in a Windows Forms Applicati...
- Write Readable Code and Comments for Windows...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 1 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials