As a concluding exercise for this chapter, we will develop a pop-up eliminator application. If you have used the World Wide Web, you probably are already familiar with pop-ups, as shown in Figure 7.2. These additional windows display ads or other information in a separate Internet Explorer window, which must be closed to avoid cluttering up the screen. To help eliminate this nuisance, we will write a sample program that will automatically close these windows for you. In doing so, we will use several types of decision and control statements, including the If statement and several types of loops. Figure 7.2. Secondary windows such as "pop-up" advertisements can be really annoying when you are trying to browse the Internet. Creating the Sample Form To create the sample application, perform the following steps: -
Create a new Windows Application Project. -
Add a list box to the form and set its Name property to lstStatus. -
Add two button controls to the form. Set their names to btnStart and btnStop and their Text properties to Start and Stop, respectively. -
Drag a Timer control to the form. It will appear at the bottom. Change its Name property to tmrCheck. -
Set the Enabled property of tmrCheck to True. -
Set the Interval property of tmrCheck to 2000. Your form is now designed and should look similar to the one in Figure 7.3. Figure 7.3. A Timer control will be used to repeatedly update the list box with a list of Internet Explorer windows. For more on the Timer control, p.309 Adding the Code Open the code window for the form and find a section within the form class after the code generated by the form designer. Enter the code in Listing 7.2. Listing 7.2 POPUP.ZIP Custom Functions Used by the Sample Application 'API Declarations Private Declare Function FindWindow Lib "user32" Alias "FindWindowA"_ (ByVal ClassName As String, ByVal lpWindowName As String) As Integer Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA"_ (ByVal hwnd As Integer, ByVal lpClassName As String,_ ByVal intMaxCount As Integer) As Integer Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA"_ (ByVal hwnd As Integer, ByVal lpWindowText As String,_ ByVal cch As Integer) As Integer Private Declare Function GetWindow Lib "user32"_ (ByVal hwnd As Integer, ByVal wCmd As Integer) As Integer Private Const GW_HWNDNEXT As Integer = 2 Private Declare Function SendWin32Message Lib "user32" Alias "SendMessageA"_ (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer,_ ByVal lParam As Integer) As Integer Private Const WM_CLOSE As Integer = &H10 Private Const WM_COMMAND As Integer = &H111 'Array of Windows we do NOT want to close Private IEWindowsToKeep() As Integer Private Sub GetIEWindowList(ByRef WindowHandleList() As Integer) Dim hwndCurrent As Integer 'Current window handle Dim sClassName, sWindowCaption As String 'Class and window names Dim intClassLen, intCaptionLen As Integer 'Length of class and window names Dim sDisplayInfo As String Dim intWindowCount As Integer = 0 'Some Windows API calls require pre-filled strings Const Max_Chars As Integer = 50 sClassName = Space(Max_Chars + 1) sWindowCaption = space(Max_Chars + 1) 'Add window information to the list box and array lstStatus.Items.Clear() hwndCurrent = FindWindow("IEFrame", Nothing) Do While hwndCurrent <> 0 intClassLen = GetClassName(hwndCurrent, sClassName, Max_Chars) intCaptionLen = GetWindowText(hwndCurrent, sWindowCaption, Max_Chars) If intCaptionLen > 0 And intClassLen > 1 Then If sClassName.Substring(0, 2) = "IE" Then sDisplayInfo = "Class:" & sClassName.Substring(0, intClassLen) & chr(9) sDisplayInfo &= "Caption:" & sWindowCaption.Substring(0, intCaptionLen) sDisplayInfo &= "Handle: " & hwndCurrent lstStatus.Items.Add(sDisplayInfo) intWindowCount += 1 ReDim Preserve WindowHandleList(intWindowCount) WindowHandleList(intWindowCount - 1) = hwndCurrent End If End If hwndCurrent = GetWindow(hwndCurrent, GW_HWNDNEXT) Loop End Sub Private Sub CloseExtraIEWindows(ByRef WindowList() As Integer) Dim i As Integer For i = 0 To Ubound(WindowList) If array.BinarySearch(IEWindowsToKeep, windowlist(i)) < 0 Then 'Send messages to close the window lstStatus.Items.Add("Closing window " & windowlist(i)) SendWin32Message(windowlist(i), WM_COMMAND, &HA021, 0) SendWin32Message(windowlist(i), WM_CLOSE, 0, 0) End If Next End Sub The code in Listing 7.2 contains several Windows API declarations. API declarations are native Windows functions that are not part of the .NET framework and therefore must be declared in order to be accessed from within Visual Basic .NET. In this program they are used to work with the windows on your system. Each window has a handle, which is a unique number that identifies it. The GetIEWindowList custom function uses API calls to retrieve the handles for all of the open Internet Explorer windows and stores them in an integer array. This array, along with a second, class-level integer array (IEWindowsToKeep) is used by another custom function, CloseExtraIEWindows. This function closes any Internet Explorer Windows that are not in the IEWindowsToKeep array. For more on the Windows API, p.699 For the program to function, we'll need to add code to three event procedures: The Tick event of tmrCheck initiates the checking process. The Timer control will fire this event about every two seconds. The Click event of btnStart fills the IEWindowsToKeep array. The Click event of btnStop stops the process so you can open additional Internet Explorer windows. The code for each of these event procedures is in Listing 7.3. Listing 7.3 POPUP.ZIP Event Procedures Code for the Sample App Private Sub tmrCheck_Tick(ByVal sender As Object,_ ByVal e As System.EventArgs) Handles tmrCheck.Tick Dim ListOfIEWindows() As Integer tmrCheck.Enabled = False GetIEWindowList(ListOfIEWindows) If Not ListOfIEWindows Is Nothing Then If Not IEWindowsToKeep Is Nothing Then CloseExtraIEWindows(ListOfIEWindows) End If End If tmrCheck.Enabled = True End Sub Private Sub btnStart_Click(ByVal sender As Object,_ ByVal e As System.EventArgs) Handles btnStart.Click Dim ListOfIEWindows() As Integer tmrCheck.Enabled = False GetIEWindowList(ListOfIEWindows) If Not ListOfIEWindows Is Nothing Then IEWindowsToKeep = ListOfIEWindows Array.Sort(IEWindowsToKeep) MessageBox.Show("Any new IE Windows will be closed.") Else MessageBox.Show("Please open some IE windows first") End If tmrCheck.Enabled = True End Sub Private Sub btnStop_Click(ByVal sender As Object,_ ByVal e As System.EventArgs) Handles btnStop.Click IEWindowsToKeep = Nothing Messagebox.Show("Stopped closing windows.") EndSub Testing the Program To test your program, perform the following steps: -
Run the program. -
Open as many Internet Explorer windows as you would like to use. -
Click the Start button. -
Begin browsing the Web. Any new windows that pop up should be quickly closed. You can test this by clicking Ctrl+N (open new window) in Internet Explorer. As the program is running, you will see a list of Internet Explorer windows displayed in the list box, as shown in 7.4. Figure 7.4. The sample application displays a list of open Internet Explorer windows and indicates which ones it has closed. |