Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Visual Basic 2005 (2006)

.pdf
Скачиваний:
219
Добавлен:
17.08.2013
Размер:
14.97 Mб
Скачать

Chapter 11

2.When the Designer for Form1 appears, change the WindowState property to Minimized and change the ShowInTaskbar property to False. This will, effectively, prevent the form from being displayed.

3.Using the Toolbox, drag a NotifyIcon control onto the form. Set the Name property of the new control to icnNotify and set the Text property to Right-click me to view Favorites.

4.Next, open the Code Editor for Form1. In the Class Name combo box at the top of the Code Editor, select (Form1 Events), and in the Method Name combo box select VisibleChanged. Add this highlighted code to the event handler:

Private Sub Form1_VisibleChanged(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles Me.VisibleChanged

‘If the user can see us, hide us

If Me.Visible = True Then Me.Visible = False

End Sub

5.You now need to design a new icon. If you don’t do this, the icon won’t be displayed on the task bar and your application won’t do anything. Using the Solution Explorer, right-click the Favorites Tray project and select Add New Item. Scroll down the Templates list and select Icon File, as shown in Figure 11-8. Enter the filename as Tray.ico and click Add.

Figure 11-8

6.This displays Visual Studio 2005’s Image Editor. You can use this to design new icons, new cursors, and new bitmap images for use in your applications. It’s fairly intuitive to use, so I won’t go through how you actually draw in much detail. In the toolbar you’ll find a list of tools that you can use to design the icon, as shown in Figure 11-9.

Figure 11-9

366

Advanced Object-Oriented Techniques

7.From the menu, select Image Show Colors Window to bring up the palette of colors shown in Figure 11-10, if they are not already displayed.

Figure 11-10

8.Before you start painting, you’ll need to change the icon type. By default, Visual Studio 2005 will create a 32_32 pixel icon, which is too large to fit on the system tray. From the menu, select Image New Image Type. Then in the New Icon Image Type dialog box, select 16x16, 256 colors and click OK.

9.This creates a new subicon within the image file, but you need to delete the main 32x32 icon, otherwise things will get confusing. From the menu again, select Image Current Icon Image Types 32x32, 16 colors. Then, immediately select Image Delete Image Type from the menu. Repeat this process for the 16x16, 16 color image. When done, you should be left with only the 16x16, 256 color image.

10.If you’re feeling creative, you can design your own icon for this application. On the other hand, you can do what we’ve done, which is to use a screen capture utility to take the favorites icon from Internet Explorer. Our preferred utility is SnagIt (www.techsmith.com/), but a number of graphics programs offer this functionality.

11.Save the icon by selecting File Save Tray.ico from the menu.

12.Go back to the Form Designer and select the icnNotify control at the bottom of the IDE. Use the Icon property in the properties list to open the icon you just created in the NotifyIcon control.

13.Right-click the Favorites Tray project in the Solution Explorer and select Set As Startup Project. Now try running the project. You should discover that the tray icon is added to your system tray as shown in Figure 11-11, but no form window will appear. If you hover your mouse over the icon, you’ll see the message that you set in the Text property of the Notify Icon control.

Figure 11-11

14.Also, you’ll notice that there appears to be no way to stop the program! Flip back to Visual Studio and select Debug Stop Debugging from the menu.

15.When you do this, although the program will stop, the icon will remain in the tray. To get rid of it, hover the mouse over it and it should disappear.

Windows redraws the icons in the system tray only when necessary (for example, when the mouse is passed over an icon).

367

Chapter 11

How It Works

Setting a form to appear minimized (WindowState = Minimized) and telling it not to appear in the taskbar (ShowInTaskbar = False) has the effect of creating a window that’s hidden. You need a form to support the tray icon, but you don’t need the form for any other reason. However, this is only half the battle, because the form could appear in the Alt+ Tab application switching list, unless you add the following code, which you already did:

Private Sub Form1_VisibleChanged(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles Me.VisibleChanged

‘If the user can see us, hide us

If Me.Visible = True Then Me.Visible = False End Sub

This event handler has a brute force approach that says, “If the user can see me, hide me.”

Displaying Favorites

In the next Try It Out, let’s look at how to display the favorites. The first thing you need to do is include the classes built in Favorites Viewer in this Favorites Tray solution. You can then use the Favorites object to get a list of favorites back and build a menu.

Try It Out

Displaying Favorites

1.To display favorites, you need to get hold of the classes defined in the Favorites Viewer project. To do this you need to add the Favorites, WebFavorite, and WebFavoriteCollection classes to this solution.

Using the Solution Explorer, right-click the Favorites Tray project and select Add Existing Item. Click the Browse button and find the Favorites class. This will be in the Favorites Viewer project folder. After clicking Add the class appears in the Solution Explorer for this project. You can select multiple files at once by holding down the Ctrl key.

2.Repeat this for the WebFavorite and WebFavoriteCollection classes.

3.Now, create a new class in Favorites Tray by clicking the project once more and selecting Add Class. Call the new class WebFavoriteMenuItem.vb and then click the Add button to add this class to the project.

4.Set the new class to inherit from System.Windows.Forms.MenuItem by adding this code:

Public Class WebFavoriteMenuItem

Inherits MenuItem

5.Add this member and method to the class:

‘Public member

Public Favorite As WebFavorite

‘Constructor

Public Sub New(ByVal newFavorite As WebFavorite) ‘Set the property

Favorite = newFavorite

368

Advanced Object-Oriented Techniques

‘Update the text Text = Favorite.Name

End Sub

6.Unlike ListViewItem, MenuItem objects can react to themselves being clicked by overloading the Click method. In the Class Name combo box at the top of the Code Editor, select (WebFavoriteMenuItem Events) and then select the Click event in the Method Name combo box. Add the following highlighted code to the Click event handler:

Private Sub WebFavoriteMenuItem_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles Me.Click

‘Open the favorite

If Not Favorite Is Nothing Then

Process.Start(Favorite.Url)

End If

End Sub

7.You need to do a similar trick to add an Exit option to your pop-up menu. Using the Solution Explorer create a new class called ExitMenuItem.vb in the Favorites Tray project. Add the following highlighted code to this class:

Public Class ExitMenuItem

Inherits MenuItem

‘Constructor Public Sub New()

Text = “Exit” End Sub

Private Sub ExitMenuItem_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles Me.Click

Application.Exit()

End Sub

End Class

8.Finally, you’re in a position where you can load the favorites and create a menu for use with the tray icon. Add these members to Form1:

Public Class Form1

‘Public member

Public Favorites As New Favorites()

‘Private member

Private _loadCalled As Boolean = False

9.In the Class Name combo select (Form1 Events) and, in the Method Name combo box, select the Load event. Now add the following highlighted code to this event handler:

Private Sub Form1_Load(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles Me.Load

369

Chapter 11

‘Load the favorites Favorites.ScanFavorites()

‘Create a new context menu

Dim objMenu As New ContextMenu()

‘Process each favorite

For Each objWebFavorite As WebFavorite In Favorites.FavoritesCollection ‘Create a menu item

Dim objItem As New WebFavoriteMenuItem(objWebFavorite) ‘Add it to the menu

objMenu.MenuItems.Add(objItem)

Next

‘Add a separator menu item objMenu.MenuItems.Add(“-”)

‘Now add the Exit menu item objMenu.MenuItems.Add(New ExitMenuItem())

‘Finally, tell the tray icon to use this menu icnNotify.ContextMenu = objMenu

‘Set the load flag and hide ourselves _loadCalled = True

Me.Hide() End Sub

10.Modify the Form1_VisibleChanged procedure as follows:

Private Sub Form1_VisibleChanged(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles Me.VisibleChanged

‘Don’t set the Visible property until the Load event has ‘been processed

If _loadCalled = False Then Return

End If

‘If the user can see us, hide us

If Me.Visible = True Then Me.Visible = False End Sub

11.Run the project, and the icon will appear on the system tray. Right-click the icon, and you’ll see a list of favorites as shown in Figure 11-12. Clicking one will open Internet Explorer, while clicking Exit will close the application.

How It Works

One thing to note is that, variable in Form1 called form’s Load event.

because of the order of events that are fired for your form, you have to create a _loadCalled. This variable makes sure that your favorites get loaded in the

370

Advanced Object-Oriented Techniques

Figure 11-12

The WebFavoriteMenuItem class accepts a WebFavorite object in its constructor, and it configures itself as a menu item using the class. However, this class provides a Click method that you can overload. So, when the user selects the item from the menu, you can immediately open up the URL:

Private Sub WebFavoriteMenuItem_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles Me.Click

‘Open the favorite

If Not Favorite Is Nothing Then Process.Start(Favorite.Url)

End If End Sub

The ExitMenuItem class does a similar thing. When this item is clicked, you call the shared Application.Exit method to quit the program:

Private Sub ExitMenuItem_Click(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles Me.Click

Application.Exit()

End Sub

The important thing here is not the construction of the application itself but rather the fact that you can reuse the functionality you built in a different project. This underlines the fundamental motive for reuse; it means you don’t have to “reinvent the wheel” every time you want to do something.

The method of reuse described here was to add the existing classes to your new project, hence making a second copy of them. This isn’t efficient, because it takes double the amount of storage needed for the classes; however, the classes are small, so the cost of memory is minimal. It did save you from having to create the classes from scratch, allowing you to reuse the existing code, and it was very easy to do.

An alternative way of reusing classes is to create them in a class library. This class library is a separate project that can be referenced by a number of different applications so that only one copy of the code is required. This is discussed in Chapter 12.

Using Shared Proper ties and Methods

On occasion, you might find it useful to be able to access methods and properties that are not tied to an instance of an object but are still associated with a class.

371

Chapter 11

Imagine you have a class that stores the user name and password of a user for a computer program. You might have something that looks like this:

Public Class User

‘Public members

Public Username As String

‘Private members

Private _password As String End Class

Now imagine that the password for a user has to be of a minimum length. You create a separate member to store the length and implement a property like this:

Public Class User

‘Public members

Public Username As String

Public MinPasswordLength As Integer = 6

‘Private members

Private _password As String

‘Password property

Public Property Password() As String

Get

Return _password End Get

Set(ByVal value As String)

If value.Length >= MinPasswordLength Then _password = value

End If End Set

End Property End Class

That seems fairly straightforward. But now imagine that you have 5000 user objects in memory. Each MinPasswordLength variable takes up 4 bytes of memory, meaning that 20KB of memory is being used just to store the same value. Although 20KB of memory isn’t a lot for modern computer systems, it’s extremely inefficient, and there is a better way.

Using Shared Procedures

Ideally, you want to store the value for the minimum password length in memory against a specific class once and share that memory between all of the objects created from that class, as you’ll do in the following Try It Out.

Try It Out

Using Shared Properties

1.Open Visual Studio 2005 and create a new Visual Basic Windows Application project. Call it

SharedDemo.

372

Advanced Object-Oriented Techniques

2.When the Designer for Form1 appears, change the Text property of the form to Shared Demo and then drag a ListBox, a Label, and a NumericUpDown control from the Toolbox onto the form as shown in Figure 11-13.

Figure 11-13

3.Set the Name property of the ListBox control to lstUsers.

4.Set the Name property of the NumericUpDown control to nupMinPasswordLength, set the Maximum property to 10, and set the Value property to 6.

5.Using the Solution Explorer, create a new class named User. Add the highlighted code to the class:

Public Class User

‘Public members

Public Username As String

Public Shared MinPasswordLength As Integer = 6

‘Private members

Private _password As String

‘Password property

Public Property Password() As String

Get

Return _password End Get

Set(ByVal value As String)

If value.Length >= MinPasswordLength Then _password = value

End If End Set

End Property End Class

6.Switch to the Code Editor for Form1 and add this highlighted member:

Public Class Form1

‘Private member

Private arrUserList As New ArrayList()

373

Chapter 11

7.Next, add this method to the Form1 class:

Private Sub UpdateDisplay() ‘Clear the list lstUsers.Items.Clear()

‘Add the users to the list box

For Each objUser As User In arrUserList lstUsers.Items.Add(objUser.Username & “, “ & objUser.Password & _

“ (“ & User.MinPasswordLength & “)”)

Next End Sub

8.Select (Form1 Events) in the Class Name combo box at the top of the Code Editor and the Load event in the Method Name combo box. Add the highlighted code to the Load event:

Private Sub Form1_Load(ByVal sender As Object, _

ByVal e As System.EventArgs) Handles Me.Load

‘Load 100 users

For intIndex As Integer = 1 To 100 ‘Create a new user

Dim objUser As New User objUser.Username = “Robbin” & intIndex objUser.Password = “password15”

‘Add the user to the array list arrUserList.Add(objUser)

Next

‘Update the display UpdateDisplay()

End Sub

9.Select nupMinPasswordLength in the Class Name combo box at the top of the Code Editor and the ValueChanged event in the Method Name combo box. Add the highlighted code to the ValueChanged event:

Private Sub nupMinPasswordLength_ValueChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles nupMinPasswordLength.ValueChanged

‘Set the minimum password length User.MinPasswordLength = nupMinPasswordLength.Value

‘Update the display UpdateDisplay()

End Sub

10.Run the project. You should see a screen like the one shown in Figure 11-14.

11.Scroll the NumericUpDown control up or down, and the list will update itself and the number in parentheses will change to correspond to the number shown in the NumericUpDown control.

374

Advanced Object-Oriented Techniques

Figure 11-14

How It Works

To create a member variable, property, or method on an object that is shared, you use the Shared keyword.

Public Shared MinPasswordLength As Integer = 6

This tells Visual Basic 2005 that the item should be available to all instances of the class.

Shared members can be accessed from within nonshared properties and methods as well as from shared properties and methods. For example, here’s the Password property, which can access the shared

MinPasswordLength member:

‘Password property

Public Property Password() As String Get

Return _password End Get

Set(ByVal value As String)

If value.Length >= MinPasswordLength Then _password = value

End If End Set

End Property

What’s important to realize here is that although the Password property and _password member “belong” to the particular instance of the User class, MinPasswordLength does not, therefore, if it is changed the effect is felt throughout all the object instances built from the class in question.

In the form, UpdateDisplay is used to populate the list. You can gain access to MinPasswordLength as if it were a normal, nonshared public member of the User object:

Private Sub UpdateDisplay() ‘Clear the list lstUsers.Items.Clear()

‘Add the users to the list box

375