SendMessage {ENTER} to Internet Explorer browser iFrame element - vb.net

I have a little project that needs me to automate IE.
I've used SHDocVw.InternetExplorer class for the initial move. (attaching to IE)
But after that I want to use the Windows API to get focus to browser element and to click it.
I know that I can do this job more easy with the built in function of SHDocVw.InternetExplorer, or use 3rd party class like Watin
But this time I want to use Windows API.
This is work perfect when I open IE browser and find some links/element to click
I used the key press {TAB} to iterate thru HTML elements then read the IE status bar to get its link. Then I use the key press {ENTER} to click/execute it.
I got problem when the element that are selected by {TAB} are inside iFrame, the keypress {ENTER} not work.
Here is my sample code
Imports WindowsApplication1.win_Api
Module browser
Public Class IE
Private Shared IE As SHDocVw.InternetExplorer
Sub New(Optional ByVal url As String = "about:blank")
Dim bw As New SHDocVw.InternetExplorer
IE = bw
Try
IE.Navigate(url)
Catch ex As Exception
End Try
End Sub
Shared Sub click(byval url as string)
Dim Z As Integer = 0
Do While Z = 0
IE.Stop()
'Send keboard press TAB this API is work perfect
SendMessage(IE.HWND, WM_IME_KEYDOWN, Keys.Tab, 0)
IE.Stop()
If IE.StatusText = url Then
Z = 1
End If
Loop
For Each I As IntPtr In GetChildWindows(IE.HWND)
Dim L As Integer = 256
Dim sb As New System.Text.StringBuilder(L)
GetClassName(I, sb, L)
If sb.ToString = "Internet Explorer_Server" Then
'Send keyboard press ENTER, this work
'But not work if the element selected by TAB action is on iframe
SendMessage(I, WM_CHAR, Keys.Enter, 0)
End If
Next
End Sub
End Class
End Module

Related

Downloading pdf file through webbrowser

i will make it simple, i need to silenty (without download dialog pop up) download a file from a website through webbrowser in vb.net, i cant download using WebClient, because i have to be login in first, neither httprequest will work even login in with it first, because first it have google captcha for login, 2nd i dont want automate the login stuff ..
i have tried api stuff:
Dim hwnd = FindWindow(vbNullString, "File Download")
If hwnd <> IntPtr.Zero Then ' dialog window found
'MsgBox("yes")
' find button on dialog window: classname = "Button", text = "OK"
Dim btn = FindWindowEx(hwnd, IntPtr.Zero, "Button", "&Save")
'Dim sd = FindWindowEx(hwnd, IntPtr.Zero, )
If btn <> IntPtr.Zero Then ' button found
' activate the button on dialog first or it may not acknowledge a click msg on first try
SendMessage(btn, WM_ACTIVATE, WA_ACTIVE, 0)
' send button a click message
SendMessage(btn, BM_CLICK, 0, 0)
Else
MsgBox("button not found!")
End If
End If
so the far, it gets the windwo, also the button found, but it wont press/click on it, its like there nothing happens ..(plus: dont incourage me for sendkeys stuff, i want it silenty)
using IE: 11
Any chances that i download using httprequest by transfering the cookie (or whatver) from webbroser to http ? any workaround, please do let me know.

Is there a way to open an IE window with a user-defined name. When same URL opened, already opened IE window comes to foreground

Here is my requirement which I intend to implement. There is one window application showing some icons which take me to different web sites. When I click on one of the icons, it should open an IE window and append a customized name to it.
So, before opening any website after I click on website icon, I want to check if there is already an IE window open with that customized name, if yes, bring that already opened window to the foreground. If not, open a new IE window.
I have checked various questions posted which are related to what I am looking to achieve, but am somehow not able to get it right. Below is my attempt.
For Each e In shellWins
If InStr(1, e.GetProperty("IEWindowName"), namedWindow, CompareMethod.Text) <> 0 Then
hWnd = e.HWND
myIE = e
End If
Next
If hWnd == -1
Dim p As New Process
Dim psi As New ProcessStartInfo(IEPath, webSiteURL)
p.StartInfo = psi 'Trying to open a new IE window
p.Start()
For Each ie In shellWins
If ie.hwdn = p.MainWindowHandle Then
ie.PutProperty("IEWindowName", namedWindow)
End If
Next
End if
Else
myIE.BringToForeground()
This sometime works and sometimes does not. Is there any better way to do it?
It doesn't work in which situation? Does there any error throw when it doesn't work? If there is, please tell us the detailed error information and in which line it occurs.
Besides, you could try to compare the url to check if the website is already open in IE like this:
Sub Main()
Dim shellWins As SHDocVw.ShellWindows
Dim explorer As SHDocVw.InternetExplorer
shellWins = New SHDocVw.ShellWindows
Dim SQuery As String = "https://www.example.com/"
For Each explorer In shellWins
If explorer.Application.Name = "Internet Explorer" And explorer.LocationURL.Contains(SQuery) Then
explorer.BringToForeground()
End If
Next
shellWins = Nothing
explorer = Nothing
End Sub

Trouble clicking on a load more button using vba

I'm trying to click on the Load More button located at the bottom of the left window of this webpage using vba in combination with selenium but the script always throws timeout error pointing at this .Get Url line. Although it seems I've defined an accurate xpath to locate the element, I can't think further as to what I should do now to achieve the same.
How can I click on that Load More button?
Sub ClickOnLoadMore()
Const Url$ = "http://www.ratemyprofessors.com/search.jsp?queryoption=TEACHER&queryBy=schoolDetails&schoolID=457&schoolName=James+Madison+University&dept=select"
Dim driver As New ChromeDriver, post As Object
With driver
.Get Url
Set post = .FindElementByXPath("//div[contains(.,'Load More')]")
.ExecuteScript "arguments[0].scrollIntoView();", post
post.Click
End With
End Sub
I see two "Load More" buttons. Both are matched by "//div[contains(.,'Load More')]". The first one is hidden. You need to handle second one.
Try this XPath
"//div[#class='content' and . = 'Load More']"
At least for me there were a couple of banners to dismiss as well as scrolling. There was no problem with the get line
Option Explicit
Public Sub ClickOnLoadMore()
Const Url$ = "http://www.ratemyprofessors.com/search.jsp?queryoption=TEACHER&queryBy=schoolDetails&schoolID=457&schoolName=James+Madison+University&dept=select"
Dim driver As New ChromeDriver, post As Object
With driver
.get Url
If .FindElementsByCss(".close-notice.close-this").Count > 0 Then
.FindElementByCss(".close-notice.close-this").Click
End If
.SwitchToFrame .FindElementByCss("[id^='spout-unit-iframe']")
With .FindElementByCss("#spout-ads #spout-header-close")
.ScrollIntoView
.Click
End With
.SwitchToDefaultContent
.ExecuteScript "document.querySelector('.result-list [onclick*=LoadMore]').scrollIntoView(true);" & _
"window.scrollBy(0, -(window.innerHeight - this.clientHeight) / 2);"
.FindElementByCss(".result-list [onclick*=LoadMore]").Click
Stop '<== Delete me later
'other code
.Quit
End With
End Sub

How can I play the first url that I get when I search in youtube with vb.net?

I trying to do a program in vb.net that will search a video on youtube by words and play the first url (the first result) that I will get without waiting to client to choose.
Someone can help me?
I did the search but I dont know how to do that it will play the first video that I will get automatically.
What form you choose to develop this program ? Webform ? Winform?
I assume that the form is winform, then you could use the "WebBrowser" (you can find the "WebBrowser" in the toolbox)
Private Sub openYouTube()
WebBrowser1.Navigate("https://www.youtube.com/?gl=TW")
End Sub
Find the search bar on the youtube (use GetElementByID) and insert the string which you want to search (Use SetAttribute). The ID of the inputbox of youtube search bar is "search" (How to find the ID of any element in a webpage? Target the element and click the right button of mouse, choose "inspect" for Chrome, "inspect element" for IE, it would show the element detail)
Private Sub inputString&SearchIt()
Dim theStringYouWantToSearch as string
WebBrowser1.Document.GetElementById("search").SetAttribute("value", theStringYouWantToSearch)
End Sub
Execute the search (Use InvokeMember("click") to fire the search)
Private Sub executeSearch()
WebBrowser1.Document.GetElementById("search-icon-legacy").InvokeMember("click")
End Sub
Find the first result and record the URL.
This process is more complicated, use GetElementsByTagName to get a collection of result tables, the first result is the first item of this collection. Find the table of first result then loop through all elements of this table, to find the element which id is "thumbnail", and this element has the information of part of URL.
Private Sub findFirstResult()
Dim elemCollection as HtmlElementCollection
Dim firstResultTable as HtmlElement
Dim hrefString as string
Dim resultURL as string
elemcollection = WebBrowser1.Document.GetElementsByTagName("ytd-video-renderer")
firstResultTable = elemCollection.item(0)
For each element as HtmlElement in firstResultTable.All
If element.Id = "thumbnail" then
hrefString = element.GetAttribute("href")
End if
Next
resultURL = "https://www.youtube.com" & hrefString
End Sub
Between every step, you have to wait for the complement of webpage loading, or the program wouldn't find the element. There are several ways to do that, you could do some search for that.

VB.net send keypress to game

ive seen other questions about this issue but none of them resolved it for me so here i go. I'm trying to send a keypress to a game to save the progress(its a 64bit game). what i've coded so far is :
Dim p() As Process
Dim GameID As Integer = 0
Dim p As Process() = Process.GetProcessesByName("Gamename")
If p.Length > 0 Then
For i As Integer = 0 To p.Length - 1
GameID = (p(i).Id)
Next
End If
AutoSaveTimer.Enabled = True
Dim Test As Integer = 0
GetAsyncKeyState(Test)
AppActivate("GameName")
My.Computer.Keyboard.SendKeys(";", True)
now i've tried Sendkeys.Send(";") but without luck, and the game runs under "GameName" but then the keypress needs to be sent in a window under the game :
Blacked out is the game and under the first window is where the keypress needs to be sent
thanks in advance for the help
I use InputSimulator in my app and it works great.
https://inputsimulator.codeplex.com/
It could be this easy to send keys. The active window will see that as if the user actually used those keys.
var sim = new InputSimulator();
sim.Keyboard.KeyPress(VirtualKeyCode.SPACE);
sim = null;
Here's a screen shot of the methods you can use for keyboard.
You can simulate keyboard input to a program like this:
<DllImport("user32.dll")> _
Public Shared Function SetForegroundWindow(hWnd As IntPtr) As Boolean
End Function
Public Sub Send()
Dim p As System.Diagnostics.Process() = System.Diagnostics.Process.GetProcessesByName("notepad")
'search for process notepad
If p.Length > 0 Then
'check if window was found
'bring notepad to foreground
SetForegroundWindow(p(0).MainWindowHandle)
End If
SendKeys.SendWait("a")
'send key "a" to notepad
End Sub