mixing
Regular Member
- Jan 18, 2014
- 412
- 63
Hello everyone.. I hope someone can help me figure this out as it's been bothering the heck out of me.
So, I've got a WebBrowser component accessing webpages just fine. Some of the websites I try to access give those dreaded script errors like the one you see below.
I've tried going in and changing the ScriptErrorsSuppressed to 'True' and yet these javascript errors keep coming up. I know the best thing to do would be to have the website owners fix these errors, but since my tool accesses so many different websites that will be pretty much impossible. I did some more browsing online and found a nice little class that will automatically click on Dialog Boxes for you. I tested it with a normal messagebox and it seams to do the trick. However, when I try to make it work with these javascript dialog boxes I get nowhere. Below is the code I'm trying.
DialogHandler Class
I have a timer which kicks off looking for the dialog boxes. Here is the code for my timer
As I mentioned, this code works fine for a traditional dialog box, such as a message box. But, for the one in my screenshot above nothing happens. At first I thought maybe I needed to change the parameter in my timer code. So I tried both..
and
Still nothing..Any ideas where I could be going wrong here? I can see the Yes/No buttons in the screenshot have lines under them and I'm not sure if that would make any difference.
So, I've got a WebBrowser component accessing webpages just fine. Some of the websites I try to access give those dreaded script errors like the one you see below.
I've tried going in and changing the ScriptErrorsSuppressed to 'True' and yet these javascript errors keep coming up. I know the best thing to do would be to have the website owners fix these errors, but since my tool accesses so many different websites that will be pretty much impossible. I did some more browsing online and found a nice little class that will automatically click on Dialog Boxes for you. I tested it with a normal messagebox and it seams to do the trick. However, when I try to make it work with these javascript dialog boxes I get nowhere. Below is the code I'm trying.
DialogHandler Class
Code:
Imports System.Runtime.InteropServices
Public Class DialogHandler
'API CONSTANTS
Const WM_GETTEXT As Long = &HD
Const WM_GETTEXTLENGTH As Long = &HE
Const GW_ENABLEDPOPUP As Long = 6
Const BM_CLICK As Long = &HF5&
Const GW_CHILD As Long = 5
Const GW_HWNDNEXT As Long = 2
'FINDS CHILD WINDOWS
Private Declare Auto Function GetWindow Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal uCmd As Integer) As IntPtr
'SEND MESSAGES TO THE BUTTON
Private Declare Auto Function SendMessage Lib "user32.dll" Alias "SendMessage" (ByVal hWnd As IntPtr, ByVal Msg As Integer, _
ByVal wParam As Integer, ByRef lParam As IntPtr) As IntPtr
'GETS WINDOW TEXT
Private Declare Auto Function SendMessageA Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As IntPtr, ByVal Msg As Integer, _
ByVal wParam As IntPtr, ByRef lParam As IntPtr) As IntPtr
<DllImport("User32.dll", CharSet:=CharSet.Auto, Entrypoint:="SendMessage")> Public Shared Function SendMessageString(ByVal hwnd As IntPtr, _
ByVal wMsg As Integer, ByVal wparam As Integer, ByVal lparam As System.Text.StringBuilder) As IntPtr
End Function
Private Function GetChildWindowHandles(ByVal ParentWindowHandle As IntPtr) As ArrayList
Dim ptrChild As IntPtr
Dim clsRet As New ArrayList
'GET FIRST CHILD HANDLE
ptrChild = GetChildWindowHandle(ParentWindowHandle)
Do Until ptrChild.Equals(IntPtr.Zero)
'ADD TO COLLECTION OF HANDLES
clsRet.Add(ptrChild)
'GET NEXT CHILD
ptrChild = GetNextWindowHandle(ptrChild)
Loop
Return clsRet
End Function
Private Function GetChildWindowHandle(ByVal ParentWindowHandle As IntPtr) As IntPtr
Return GetWindow(ParentWindowHandle, GW_CHILD)
End Function
Private Function GetNextWindowHandle(ByVal CurrentWindowhandle As IntPtr) As IntPtr
Return GetWindow(CurrentWindowhandle, GW_HWNDNEXT)
End Function
'RETURNS TEXT OF THE WINDOW FOR CONFIRMATION OF CORRECT DIALOG
Private Function GetWindowText(ByVal WindowHandle As IntPtr) As String
Dim ptrRet As IntPtr
Dim ptrLength As IntPtr
'LENGTH OF BUFFER
ptrLength = SendMessageA(WindowHandle, WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero)
'BUFFER NEEDED FOR RETURN VALUE
Dim sb As New System.Text.StringBuilder(ptrLength.ToInt32 + 1)
'WINDOW TEXT
ptrRet = SendMessageString(WindowHandle, WM_GETTEXT, ptrLength.ToInt32 + 1, sb)
Return sb.ToString
End Function
'SEND A 'CLICK' TO THE BUTTON ("WINDOW")
Private Sub PerformClick(ByVal WindowHandle As IntPtr)
SendMessage(WindowHandle, BM_CLICK, 0, IntPtr.Zero)
End Sub
Public Sub LookForAndCloseIEPopup(ByVal whichButton As String)
'GET HANDLE OF ANY POPUP WINDOW ASSOCIATED WITH MAIN FORM
Dim ptrDialogWindow As IntPtr = GetWindow(Process.GetCurrentProcess.MainWindowHandle, GW_ENABLEDPOPUP)
'IF IT'S A BROWSER POPUP, HANDLE IT
If GetWindowText(ptrDialogWindow) = "Microsoft Internet Explorer" Or GetWindowText(ptrDialogWindow) = "Message from webpage" Or GetWindowText(ptrDialogWindow) = "Windows Internet Explorer" Then
ClosePopup(ptrDialogWindow, whichButton)
End If
End Sub
Private Sub ClosePopup(ByVal WindowHandle As IntPtr, ByVal whichButton As String)
Dim clsChildHandles As ArrayList = GetChildWindowHandles(WindowHandle)
For Each ptrHandle As IntPtr In clsChildHandles
'IF IT FINDS A BUTTON WITH THE TEXT SPECIFIED, CLICK IT
If GetWindowText(ptrHandle).Contains(whichButton) Then PerformClick(ptrHandle) : Exit For
Next
End Sub
End Class
I have a timer which kicks off looking for the dialog boxes. Here is the code for my timer
Code:
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim dh As New DialogHandler
dh.LookForAndCloseIEPopup("No") 'This single parameter is the text of the button you want to click (case insensitive)
End Sub
As I mentioned, this code works fine for a traditional dialog box, such as a message box. But, for the one in my screenshot above nothing happens. At first I thought maybe I needed to change the parameter in my timer code. So I tried both..
Code:
dh.LookForAndCloseIEPopup(&No") 'This single parameter is the text of the button you want to click (case insensitive)
and
Code:
dim noo as string = string.format("&No")
dh.LookForAndCloseIEPopup(noo) 'This single parameter is the text of the button you want to click (case insensitive)
Still nothing..Any ideas where I could be going wrong here? I can see the Yes/No buttons in the screenshot have lines under them and I'm not sure if that would make any difference.
Last edited: