Hello Olaf.
I am using this excellent option of using webview2 with vb6, I have managed to make functions to interact with the elements of some websites, but I found a problem that I have been struggling with for days, this is when simulating the click() event in an Input of type File, it simply does not open the file chooser dialog, when opening devtools the following alert can be displayed "File chooser dialog can only be shown with a user activation", I understand that this is a security block, but I want to know if There is the option to bypass that restriction.
I have managed to make functions to interact with the elements of some websites, but I found a problem that I have been struggling with for days, this is when simulating the click() event in an Input of type File, it simply does not open the file chooser dialog, when opening devtools the following alert can be displayed "File chooser dialog can only be shown with a user activation"
I understand that this is a security block...
Then don't fight it (within the Browser-Control)...
The nice thing about these "Dual-Apps" is, that you can always choose the side more suited for the task -
so why not show a modal FileOpen-Dialog via VB6-code?
Then don't fight it (within the Browser-Control)...
The nice thing about these "Dual-Apps" is, that you can always choose the side more suited for the task -
so why not show a modal FileOpen-Dialog via VB6-code?
Olaf
Using the vb6 FileOpen-Dialog would not allow assigning the path of the selected file in the file type input, since I am trying to upload a file to a website.
If I'm wrong, I would appreciate if you could guide me on it.
The way I handle resizing is to set the form font to the control font and then use TextWidth with the text to determine the width and then size the control to whatever number it gives me back plus a little buffer.
It only works on one-liners though - like labels and single-line textboxes. I've never tried it with multiline textboxes.
I use it for all controls (that are one-lines) that I want to resize at run-time such as labels, check and optionboxes and single-line text boxes.
Code:
Private Function ResizeCheckBox(ByRef Check As Control, ByRef Form As Form, Optional ByRef Padding As Long = 0) As Long
Dim nWidth As Long
' Returns CheckBox width.
On Error GoTo errHandler
CopyFontFromControl Check, Form
nWidth = Form.TextWidth(Check.Caption)
nWidth = nWidth + CHECKBOX_PADDING + Padding
Check.Width = nWidth
ResizeCheckBox = nWidth
Exit Function
errHandler:
Dim nErrorNumber As Long
Dim nErrorHandlerResult As Long
Dim sError As String
Dim nErr As Long
Dim Parameters(1) As String
sError = Error
nErrorNumber = Err
Parameters(0) = "Check.Name = " & Check.NAME
Parameters(1) = "Check.Parent.Name = " & Check.Parent.NAME
nErrorHandlerResult = ErrorHandler(sError, nErrorNumber, ParameterString(Parameters), NAME & ".ResizeCheckBox(Private Function)")
Resume CleanUp
End Function
Public Function CopyFontFromControl(ByRef FromControl As Object, ByRef ToControl As Object) As Long
' Returns Error Code.
On Error GoTo errHandler
With ToControl.Font
.Bold = FromControl.Font.Bold
.Charset = FromControl.Font.Charset
.Italic = FromControl.Font.Italic
.NAME = FromControl.Font.NAME
.Size = FromControl.Font.Size
.Strikethrough = FromControl.Font.Strikethrough
.Underline = FromControl.Font.Underline
.Weight = FromControl.Font.Weight
End With
Exit Function
errHandler:
Dim nErrorNumber As Long
Dim nErrorHandlerResult As Long
Dim sError As String
Dim Parameters(1) As String
CopyFontFromControl = Err
nErrorNumber = Err
sError = Error
Parameters(0) = "FromControl.Name = " & FromControl.NAME
Parameters(1) = "ToControl.Name = " & ToControl.NAME
nErrorHandlerResult = ErrorHandler(sError, nErrorNumber, ParameterString(Parameters), NAME & ".CopyFontFromControl(Public Function)")
End Function
(From dm)
.....but the problem is that if a commercial software can only run in a Windows environment, its market demand and market share will be very low. Such softwares cannot form a solid software ecological chain, nor can they provide you with more resources.
Not quite true. Even in 2024 - some 4 years after this post - MS Windows still dominates the desktop, especially in productivity applications. And yes, there is still a smaller-than-in-the-past but re-growing market for desktop apps on Windows. Windows has always had - and likely always will - far more available software for most any conceivable desktop purpose then MAC OS and Linux combined. And I don't even want to go down the Linux mess rabbit hole - WAY too many "Distros", WAY to much incompatibility among them etc. so Linux is best left where it shines most - the server side.
One can still build, sell and maintain good quality commercial 32-bit desktop apps with VB6. I've done it not so long ago and I plan to again. My users/customers can't tell/don't know/don't care what language their tools are written in.
And now, with twinBasic up-and-coming, it's only going to get better!
(From dm)
.....but the problem is that if a commercial software can only run in a Windows environment, its market demand and market share will be very low. Such softwares cannot form a solid software ecological chain, nor can they provide you with more resources......
\
Not quite true. Even in 2024 - some 3.5 years after this post, MS Windows still dominates the desktop, especially for productivity apps. There is still a smaller-than-before but re-growing market for commercial desktop applications. Windows has always had and likely always will have a much, much wider selection of available software than MAC OS & Linux combined. And the Linux desktop mess only makes it worse i.e. WAY to many "Distros", WAY too many incompatibilities between them, endless searches for needed dependencies, etc.
One can still create, use and sell good quality commercial software with VB6. I've done it not so long ago and I plan to again. Some on this forum have also and still are.The core VB6 runtime will be supported until at least 2031 and likely beyond.
My users/customers/groupies can't tell/don't know/don't care what programming language their tools are written in. They just fire 'em up and away they go.
And with twinBasic on the playing field, its just gonna get even better .
Last edited by SomeYguy; Apr 24th, 2024 at 08:53 PM.
can you please expose webview.defaultbackgroundcolor or show me how to access it in RC6 / WV2?
Here is what I can do with WV in .NET and which I can not do with RC6 yet:
Code:
Private Async Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim View As New WebView2()
Me.Controls.Add(View)
View.Dock = DockStyle.Fill
Me.WindowState = FormWindowState.Maximized
View.DefaultBackgroundColor = Color.Transparent
View.BringToFront()
Dim exeDirectory As String = Path.GetDirectoryName(Application.ExecutablePath)
View.Source = New Uri(Path.Combine(exeDirectory, "cssanimation.html"))
Me.FormBorderStyle = FormBorderStyle.None
Me.AllowTransparency = True
Me.BackColor = Color.Red
Me.TransparencyKey = Color.Red
Await View.EnsureCoreWebView2Async()
End Sub
This makes the browser transparent.
Or is there a way to set the defaultbackcolor any different way?
I need to have a transparent browser. This will enable me to display the browser like a screen overlay.
Currently I can not do this as this property is not exposed in the wrapper.
Thank you.
Also, I would like to point out that simply settings transparency like this...
I want to subclass the wv2 window.
I want to make it transparent, but I still the mouse move events, but it should also pass the window mesages on.
What I did was to make me the hosting window layered and then I used subclassing.
I received all the windows messages, and ignored the mouse clicks on the form, and I used the mouse move events as the browser required these in this case, but I also passed these on.
However, this did not work as the hostHwnd is not what is required to subclass the messages that the browser receives I think.
If anybody knows how to handle such a task, please let me know.
Thank you.
Last edited by tmighty2; May 21st, 2024 at 02:50 PM.
Hello Olaf,
In addition to extension management, would it be possible to integrate the asynchronous functions PrintAsync and PrintToPdfAsync into the cWebView2 component of the upcoming RC6 version?
Simply integrating these functions (without defining CoreWebView2PrintSettings) would allow for the automation of certain printing tasks.
I have compiled your demo (WebView2Demo.zip) using the VB6 UI running on Win XP in order to test the exe on Win 10 and 11. It appears to be working correctly but in order to create the exe I had to rem out two of your event handlers which both generate the same error:
Procedure declaration does not match description of event or procedure having the same name
'Private Sub WV_AcceleratorKeyPressed(ByVal KeyState As eWebView2AccKeyState, ByVal IsExtendedKey As Long, ByVal WasKeyDown As Long, ByVal IsKeyReleased As Long, ByVal IsMenuKeyDown As Long, ByVal RepeatCount As Long, ByVal ScanCode As Long, IsHandled As Long)
'Debug.Print "WV_AcceleratorKeyPressed"
'End Sub
'Private Sub WV_NavigationCompleted(ByVal IsSuccess As Long, ByVal WebErrorStatus As Long)
'Debug.Print "WV_NavigationCompleted"
'End Sub
Do you know what is wrong here and also does your comment ['*** the rest of the EventHandlers below, are raised by the WebView-instance itself] mean that they are not needed anyway?
... I had to rem out two of your event handlers which both generate the same error:
Procedure declaration does not match description of event or procedure having the same name
Have redefined the Interface since writing the demo... (e.g. in the two events - some of the Long-Param-Flags are now Booleans) -
just re-select (after commenting out) these EventHandlers from the DropDown-Combobox again for correct Param-population...
Originally Posted by misar
Do you know what is wrong here and also does your comment ['*** the rest of the EventHandlers below, are raised by the WebView-instance itself] mean that they are not needed anyway?
As with most Events - some of them are needed, some of them are left untouched...
Which sub-set of them ends up being used, depends on the concrete scenario at hand...
If anyone else has the same problem these are the corrected routines.
Private Sub WV_AcceleratorKeyPressed(ByVal KeyState As RC6.eWebView2AccKeyState, ByVal IsExtendedKey As Boolean, ByVal WasKeyDown As Boolean, ByVal IsKeyReleased As Boolean, ByVal IsMenuKeyDown As Boolean, ByVal RepeatCount As Long, ByVal ScanCode As Long, IsHandled As Boolean)
Debug.Print "WV_AcceleratorKeyPressed"
End Sub
Private Sub WV_NavigationCompleted(ByVal IsSuccess As Boolean, ByVal WebErrorStatus As Long)
Debug.Print "WV_NavigationCompleted"
End Sub
I have a quick question. In some old VB6 projects I used AutoComplete to connect a textbox with the history of IE. Is this also possible with WebView2 and if so how.
Old VB6 Code:
On the Form
Code:
Function EnableAutoComplete(hwnd As Long, dwFlags As Long) As Boolean
On Error GoTo Err1
SHAutoComplete hwnd, dwFlags
EnableAutoComplete = True
Exit Function
Err1:
EnableAutoComplete = False
End Function
Modul
Code:
Option Explicit
Public Declare Function SHAutoComplete Lib "shlwapi" (ByVal hwnd As Long, ByVal dwFlags As Long) As Long
'API constants
Public lngRet As Long
' // Currently (SHACF_FILESYSTEM | SHACF_URLALL)
Public Const SHACF_DEFAULT = &H0
' // This includes the File System as well as the rest of the shell (Desktop\My Computer\Control Panel\)
Public Const SHACF_FILESYSTEM = &H1
' // URLs in the User's History
Public Const SHACF_URLHISTORY = &H2
' // URLs in the User's Recently Used list.
Public Const SHACF_URLMRU = &H4
' // URLs in the User's Recently Used list.
Public Const SHACF_USETAB = &H8
' // Don't AutoComplete non-File System items.
Public Const SHACF_FILESYS_ONLY = &H10
Public Const SHACF_URLALL = (SHACF_URLHISTORY Or SHACF_URLMRU)
' // Ignore the registry default and force the feature on.
Public Const SHACF_AUTOSUGGEST_FORCE_ON = &H10000000
' // Ignore the registry default and force the feature off.
Public Const SHACF_AUTOSUGGEST_FORCE_OFF = &H20000000
' // Ignore the registry default and force the feature on.
' (Also know as AutoComplete)
Public Const SHACF_AUTOAPPEND_FORCE_ON = &H40000000
' // Ignore the registry default and force the feature off.
' (Also know as AutoComplete)
Public Const SHACF_AUTOAPPEND_FORCE_OFF = &H80000000
Many thanks in advance.
Andreas
Last edited by EasyOneX; Nov 14th, 2024 at 09:58 AM.
Thanks again for the WebView2 control. This has really given new life to an old VB6 app (and developer
I have a use for InPrivate mode or Incognito mode. I was wondering if there is an easy way to turn this on? My app logs into the same site multiple times with different credentials, and I have found that I have to make it logout/login for it to switch between them. I want to split this into 2 WVs and separately login to each.
Hello Olaf,
Since I last posted I have used the WebView2 control very successfully to display web pages in my programs. I would now like to extend that to extracting the html content of a page (to a variable or save to file) after it has displayed. This is required with pages that use code to generate their content from a database (eg an Amazon S3 bucket). I assume it requires a script but could not work out how to do it from the examples in the demo. Is it possible and could you give me an example?
Thanks
Update:
I already had the solution I need:
Code:
WV.jsProp("document.body.outerText")
but forgot that with a large amount of content the page needs a long time to complete!
1. try using .jsProp("document.documentElement.innerHTML") - i do this all the time to pull out information i need from web pages. you just need to make sure that the document is "settled" and fully loaded.
2. you actually replied to *my* post (just above) that asks about implementing "incognito" mode. I believe you should Reply to the very first post, so that Olaf is alerted.
WV.jsProp("document.body.outerText") is sufficient for my present need (I just want to search the page content for specific text) but your suggestion is useful for future reference. It is easy to find lists of the DOM components but I have never come across clear descriptions distinguishing the specific data captured with different permutations. Hence I resort to trial and error to extract what I need!
I am working with a website (https://bus.data.tfl.gov.uk/) which generates a file list from the contents of a large Amazon S3 data bucket. There is a substantial delay between the navigation completing and completion of the document that I want to capture. I thought that using Sub WV_DocumentComplete in Olaf's demo would deal with this but it fires immediately after Sub WV_NavigationCompleted. Is there a way to detect the true document completion? At present I work around this with a loop which checks the document size until it remains constant.
I am working with a website (https://bus.data.tfl.gov.uk/) which generates a file list from the contents of a large Amazon S3 data bucket. There is a substantial delay between the navigation completing and completion of the document that I want to capture. I thought that using Sub WV_DocumentComplete in Olaf's demo would deal with this but it fires immediately after Sub WV_NavigationCompleted. Is there a way to detect the true document completion? At present I work around this with a loop which checks the document size until it remains constant.
I tested and the event that keeps firing is WV_WebResourceResponseReceived.
Maybe you could check when that event stops firing.
I tested and the event that keeps firing is WV_WebResourceResponseReceived.
Maybe you could check when that event stops firing.
What are the correct parameters?
Code:
WV_WebResourceResponseReceived(ByVal ReqURI As String, ByVal ReqMethod As String, ByVal RespStatus As Long, ByVal RespReasonPhrase As String, ByVal RespHeaders As RC6.cCollection)
It must start with "Private Sub".
The control adds the correct code automatically (I have no idea what you did).
I started it with "Private Sub". The compiler throws an incorrect parameter error. I assumed this routine posted earlier in the thread had the correct parameters:
Code:
Private Sub WV_WebResourceResponseReceived(ByVal ReqURI As String, ByVal ReqMethod As String, ByVal RespStatus As Long, ByVal RespReasonPhrase As String, ByVal RespHeaders As RC6.cCollection)
On Error Resume Next
Text2.Text = Text2.Text & RespHeaders & vbNewLine
End Sub
I have it working in one project, and it is the same:
Code:
Private Sub WV_WebResourceResponseReceived(ByVal ReqURI As String, ByVal ReqMethod As String, ByVal RespStatus As Long, ByVal RespReasonPhrase As String, ByVal RespHeaders As RC6.cCollection)
' (code)
End Sub
I'm using RC6 version 6.0.0.15 with the code from Olaf's demo. Apart from WV_WebResourceResponseReceived everything is compiling correctly.
The version history says:
version 6.0.0.15
- cWebView2: now using *App-specific* UserData-Folders, in case the UserData-Param was left out in the Bind-Method
- cSimplePSD: a bit of hardening, to properly cooperate with a "wider range of PSD-Files"
- RC6Widgets got a new cwAlphaImg Widget
Your example also works for me. The difference was the line Static c As Long
- I added that to the routine and now my code also compiles and runs correctly.
Many thanks for your help.
Edit
After looking at this more carefully I realised that the line "Static c As Long" is irrelevant to my code so I deleted it
- and of course the routine still worked OK.
I cannot understand what changed as previously I made several attempts to get apparently identical code to work.
Thanks again for the WebView2 control. This has really given new life to an old VB6 app (and developer
I have a use for InPrivate mode or Incognito mode. I was wondering if there is an easy way to turn this on? My app logs into the same site multiple times with different credentials, and I have found that I have to make it logout/login for it to switch between them. I want to split this into 2 WVs and separately login to each.
Just bumping this... hopefully someone else has a need for this also. Before i posted before, and again just now, I tried passing different options for the parameter additionalBrowserArguments. I tried:
Just bumping this... hopefully someone else has a need for this also. Before i posted before, and again just now, I tried passing different options for the parameter additionalBrowserArguments. I tried:
None of which appear to do the job, even though no complaints from the New_c.WebView2 call.
Any pointers would be great.
Thanks!
Have you tried using a different user data folder for each instance? You can then delete the "incognito" user folder on shutdown yourself. This approach is mentioned at the following links, but I haven't tried it myself:
Have you tried using a different user data folder for each instance? You can then delete the "incognito" user folder on shutdown yourself. This approach is mentioned at the following links, but I haven't tried it myself:
this is how i work to create a private browsing mode !
Code:
Option Explicit
Private WithEvents WV As cWebView2
....
'when loading the container
Set WV = New_C.WebView2 'create the instance
Load picWV(1)
picWV(1).Visible = True
....
If mPrivate = True Then
DataEdgePath = AddDirSep(Environ("TEMP")) & "MyAppName\" & CreateGUIDString(True) 'The navigation is in private mode and begins in a directory free of any data which will be destroyed at the end of navigation
Else
DataEdgePath = fGetSpecialFolderLocation(CSIDL_COMMON_APPDATA) & "\"MyAppName\Data\" & Environ$("Username")
End If
MD DataEdgePath
.....
WV.BindTo picWV(1).hWnd, m_InitTimeOut, , DataEdgePath, TmpLang, mAllowSingleSignOnUsingOSPrimaryAccount
.....
'before unloading the container
Set WV = Nothing
Unload picWV(1)
If mPrivate = True Then KillFiles DataEdgePath, True
....
Private Sub MD(DirPath As String)
If InStr(DirPath, "\") > 0 Then
DirPath = AddDirSep(DirPath)
On Error Resume Next
Dim strTmp$(), f%, StrPath$
strTmp$ = Split(DirPath, "\")
For f% = 0 To UBound(strTmp()) - 1
StrPath$ = StrPath$ & strTmp(f) & "\"
MkDir StrPath
Next f%
Else
MkDir DirPath
End If
End Sub
Private Function AddDirSep(strPathName As String) As String
If strPathName = "" Then Exit Function
strPathName = RTrim$(strPathName)
If Right$(strPathName, 1) <> "\" Then
strPathName = strPathName & "\"
End If
AddDirSep = strPathName
End Function
........................................................................
CreateGUIDString(True) return an unique GUID
KillFiles delete all Folder,subFoldes and Files
fGetSpecialFolderLocation retrieve specials Folders Paths
...see VBForums CodeBank...
I have been using your product for a long time without problems.
I have been loading Facebook page into WV and getting the body.innerhtml without any problem. Now, when I try to get the body.innerhtml, empty string is returned. I am waiting to get the html, but nothing returned. The code is as follows:
Code:
WVerrorflag = False
WV.Navigate "about:blank"
WV.Navigate cururl$
If WVerrorstatus <> 0 Or WV.DocumentURL = "chrome-error://chromewebdata/" Then
Stop
Else
retcount = 0
Do
retcount = retcount + 1
If retcount > 2 Then Stop
curhtml$ = WV.jsProp("document.body.innerHTML")
If curhtml$ <> "" Then Exit Do
Wait 1
Loop
End If
Is there a way to get the html from Facebook page?
this is how i work to create a private browsing mode !
Appreciate you guys putting me on the right path! It appears that using a different User Data Folder on each call *does* do the trick, so that the WV's run in separate folders. The unfortunate "side effect" is that it doesn't remember some of the user's default or previous selections, but the ability to run multiple separate instances far outweighs the inconvenience.
Thanks!!
Now, if I could just figure out how to keep/fix the ZoomFactor, I would be golden... if I hold control and roll the mouse to zoom in/out on a website, then go to a different place on the same site, the zoom resets.
Appreciate you guys putting me on the right path! It appears that using a different User Data Folder on each call *does* do the trick, so that the WV's run in separate folders.
I was just looking at the WebView2 browser flags/params for another purpose and notice that there is a "--incognito" flag (maybe it is new?):
Code:
incognito Forces Incognito mode even if user data directory is specified by using the --user-data-dir flag.
Might be worth trying that to see if it keeps all of the user's existing settings but doesn't save/overwrite anything during/after the session.
Now, if I could just figure out how to keep/fix the ZoomFactor, I would be golden... if I hold control and roll the mouse to zoom in/out on a website, then go to a different place on the same site, the zoom resets.
Regarding the zoom factor, it looks like others have reported the same problem:
None of these worked for me. These are all from scouring the Internet trying to make this happen. Perhaps my formatting is off for passing in these parameters.
After digging into the 2nd link, it appears that I can now keep the same Zoom Factor between navigations (programmatically anyway):
Code:
dim ZoomFactor as double
...
' Before navigating to another page/site, save current ZF
ZoomFactor=WV.ZoomFactor
WV.ZoomFactor = ZoomFactor + .001
'navigate to site here
...
WV.ZoomFactor = ZoomFactor
I tried something similar before, but I think it needs a value that is *different* than what it currently is, in order to actually do anything. So bumping it by a little, navigating, and bumping it back by a little actually makes the WV respond.