|
-
Jun 17th, 2008, 02:30 PM
#1
Thread Starter
Member
[RESOLVED] Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
I have a module that makes heavy use of code developed by Kleinma. (His work available here)
I have made some minor modifications, in that I call alertCheck() as a function. Also, I have it returning a Boolean so I know whether it had to close a javascript alert.
In a nutshell, I am setting up users for a web site. I have a MainForm, with a WebBrowser1. I also have an AddUserForm. When the AddUserForm is ran, it attempts to add a user to the site via the WebBrowser1 control. If the email address that the application is creating using their first initial and last name is already taken, then the site pops a javascript alert when we attempt to save.
What I would like is to use the alertCheck() module to handle the javascript alert if it is there, and then to return the boolean so we know that we need to try a different email address format.
The problem is that instead of closing the javascript alert, it is currently closing the MainForm application window, closing the program.
Can anyone see why that might be happening?
vb Code:
Imports System.Runtime.InteropServices
Module JSAlertHandlerModule
'DLL IMPORTED FUNCTIONS FOR GETTING ACTIVE JS ALERT BOX AND SENDING A CLOSE MESSAGE TO IT
<DllImport("user32.dll")> _
Function GetLastActivePopup(ByVal hwnd As IntPtr) As IntPtr
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Function PostMessage( _
ByVal hWnd As IntPtr, _
ByVal Msg As Integer, _
ByVal wParam As IntPtr, _
ByVal lParam As IntPtr) As Boolean
End Function
Function alertCheck() As Boolean
'GET HANDLE OF LAST ACTIVE POPUP (AKA JS ALERT)
Dim PopupHandle As IntPtr = GetLastActivePopup(MainForm.Handle)
Dim alertsCounted As Integer = "0"
'IF THE POPUP HANDLE IS NOT 0, AND IT IS NOT THE WB HANDLE
'THEN SEND A WM_CLOSE MESSAGE (&H10) TO THE POPUP
If (PopupHandle <> IntPtr.Zero) AndAlso (PopupHandle <> MainForm.WebBrowser1.Handle) Then
'MsgBox(PopupHandle.ToString & " = " & MainForm.WebBrowser1.Handle.ToString)
PostMessage(PopupHandle, &H10, New IntPtr(1), IntPtr.Zero)
alertsCounted = alertsCounted + 1
End If
'If we had to close any, then we return TRUE. Otherwise, FALSE.
If alertsCounted > 0 Then
Return True
Else
Return False
End If
End Function
End Module
Last edited by GeekInOhio; Jun 18th, 2008 at 12:37 PM.
Reason: Clarification.
In case I forget: I'm using Visual Basic 2008 Express Edition...
Should I, in my odd, bumbling way, actually offer some assistance, feel free to show me some RATE love.
Just Another Laptop Hero
-
Jun 18th, 2008, 11:50 AM
#2
Thread Starter
Member
Re: Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
Just following up to ask once more if anyone can offer assistance.
Thanks!
In case I forget: I'm using Visual Basic 2008 Express Edition...
Should I, in my odd, bumbling way, actually offer some assistance, feel free to show me some RATE love.
Just Another Laptop Hero
-
Jun 18th, 2008, 01:33 PM
#3
Re: Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
the issue is that GetLastActivePopup(MainForm.Handle) is returning MainForm.Handle instead of the handle to the JS alert popup. This can happen in 3 scenarios. If you notice in my example code, there is a link to the MSDN doc, which states:
The return value identifies the most recently active pop-up window. The return value is the same as the hWnd parameter, if any of the following conditions are met:
The window identified by hWnd was most recently active.
The window identified by hWnd does not own any pop-up windows.
The window identifies by hWnd is not a top-level window, or it is owned by another window.
So I would imagine ONE of these conditions is being met.
Is there any focus changing going on back to your original form when this JS alert happens? That would cause condition 1.
Are you calling this code PRIOR to the popup actually being shown? This would cause condition 2.
Is the form that contains the browser control actually inside another form? Is it not a top level window? This would cause condition 3.
-
Jun 18th, 2008, 02:01 PM
#4
Thread Starter
Member
Re: Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
Below is a snippet from the createUser() function that calls the alertCheck() function:
VB Code:
'We have to put the focus() on the web page so that we can click the create button.
MainForm.WebBrowser1.Document.Window.Frames(6).Frames(1).Document.All.GetElementsByName("txtLastName").Item(0).Focus()
'CLICK Create Button!
MainForm.WebBrowser1.Document.Window.Frames(6).Frames(1).Document.All.Item("objTitleBar_cmdSave").InvokeMember("click")
Pause()
'Now we need to make sure that email address wasn't already taken.
'If it was, then a JavaScript alert will have launched.
'If it was taken, we'll try an alternate email address here before moving on.
'If the alternate is ALSO taken, then we'll kill the process and have them manually create the user.
If alertCheck() = True Then
etc...
This is the pause() sub that is called in that above snippet. It basically just waits for the frame to fully reload before moving forward:
vb Code:
'This checks the main frame of CM and makes sure and tells us if it is loaded.
Sub Pause()
Dim contentFrame As HtmlElement = MainForm.WebBrowser1.Document.Window.Frames(6).Frames(1).WindowFrameElement
Do
Application.DoEvents()
Loop Until contentFrame.GetAttribute("readyState") = "complete"
End Sub
The MainForm is.. for lack of a better phrase, the main form. The Webbrowser control is on this form. AddUserForm is launched from the MainForm, and floats above it. When you finish filling out AddUserForm, you click continue and it calls the createUser() sub, a snippet of which is posted above.
So, if I'm reading everything correctly, I can rule out Condition 3. It's not a form within a form.
I also think I can rule out Condition 1. While I put focus on the Webbrowser to click on the save button, I don't change the focus after that.
So I must be calling the checkAlert() prior to the actual alert popping up. But doesn't your code prevent the main window from closing itself? I thought that was what this was doing:
vb Code:
AndAlso (PopupHandle <> MainForm.WebBrowser1.Handle) Then
I assumed (Please insert joke here) that if there was no popup, it would do nothing. In fact, I was counting on that. I need to call this every time, as I can't predict ahead of time whether the email address will be taken. Should I be using a different approach?
In case I forget: I'm using Visual Basic 2008 Express Edition...
Should I, in my odd, bumbling way, actually offer some assistance, feel free to show me some RATE love.
Just Another Laptop Hero
-
Jun 18th, 2008, 02:14 PM
#5
Re: Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
The code is checking to make sure the PopupHandle is not the WEBBROWSERS handle. It does not check to make sure it is not the main window handle.
You could add in
AndAlso (PopupHandle <> MainForm.Handle)
to that if statement to avoid a close message being sent to the MainForm in the situation you are having.
As far as figuring out why the supress itself doesn't work, it likely could be an issue with the pause method you are using. I personally don't use that, I use the DocumentCompleted event, which fires off when a document (or frame) has fully loaded into the browser.
Have you looked at using that event instead of trying to do an inline pause of your code?
-
Jun 18th, 2008, 02:40 PM
#6
Thread Starter
Member
Re: Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
Ok, now we are getting somewhere.
I added:
AndAlso (PopupHandle <> MainForm.Handle)
And while it is still not handling the alert, it has stopped closing the entire application.
My solution with pause() sub was basically a blind man scratching about and finding something that sorta worked for most things. I'm teaching myself VB as I go, and obviously I still have a hill to climb on that front.
The site I'm manipulating is a nested frames nightmare, as you can see by the snippets I've posted.
When I'm clicking buttons on the forms, only that frame appears to be refreshing. Looking for the readystate of complete seemed to work, but when I made an empty do loop, it locked the program up. When I added the Application.DoEvents(), it functioned.
I know that the WebBrowser control has a DocumentCompleted event, but I'm unusre of how I would make use of that in this particular case. The only thing I can think of would be something like setting a My.Settings.browserBusy = TRUE when it is navigating, and then setting it to FALSE when DocumentCompleted fires. Then my pause loop could just wait for the flag to be FALSE prior to moving on?
Is that close to what you meant, or I have I wandered off down the wrong path on this one?
In case I forget: I'm using Visual Basic 2008 Express Edition...
Should I, in my odd, bumbling way, actually offer some assistance, feel free to show me some RATE love.
Just Another Laptop Hero
-
Jun 18th, 2008, 05:05 PM
#7
Re: Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
this doesn't happen to be a public site does it? Usually when doing web automation, and running into weird quirks, it is just easier to debug it on the site itself versus making guesses.
Since every site is coded differently, this is the nature of automating a website, which of course, was never the intention of the people who built the website.
-
Jun 19th, 2008, 10:26 AM
#8
Thread Starter
Member
Re: Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
No, not a public site. It's a web service run by my company. I'm creating an application to make our setup duties on this site much easier.
I have made more progress. I have discovered that the JavaScript alert is firing BEFORE DocumentCompleted. In fact, until you click "Ok", the document doesn't finish loading.
I'm going to try a different tack on this and use your example to strip the alert all together, then test the page contents to see if it saved correctly or not. I'll post an update later today.
I can't thank you enough for the help thus far.
In case I forget: I'm using Visual Basic 2008 Express Edition...
Should I, in my odd, bumbling way, actually offer some assistance, feel free to show me some RATE love.
Just Another Laptop Hero
-
Jun 19th, 2008, 11:07 AM
#9
Re: Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
Does your company actually OWN the webservice code?
If that is the case, it would be a ton easier to have the webservice just expose a method for doing this setup that you can just consume in a VB app.
Usually automation of a website is a last resort when you only have access to the site via the browser.
-
Jun 19th, 2008, 11:57 AM
#10
Thread Starter
Member
Re: Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
We own the code, and the site. However it's a large company, and getting access to or changes made in the code is next to impossible. If we ask development to add a function, it takes roughly 6 months to get done. I can have our 20 most commonly used tools created and in use for our team in half that time.
But that is alright, as I have it working at last!
Stripping the alert proved problematic, and I ended going back to something much closer to your original example, using a timer. All I had to do was start the timer from WebBrowser1_Navigated instead of DocumentCompleted.
Many thanks for the help, and for the excellent example code!
Until next time, have a good one!
In case I forget: I'm using Visual Basic 2008 Express Edition...
Should I, in my odd, bumbling way, actually offer some assistance, feel free to show me some RATE love.
Just Another Laptop Hero
-
Jun 19th, 2008, 12:11 PM
#11
Re: [RESOLVED] Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
Glad you got it working.
The timer approach is always one I use as a last resort, however when I was making that code example originally, it turned out it was pretty much a requirement to get it working correctly in 1 of the 2 scenarios.
Webpage manipulation can be really tricky like that sometimes.
-
Jun 26th, 2013, 05:59 PM
#12
Member
Re: [RESOLVED] Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
I'd like to share an interesting result of some simple modifications to Kleinma's brilliant original. This is what I did:
1) I increased tmrPopCheck.Interval from 100 to 1000;
2) I suppressed the line "tmrPopCheck.Stop()" at the Sub "tmrPopCheck_Tick";
3) I replaced the line "If (PopupHandle <> IntPtr.Zero) AndAlso (PopupHandle <> WB.Handle) Then" by "If (PopupHandle <> IntPtr.Zero) AndAlso (PopupHandle <> WB.Handle) AndAlso (PopupHandle <> Me.Handle) Then".
By doing this, every JSAlert (both "onload" and "onclick") is now promptly killed, and the form is not closed.
I have also a question:
What if my page has a JS Confirm pop-up (with OK and Cancel buttons) instead of a simple Alert? How could I give it one or other of these answers programatically? Is that possible?
Thank you very much!
-
Jun 27th, 2013, 04:23 AM
#13
Re: [RESOLVED] Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
I'm not selling anything, but thought I would mention a tool we use for automation of websites. It has a builder app to basically record the steps needed during a run, with the ability to handle popups and the like. iMacros. You can use the explorer addons for free.
-
Jun 27th, 2013, 05:12 AM
#14
Member
Re: [RESOLVED] Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
Thanks for sharing this information. I knew that from some experiences in Firefox-requiring websites. But I already have a quite complex application for automating navigation with VB.Net WebBrowser, and the ability of answering JS Confirm pop-ups would be the cherry on top of my cake... So what I want to learn is how to give them responses other than "close window" (&H10). Thanks again!
-
Jun 28th, 2013, 06:50 AM
#15
Member
Re: [RESOLVED] Help With Kleinma's Suppressing Javascript Alerts in WebBrowser
Ok, it's possible to select JS-Confirm response by replacing line "PostMessage(PopupHandle, &H10, New IntPtr(1), IntPtr.Zero)" with one of these:
-> "PostMessage(PopupHandle, &H100, New IntPtr(13), IntPtr.Zero)" (posts "Enter" typing, i.e. Ok)
-> "PostMessage(PopupHandle, &H100, New IntPtr(27), IntPtr.Zero)" (posts "Esc" typing, i.e. Cancel)
VBobCat
VS2013 & Office-VBA
Autodidact, part-time programmer for job needs
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|