***Excerpted from an article I posted to the Mercury Support site:
IE sometimes pops up dialogs. What if we could write code that would handle these without knowing which boxes and in what order they will appear?
Clicking Internet Explorer Dialogs Dynamically
Recently, I was plagued with Internet Explorer Security Alert and Security Information dialog box problems. Seemed like everytime I changed environments (we are a web shop), where these appeared changed. Sometimes, I'd get both, or neither, or just one or the other. I could try and compensate for it, but ultimately led to frustration.
For example, I used the Browser("Browswer").Dialog.Exist function to detect the boxes, then close them. Only trouble was that if the box *didn't* exist, it took QTP 20-30 seconds to tell me. A test run that should only take 15 seconds was taking almost two minutes. While speed isn't something I normally worry about, I felt this was terribly inefficient. Also, what if I changed environments for a particular run? It was concievable that I'd get a dialog in the new environment that I hadn't compensated for, and the whole run would stop. What if this occurred overnight while running a big bank of tests?
I finally wrote some code to use two Win API calls to handle the situation. One, FindWindowEx, would locate the dialogs for me (to Windows OS, *everything* visible is a window with a "handle"). Once I located the one I wanted, I used PostMessage to send the click to the dialog, and off we went. These functions work so fast you hardly notice the boxes pop up. Once I got this point, I registered them to my browser object using the RegisterUserFunc function in QTP. Now, I simply call Browser("Browser).ClearDialogs anywhere I think I might see them. The code has become more self-regulating and intelligent as a result.
I stored these in an external VBS file for ease.
***End Excerpt
I'll include the code once I get it formatted for the blog.
EDIT: Rather than get blasted by the BlogNotSee, I'll include a link to my code once I get it ready and posted on my own site. No need incur his wrath for something like this.....If you know him, you know what I mean. :-)
EDIT: I've had many requests to see the actual code, and I keep forgetting to post it. Anyway, here it is:
Option Explicit
Public Const WM_COMMAND = &H111&
Extern.Declare micHwnd, "FindWindowEx", "user32.dll", "FindWindowExA", micHwnd, micHwnd, micString, micString
Extern.Declare micLong, "PostMessage", "user32.dll", "PostMessageA", micHwnd, micLong, micLong, micLong
Extern.Declare micLong, "SendMessage", "user32.dll", "SendMessageA", micHwnd, micLong, micLong, micLong
Public Sub ClearDialogs()
'************************************************************************
'*Function: ClearDialogs
'*Author: Theo Moore
'*Date: 02142006
'*Assumptions:
'* - That the Object being passed here
'* is an Browser object
'*Inputs:
'* - Object: The object to used in downstream
'*
'*Outputs:
'* - None
'*
'*Notes:
'* This function is registered to Browser objects. It checks to see
'* if any dialogs are present. Using descriptive prog, we can get the
'* dialog without having to learn it. We can also add more logic
'* to handle other dialogs since sometimes we get more than one.
'*************************************************************************
Dim Hwnd
Dim blnNoMoreDialogs
Dim lResult
blnNoMoreDialogs = False
Wait 2 'We have to wait, as this call may execute faster then IE can pop the box
Do Until blnNoMoreDialogs
Hwnd = extern.FindWindowEx(0,0,vbNullString, "Security Alert")
If Hwnd = 0 Then
Hwnd = extern.FindWindowEx(0,0,vbNullString, "Security Information")
End If
blnNoMoreDialogs = Not(CBool(Hwnd))
If Hwnd > 0 Then
lResult = extern.PostMessage(Hwnd, WM_COMMAND, 6, 0)
'TM - 10192006
'Added a one second wait here to let another window pop should
'one need to be shown immediately after the first one
Wait 1
End If
Hwnd = 0
Loop
End Sub
RegisterUserFunc "Browser", "ClearDialogs", "ClearDialogs"