VB.Net - How to get new window URL in GeckoFX60 - vb.net

How can i get url from new opened window in GeckoFX60
C# code:
void wb1_CreateWindow2(object sender, GeckoCreateWindow2EventArgs e)
{
e.Cancel = true;
e.WebBrowser.Navigate(e.Uri);
}
but i can't find e.Uri in vb.net
i tried e.WebBrowser.Url.AbsoluteUri but it always null
this is what i tried in vb.net
Private Sub GeckoWebBrowser1_CreateWindow(sender As Object, e As Gecko.GeckoCreateWindowEventArgs) Handles GeckoWebBrowser1.CreateWindow
Try
e.Cancel = True
Console.WriteLine(e.WebBrowser.Url.AbsoluteUri)
Catch ex As Exception
End Try
End Sub

In GeckoFX 60.x on the CreateWindow event of the GeckoWebBrowser there is no Uri property on the e GeckoCreateWindowEventArgs object.
To get the URL create a new instance of GeckoBrowser, then you get the URL in Navigating event
Here's some sample code from a related thread on the GeckoFX forum:
Private Sub Gecko_CreateWindow(sender As Object, e As GeckoCreateWindowEventArgs) Handles Gecko.CreateWindow
'Create new form & initialise the browser
Dim Frm As New GeckoFrm
Dim h = Frm.Gecko.Handle
'Keep flags for use in Navigating event
If e.Flags = GeckoWindowFlags.All Then
Frm.Gecko.SetContextFlagsAttribute(ContextFlags.Tab)
Else
Frm.Gecko.SetContextFlagsAttribute(ContextFlags.Popup)
End If
'Pass back the browser
e.WebBrowser = Frm.Gecko
End Sub
Private Sub Gecko_Navigating(sender As Object, e As GeckoNavigatingEventArgs) Handles Gecko.Navigating
If Gecko.GetContextFlagsAttribute And ContextFlags.Tab Then
'Navigate existing or open tab
NavigateTab(e.Uri.ToString)
ElseIf Gecko.GetContextFlagsAttribute And ContextFlags.Popup Then
If BlockPopup()
e.Cancel = True
Return
Else
'navigate existing or open popup
NavigatePopup(e.Uri.ToString)
End If
Else
'Not a popup, just show
Show()
End If
'Clear the popup/tab flags
Gecko.SetContextFlagsAttribute(0)
End Sub

Related

Folder Browser Replacement

I want to be able to add multiple download links and for them to go into a single folder which is selected by the user in a Folder Browser Dialog
The code you see below works great except only for a single file. I have tried changing all 'savefiledialog1' to 'folderbrowserdialog1' instead. However this leads to me clicking download and nothing happening even if only a single link is entered.
Private Sub BtnBrowse_Click(sender As Object, e As EventArgs) Handles btnBrowse.Click
If (SaveFileDialog1.ShowDialog() = DialogResult.OK) Then
txtSave1.Text = SaveFileDialog1.FileName
btnDownload.Enabled = True
End If
End Sub
' ------------ DOWNLOADING SECTION ------------
Private WithEvents HTTPCLIENT As WebClient
Private Sub BtnDownload_Click(sender As Object, e As EventArgs) Handles
btnDownload.Click
btnDownload.Enabled = False
txtSave1.Enabled = False
btnBrowse.Enabled = False
btnDownload.Enabled = False
HTTPCLIENT = New WebClient
Dim Download As String
Download = Links(i)
Dim User = Environment.UserName
Dim Save As String = txtSave1.Text
Try
HTTPCLIENT.DownloadFileAsync(New Uri(Download), Save)
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub
I expected the folder browser dialog to just be a general save path where the file being downloaded is placed into that folder, however I am given an error.
The code above works but only for a single file.
I have code that can retrieve the download name and extension which I plan to add to the path once i figure this part out.
You can use the FolderBrowserDialog. Once you get the path, you combine it with each filename you will download. Use System.IO.Path.Combine()
Private Sub BtnBrowse_Click(sender As Object, e As EventArgs) Handles btnBrowse.Click
Using fbd As New FolderBrowserDialog()
If fbd.ShowDialog() = DialogResult.OK Then
txtSave1.Text = fbd.SelectedPath
btnDownload.Enabled = True
End If
End Using
End Sub
Private Sub BtnDownload_Click(sender As Object, e As EventArgs) Handles btnDownload.Click
Try
btnDownload.Enabled = False
txtSave1.Enabled = False
btnBrowse.Enabled = False
btnDownload.Enabled = False
Dim exceptionMessages As New List(Of String)
Using client = New WebClient()
' configure client here as needed i.e. add Credentials
For Each link In Links
Try
client.DownloadFileAsync(New Uri(link), Path.Combine(txtSave1.Text, link))
Catch ex As Exception
exceptionMessages.Add(ex.Message)
End Try
Next
End Using
If exceptionMessages.Any() Then MessageBox.Show($"Exception{If(exceptionMessages.Count > 1, "s", "")}: {String.Join(Environment.NewLine, exceptionMessages)}")
Finally
txtSave1.Enabled = True
btnBrowse.Enabled = True
btnDownload.Enabled = True
End Try
End Sub
Note that I will not post an answer with IDisposable objects without Using (in most cases) so FolderBrowserDialog and WebClient are both in Usings. You may need to add additional configuration to the WebClient before downloading.
Also, you probably don't want a separate message for each Exception, if any. So the messages can be cached and shown all at once.
I inserted a Finally for you to set control states back to default when done. This is up to you.
Lastly, the work is being done on a UI thread as evidenced by it being one inside the button click handler. You should move it off the UI even though you aren't blocking. This is outside the scope of the question.

Download Image under the Mouse pointer via WebBrowser

I'm navigating to Google Images using a WebBrowser control. The aim is to be able to right click on any image and download and populate a PictureBox background.
I have my own ContextMenuStrip with Copy on it and have disabled the built in context menu.
The issue I am having is that the coordinate returned from CurrentDocument.MouseMove are always relative to the first (top left) image.
So my code works correctly if the Image I want is the very first image on the page, however clicking on any other Images always returns the coordinates of the first image.
It would appear that the coordinates are relative to each Image rather than the page.
Private WithEvents CurrentDocument As HtmlDocument
Dim MousePoint As Point
Dim Ele As HtmlElement
Private Sub Google_covers_Load(sender As Object, e As EventArgs) Handles MyBase.Load
WebBrowser1.IsWebBrowserContextMenuEnabled = False
WebBrowser1.ContextMenuStrip = ContextMenuStrip1
End Sub
Private Sub WebBrowser1_Navigated(sender As Object, e As WebBrowserNavigatedEventArgs) Handles WebBrowser1.Navigated
CurrentDocument = WebBrowser1.Document
End Sub
Private Sub CurrentDocument_MouseMove(sender As Object, e As HtmlElementEventArgs) Handles CurrentDocument.MouseMove
MousePoint = New Point(e.MousePosition.X, e.MousePosition.Y)
Me.Text = e.MousePosition.X & " | " & e.MousePosition.Y
End Sub
Private Sub ContextMenuStrip1_Opening(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles ContextMenuStrip1.Opening
Ele = CurrentDocument.GetElementFromPoint(MousePoint)
If Ele.TagName = "IMG" Then
CopyToolStripMenuItem.Visible = True
Else
CopyToolStripMenuItem.Visible = False
End If
End Sub
Private Sub CopyToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles CopyToolStripMenuItem.Click
Dim ToImg = Ele.GetAttribute("src")
mp3_row_edit.PictureBox1.BackgroundImage = New System.Drawing.Bitmap(New IO.MemoryStream(New System.Net.WebClient().DownloadData(ToImg)))
ToImg = Nothing
End Sub
This code allow to use a standard WebBrowser control to navigate to the Google Image search page and select/download an Image with a right-click of the Mouse.
To test it, drop a WebBrowser Control and a FlowLayoutPanel on a Form and navigate to a Google Image search page.
Things to know:
WebBrowser.DocumentCompleted: This event is raised each time one of the Sub-Documents inside a main HtmlDocument page is completed. Thus, it can be raised multiple times. We need to check whether the WebBrowser.ReadyState = WebBrowserReadyState.Complete.
Read these note about this: How to get an HtmlElement value inside Frames/IFrames?
The images in the Google search page can be inserted in the Document in 2 different manners: both using a Base64Encoded string and using the classic src=[URI] format. We need to be ready to get both.
The mouse click position can be espressed in either absolute or relative coordinates, referenced by the e.ClientMousePosition or e.OffsetMousePosition.
Read the notes about this feature here: Getting mouse click coordinates in a WebBrowser Document
The WebBrowser emulation mode can be important. We should use the most recent compatible mode available in the current machine.
Read this answer and apply the modifications needed to have the most recent Internet Explorer mode available: How can I get the WebBrowser control to show modern contents?.
Note that an event handler is wired up when the current Document is completed and is removed when the Browser navigates to another page. This prevents undesired calls to the DocumentCompleted event.
When the current Document is complete, clicking with the right button of the Mouse on an Image, creates a new PictureBox control that is added to a FlowLayouPanel for presentation.
The code in the Mouse click handler (Protected Sub OnHtmlDocumentClick()) detects whether the current image is a Base64Encoded string or an external source URI.
In the first case, it calls Convert.FromBase64String to convert the string into a Byte array, in the second case, it uses a WebClient class to download the Image as a Byte array.
In both cases, the array is then passed to another method (Private Function GetBitmapFromByteArray()) that returns an Image from the array, using Image.FromStream() and a MemoryStream initialized with the Byte array.
The code here is not performing null checks and similar fail-proof tests. It ought to, that's up to you.
Public Class frmBrowser
Private WebBrowserDocumentEventSet As Boolean = False
Private base64Pattern As String = "base64,"
Private Sub frmBrowser_Load(sender As Object, e As EventArgs) Handles MyBase.Load
WebBrowser1.ScriptErrorsSuppressed = True
WebBrowser1.IsWebBrowserContextMenuEnabled = False
End Sub
Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
If WebBrowser1.ReadyState = WebBrowserReadyState.Complete AndAlso WebBrowserDocumentEventSet = False Then
WebBrowserDocumentEventSet = True
AddHandler WebBrowser1.Document.MouseDown, AddressOf OnHtmlDocumentClick
End If
End Sub
Protected Sub OnHtmlDocumentClick(sender As Object, e As HtmlElementEventArgs)
Dim currentImage As Image = Nothing
If Not (e.MouseButtonsPressed = MouseButtons.Right) Then Return
Dim source As String = WebBrowser1.Document.GetElementFromPoint(e.ClientMousePosition).GetAttribute("src")
If source.Contains(base64Pattern) Then
Dim base64 As String = source.Substring(source.IndexOf(base64Pattern) + base64Pattern.Length)
currentImage = GetBitmapFromByteArray(Convert.FromBase64String(base64))
Else
Using wc As WebClient = New WebClient()
currentImage = GetBitmapFromByteArray(wc.DownloadData(source))
End Using
End If
Dim p As PictureBox = New PictureBox() With {
.Image = currentImage,
.Height = Math.Min(FlowLayoutPanel1.ClientRectangle.Height, FlowLayoutPanel1.ClientRectangle.Width)
.Width = .Height,
.SizeMode = PictureBoxSizeMode.Zoom
}
FlowLayoutPanel1.Controls.Add(p)
End Sub
Private Sub WebBrowser1_Navigating(sender As Object, e As WebBrowserNavigatingEventArgs) Handles WebBrowser1.Navigating
If WebBrowser1.Document IsNot Nothing Then
RemoveHandler WebBrowser1.Document.MouseDown, AddressOf OnHtmlDocumentClick
WebBrowserDocumentEventSet = False
End If
End Sub
Private Function GetBitmapFromByteArray(imageBytes As Byte()) As Image
Using ms As MemoryStream = New MemoryStream(imageBytes)
Return DirectCast(Image.FromStream(ms).Clone(), Image)
End Using
End Function
End Class

System.ObjectDisposedException when closing a form in vb.net

I am having a weird error and I am sure it is something very simple, but I can't for the life of me figure out what is going on. I thought I was opening and closing the forms properly, but it appears something is amiss. I am working with VS 2015. I have my program set to close when the last form is closed. There are two forms that I am using right now.
Dashboard
Public Class frmDashboard
Private Sub recExit_Click(sender As Object, e As EventArgs) Handles recExit.Click
Me.Close()
End Sub
Private Sub recMember_Click(sender As Object, e As EventArgs) Handles recMember.Click, lblMember.Click
'Create instance of Member Form
Dim memberForm As New frmMember
'Open an instance
memberForm.Show()
Me.Close()
'Using this code test if the form window is still open
For Each frm As Form In Application.OpenForms
MessageBox.Show(frm.Name)
Next
End Sub
End Class
Members Form
Public Class frmMember
Private Sub frmMember_Load(sender As Object, e As EventArgs) Handles Me.Load
ShowSpouse(rdoMarried.Checked)
End Sub
Private Sub ShowSpouse(ByRef isMarried As Boolean)
If isMarried Then
'Marital status is set to married lets show the extra spouse information
'Lets first make the form larger
Me.Size = New Size(793, 576)
'Now lets unhide the form
pnlSpouse.Visible = True
'pnlSpouse.Enabled = True
lblSpouse.Visible = True
'lblSpouse.Enabled = True
lineSpouse.Visible = True
'lineSpouse.Enabled = True
'Now lets move the buttons to their new location
btnApply.Location = New Point(624, 541)
btnExit.Location = New Point(710, 541)
Else
'Single is Selected
'Let's make sure all the spouse information is hidden
'Lets first make the form smaller
Me.Size = New Size(793, 358)
'Now lets hide the form and disable the controls
pnlSpouse.Visible = False
'pnlSpouse.Enabled = False
lblSpouse.Visible = False
'lblSpouse.Enabled = False
lineSpouse.Visible = False
'lineSpouse.Enabled = False
'Now lets move the buttons to their new location
btnApply.Location = New Point(624, 320)
btnExit.Location = New Point(710, 320)
End If
End Sub
Private Sub MaritalStatusChanged(sender As Object, e As EventArgs) Handles rdoSingle.CheckedChanged, rdoMarried.CheckedChanged
ShowSpouse(rdoMarried.Checked)
End Sub
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Dim dashboard As New frmDashboard
'Open the dashboard
dashboard.Show()
'Close the member form
Me.Close()
End Sub
End Class
I havent added the database to it but eventually I will load data into the members form. When I click to open the members form it goes through and runs the code in the form load event for members form but then returns focus back to the dashboard form. Runs the Me.Close on the dashboard, but once it gets to End Sub thats when this exception gets thrown:
System.ObjectDisposedException was unhandled
Message: An unhandled exception of type 'System.ObjectDisposedException' occurred in System.Windows.Forms.dll
Additional information: Cannot access a disposed object.
Any help you guys can give would be greatly appreciated.

Highlight scroll bar of textbox [duplicate]

Is it possible to show/hide the scroll bar in a text box only when the line count in the text box is more than the number of lines displayed?
Consider using the RichTextBox -- it has that behavior built in.
Thanks dummy, it works! Here short version of dummy answer in c#
Call this code at the end of your SizeChanged and TextChanged handlers:
Size textBoxRect = TextRenderer.MeasureText(
this.YourTextBox.Text,
this.YourTextBox.Font,
new Size(this.YourTextBox.Width, int.MaxValue),
TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl);
try
{
this.YourTextBox.ScrollBars = textBoxRect.Height > this.YourTextBox.Height ?
ScrollBars.Vertical :
ScrollBars.None;
} catch (System.ComponentModel.Win32Exception)
{
// this sometimes throws a "failure to create window handle" error.
// This might happen if the TextBox is unvisible and/or
// too small to display a toolbar.
}
Public Class TextBoxScrollbarPlugin
Private WithEvents mTarget As TextBox
''' <summary>
''' After the Handle is created, mTarget.IsHandleCreated always returns
''' TRUE, even after HandleDestroyed is fired.
''' </summary>
''' <remarks></remarks>
Private mIsHandleCreated As Boolean = False
Public Sub New(item As TextBox)
mTarget = item
mIsHandleCreated = mTarget.IsHandleCreated
End Sub
Private Sub Update()
If Not mTarget.IsHandleCreated Then
Return
ElseIf Not mIsHandleCreated Then
Return
End If
Dim textBoxRect = TextRenderer.MeasureText(mTarget.Text,
mTarget.Font,
New Size(mTarget.Width, Integer.MaxValue),
TextFormatFlags.WordBreak + TextFormatFlags.TextBoxControl)
Try
If textBoxRect.Height > mTarget.Height Then
mTarget.ScrollBars = ScrollBars.Vertical
Else
mTarget.ScrollBars = ScrollBars.None
End If
Catch ex As System.ComponentModel.Win32Exception
'this sometimes throws a "failure to create window handle"
'error.
'This might happen if the TextBox is unvisible and/or
'to small to display a toolbar.
If mLog.IsWarnEnabled Then mLog.Warn("Update()", ex)
End Try
End Sub
Private Sub mTarget_HandleCreated(sender As Object, e As System.EventArgs) Handles mTarget.HandleCreated
mIsHandleCreated = True
End Sub
Private Sub mTarget_HandleDestroyed(sender As Object, e As System.EventArgs) Handles mTarget.HandleDestroyed
mIsHandleCreated = False
End Sub
Private Sub mTarget_SizeChanged(sender As Object, e As System.EventArgs) Handles mTarget.SizeChanged
Update()
End Sub
Private Sub mTarget_TextChanged(sender As Object, e As System.EventArgs) Handles mTarget.TextChanged
Update()
End Sub
End Class
Private mPlugins As New List(Of Object)
Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
mPlugins.Add(New TextBoxScrollbarPlugin(txtBoxOne))
mPlugins.Add(New TextBoxScrollbarPlugin(txtBoxTwo))
mPlugins.Add(New TextBoxScrollbarPlugin(txtBoxThree))
End Sub
I've got tnimas solution working in vb. Functions quite well as written and I've not seen the errors.
Private Sub TextBoxSizeChanged(sender As Object, e As EventArgs) Handles Me.SizeChanged
Dim textBoxRect As Size = TextRenderer.MeasureText(TextBox.Text, TextBox.Font, New Size(TextBox.Width, Integer.MaxValue), TextFormatFlags.WordBreak Or TextFormatFlags.TextBoxControl)
Try
TextBox.ScrollBar = If(textBoxRect.Height > TextBox.Height, ScrollBars.Vertical, ScrollBars.None)
Catch ex As Exception
'handle error
End Try
End Sub
I myself tried tnimas' solution but unable to catch the exception, so I use the WinApi to toggle the visible state of scrollbars instead like so:
Size textBoxRect = TextRenderer.MeasureText(YourTextBox.Text, YourTextBox.Font, new Size(YourTextBox.Width, int.MaxValue), TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl);
WinApi.ShowScrollBar(YourTextBox.Handle, (int)WinApi.ScrollBar.SB_VERT, textBoxRect.Height > YourTextBox.Height ? true : false);
This method does not cause the exception, though should note that hiding scrollbars like this will disable scroll messages, but this is fine if you're just hiding the scrollbars for when the text area can't be scrolled anyway.

Bug on login form while trying to close the app vb.net

So currently I am using a code which provides me the possibility to manager whenever or not the application will logout or keep on track. Basically if the user is not using the program for quite some time it will move to the Login form and of course if the user wants to login back he had to type again.
I got a class where I am able to produce more or less that code:
Public Class TimerWatcher
Private _timer As System.Threading.Timer
Private _enabled As Boolean
Private _lastEvent As DateTime
Public Sub New()
_timer = New System.Threading.Timer(AddressOf watch)
_enabled = False
Timeout = 0
End Sub
Public Event Idle(sender As Form)
Public Property Timeout As Long
Public Property Enabled As Boolean
Get
Return _enabled
End Get
Set(value As Boolean)
If value Then
_lastEvent = DateTime.Now
_timer.Change(0, 1000)
Else
_timer.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite)
End If
End Set
End Property
Private Sub watch()
If DateTime.Now.Subtract(_lastEvent).TotalMilliseconds > Timeout Then
Enabled = False
' "End" is quite blunt. You may want to raise an event
' so the form can terminate the application gracefully.
RaiseEvent Idle(Login)
End If
End Sub
Public Sub Refresh()
_lastEvent = DateTime.Now
End Sub
End Class
And then on my main form I got this:
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
watcher.Timeout = 5000
watcher.Enabled = True
End Sub
Private Sub PaginaInicial_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
watcher.Refresh()
End Sub
Private Sub watcher_idle(sender As Form) Handles watcher.Idle
Dim logIN = New Login
If MsgBox("The application will close, are you sure you want to do it?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
logIN.Show()
Else
End If
End Sub
But, because some bug I am not able to return the Login form...And this is what happen to the form after I click yes on the MessageBox. The login form crash or something
Do you have any idea how I can solve this bug?