Put browser window in foreground #16
Replies: 7 comments 2 replies
-
Yeah I've noticed that sometimes (not always) I experience the window problem too. I'd be open to consider it if you can find a relatively clean solution. I will give a solution some thought as well. Incidentally, I am ready to publish your previously submitted changes along with mine. Should I do that now, or wait for more from you? If the latter, please keep detailed track of any more proposed changes. Thanks! |
Beta Was this translation helpful? Give feedback.
-
There are two methods called "GetWindowHandles" and "GetCurrentWindowHandle" that may be of use... Also, there is the excel native method Application.Hwnd in case you want to take the approach of changing the disposition of the Excel window. |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9 , I think I have a solution that will send the Visual Basic IDE and the Excel windows to the background (bottom of the z-order). So I'm thinking of adding a method to the WebDriver class called "SendExcelToBack" or something like that. If it that works reliably after some testing period, then we can consider building it into the OpenBrowser method. Private Declare PtrSafe Function SetWindowPos Lib "user32" _
(ByVal hWnd As LongPtr, ByVal hwndInsertAfter As LongPtr, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As LongPtr) As Long
Const SWP_NOSIZE = &H1
Const SWP_NOMOVE = &H2
Const SWP_NOACTIVATE = &H10
Const HWND_TOPMOST = -1
Const HWND_NOTOPMOST = -2
Const HWND_BOTTOM = 1
Const HWND_TOP = 0
Sub SendExcelToBack()
Dim hWnd As LongPtr, lngRet As Long
Dim strText As String, partialName As String
'first send all VBA IDE windows to background
partialName = "Microsoft Visual Basic for Applications"
hWnd = FindWindowEx(0&, 0&, vbNullString, vbNullString)
While hWnd <> 0
strText = String$(200, Chr$(0))
lngRet = GetWindowText(hWnd, strText, 200)
If InStr(1, strText, partialName, vbTextCompare) > 0 Then
Call SetWindowPos(hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOACTIVATE)
End If
'find next window
hWnd = FindWindowEx(0&, hWnd, vbNullString, vbNullString)
Wend
'now send Excel window to background
Call SetWindowPos(Application.hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOACTIVATE)
End Sub Would that work for you? |
Beta Was this translation helpful? Give feedback.
-
Interesting approach. I'm currently using a temporary fast solution sending the Edge/Chrome window to TOPMOST finding it with a simple Just a (big) worry: can we find a reliable way to restore the Z order of the Excel/VBE window when the executions terminate with a Reset or an unhandled error (where the Class_Terminate doesn't trigger)? Oh by the way, do you have a procedure to manually completely "clean" the environment (at least the WebDriver executable) after a Reset or an unhandled error? and/or, is there in your current code a cleaner routine executed each time just before opening a new session? |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9, I could not reproduce the issue of the browser in the background behind the other previously open windows, even though I recall it has happened to me before. So the problem is intermittent for me, and seems to mostly not be a problem. Does it happen to you always? I agree that sending the browser window to the foreground sounds like a more direct solution - remember though that there can be more than one automated browser windows opened at the same time. Because I could not reproduce the issue yesterday to fully test what happens when user has opened more than one windows, I thought it might be safer to go the other way. Share your solution so that I can do some testing with it. On the cleaning of the environment after an unhandled error: I have not run into a problem with Edge and Chrome as those webdrivers seem to support multi-sessions on the same port without interference so as long as your code eventually runs through a "ShutDown", things should clean up. The native webdriver "Shutdown" kills all open sessions and child windows for Chrome and Edge on the port that was used to start the driver. Firefox is different however in that it does not support multiple sessions on same port. So with that one I call a routine KillDriver in the StartFirefox method that cleans up all previously stranded webdrivers and child windows on the port being used. When I publish the updated version today you will see what I'm doing with that. I have not had a need to do same with Chrome and Edge and so have left the job to "ShutDown" for those. But I'm certainly open to doing same for Edge/Chrome if there is a need for that. All three drivers do support multi-sessions if on different ports, so one has to be careful not to indiscriminately kill webdrivers if that functionality is to be preserved. I will publish the new version later today. Thanks for your help... |
Beta Was this translation helpful? Give feedback.
-
Ok I isolated the cause of my SeleniumVBA browser window always going behind Excel:
|
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9 - I can reproduce. My SendExcelToBack works to get the Excel app out of the way but obviously puts your form behind the browser too. I'm not sure if that is what you want. If you come up with a better solution let me know... I published version 1.5 with your excellent suggestions and the planned updates since the last version. We can try using PR's going forward but given that the "actual" code sits in an xlsm file, it might be easier (especially for me) to collaborate via Issues and Discussion entries as we have been doing. But I'm game either way. Thanks again! |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi
I'm looking for a method to bring the browser window in foreground, always on top over the Excel and VBE and all other windows, during the execution of code. I don't find it in the published library yet.
Do you already have a procedure for this?
I'd use the FindWindowA and SetWindowPos user32 API functions.
I'm now researching a bit for the most reliable way to find the hWnd of the browser window, maybe something like this: https://stackoverflow.com/a/39402106/11738627
What do you think?
Not sure if you'll be interested in adding a method related to this to the WebDriver class though.
Beta Was this translation helpful? Give feedback.
All reactions