Closing form after printing a web browser control contained in it - vb.net

I'm taking some random print through the html and web browser control in vb.net winforms
Here is my code
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim myWebBrowser As New WebBrowser
AddHandler myWebBrowser.DocumentCompleted, AddressOf DocumentCompleted
myWebBrowser.Navigate("http://www.bing.com")
End Sub
Private Sub DocumentCompleted(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)
With DirectCast(sender, WebBrowser)
If .ReadyState = WebBrowserReadyState.Complete Then
.Print()
End If
End With
End Sub
End Class
I want the form to be closed after the print. Now if I write Me.Close() after .Print() nothing is being printed. what should I do to achieve this?
Any help is appreciated.
::Update::
after #Noseratio's suggestion I tried to handle the event onafterprint in my html and tried to invoke Me.Close() using ObjectFoprScripting set to my form. But that is firing the close method without any print.
Here is my code
script tag in my html page
<script>
function window.onafterprint() {
window.external.Test('called from script code');
}
</script>
VB.net Code of my form
Imports System.IO
Imports Microsoft.Win32
Imports System.Security.Permissions
<PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
<System.Runtime.InteropServices.ComVisibleAttribute(True)> _
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
WebBrowser1.AllowWebBrowserDrop = False
WebBrowser1.IsWebBrowserContextMenuEnabled = False
WebBrowser1.WebBrowserShortcutsEnabled = False
webBrowser1.ObjectForScripting = Me
WebBrowser1.DocumentText = File.ReadAllText("localprint.htm")
End Sub
Public Sub Test(ByVal message As String)
MessageBox.Show(message, "client code")
Me.BeginInvoke(DirectCast(Sub() Me.Close(), MethodInvoker))
End Sub
Private Sub WebBrowser1_DocumentCompleted(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
WebBrowser1.Print()
End Sub
End Class

Found my solution
No need to handle onafterprint in javascript.
Here is what I did,
Step 1
Added a reference to SHDocVw.dll in my project. This can be found in c:\windows\system32 folder.
Step2
My new updated code
Imports System.IO
Imports Microsoft.Win32
Imports System.Security.Permissions
<PermissionSet(SecurityAction.Demand, Name:="FullTrust")> _
<System.Runtime.InteropServices.ComVisibleAttribute(True)> _
Public Class Form1
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
WebBrowser1.AllowWebBrowserDrop = False
WebBrowser1.IsWebBrowserContextMenuEnabled = False
WebBrowser1.WebBrowserShortcutsEnabled = False
WebBrowser1.DocumentText = File.ReadAllText("localprint.htm")
End Sub
Private Sub WebBrowser1_DocumentCompleted_1(sender As System.Object, e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
Dim wb As WebBrowser = TryCast(sender, WebBrowser)
Dim ie As SHDocVw.InternetExplorer = DirectCast(wb.ActiveXInstance, SHDocVw.InternetExplorer)
AddHandler ie.PrintTemplateInstantiation, AddressOf IE_OnPrintTemplateInstantiation
AddHandler ie.PrintTemplateTeardown, AddressOf IE_OnPrintTemplateTeardown
'Just to get reference of the webBrowser1 control in ie events, uncomment the below line
'ie.PutProperty("WebBrowserControl", DirectCast(wb, Object))
wb.Print()
End Sub
Private Sub IE_OnPrintTemplateInstantiation(pDisp As Object)
' The PrintTemplateInstantiation event is fired when the print job is starting.
End Sub
Private Sub IE_OnPrintTemplateTeardown(pDisp As Object)
' The PrintTemplateTeardown event is fired when the print job is done.
'Just to get reference of the webBrowser1 control, uncomment the below line
'Dim iwb2 As SHDocVw.IWebBrowser2 = TryCast(pDisp, SHDocVw.IWebBrowser2)
'Dim wb As WebBrowser = DirectCast(iwb2.GetProperty("WebBrowserControl"), WebBrowser)
Me.Close()
End Sub
End Class

Related

How to check if a Form has focus?

I have two WinForms. Let's say MainForm and ChildForm.
What I'm trying to make is when the MainForm is activated the ChildForm should always be visible, and when the MainForm loses focus the ChildForm should be hidden except if it's the ChildForm which was activated.
Here is my code :
AddHandler Me.MainForm.Activated, Sub()
Me.ChildForm.Show()
End Sub
AddHandler Me.MainForm.Deactivate, Sub()
If Not Me.ChildForm.Focused Then
Me.ChildForm.Hide()
End If
End Sub
AddHandler Me.ChildForm.Deactivate, Sub()
If Not MainForm.Focused Then
Me.ChildForm.Hide()
End If
End Sub
The code doesn't work. Basically when I click on a certain form (on the child form for example), the property Me.ChildForm.Focused is not correct and then ChildForm is hidden while it should be visible.
Can anyone know how to achieve that please ?
Not sure if this is a good one, but the idea is using flags for MainForm and ChildForm active status. These flags are set when MainForm and ChildForm's Activated and Deactive events are fired. For simplicity, I'll use a module to store the flags and the instance of ChildForm. Then call SetChildVisible() method in MainForm, Form1 and Form2 Activated event. Set startup object to MainForm.
Module1
Module Module1
Public FChild As ChildForm
Public FMainActive As Boolean
Public FChildActive As Boolean
Public Sub SetChildVisible()
FChild.Visible = Not FChildActive And FMainActive
End Sub
End Module
MainForm
Public Class MainForm
Private Sub MainForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim f1 = New Form1
Dim f2 = New Form2
Dim child = New ChildForm
Module1.FChild = child
child.Show()
f1.Show()
f2.Show()
End Sub
Private Sub MainForm_Activated(sender As Object, e As EventArgs) Handles MyBase.Activated
Module1.FMainActive = True
Module1.SetChildVisible()
End Sub
Private Sub MainForm_Deactivate(sender As Object, e As EventArgs) Handles MyBase.Deactivate
Module1.FMainActive = False
End Sub
End Class
ChildForm
Public Class ChildForm
Private Sub ChildForm_Activated(sender As Object, e As EventArgs) Handles MyBase.Activated
Module1.FChildActive = True
End Sub
Private Sub ChildForm_Deactivate(sender As Object, e As EventArgs) Handles MyBase.Deactivate
Module1.FChildActive = False
End Sub
End Class
Form1
Public Class Form1
Private Sub Form1_Activated(sender As Object, e As EventArgs) Handles MyBase.Activated
Module1.SetChildVisible()
End Sub
End Class
Form2
Public Class Form2
Private Sub Form2_Activated(sender As Object, e As EventArgs) Handles MyBase.Activated
Module1.SetChildVisible()
End Sub
End Class

Why isn't my thread doing anything?

I have the following code in a form called Fetch.vb:
Imports System.ComponentModel ' might not be needed?
Imports System.Threading
Public Class Fetch
Public Sub New()
InitializeComponent()
backgroundWorker1.WorkerReportsProgress = True
backgroundWorker1.WorkerSupportsCancellation = True
End Sub
Private Sub btnFetch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnFetch.Click
Dim ctrl As Control
For Each ctrl In Me.Controls
If TypeName(ctrl) = "TextBox" Then
If ctrl.Text.Length = (Not 0) Then
tbList.Add(ctrl.Text)
MsgBox(tbList.Item(0).ToString)
Exit For
End If
End If
Next
' ProcessLinks()
btnFetch.Enabled = False
BackgroundWorker1.RunWorkerAsync()
End Sub
Public Sub backgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
AddHandler BackgroundWorker1.DoWork, AddressOf backgroundWorker1_DoWork
ProcessLinks()
End Sub
End Class
Now process links is a module with a public sub in with the code I am trying to run, I don't need any arguments passed to it, and it doesn't do anything that (I think) could affect this, I think I'm just doing the threading code wrong. I have backgroundworker1 in my fetch.vb form, and when I click btn Fetch, the program does nothing.
Any help and guidance or reading material would be greatly appreciated.
EDIT Here is my LinkProcess module.
Public Module LinkProcess
Private Sub backgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Fetch.BackgroundWorker1.DoWork
ProcessLinks()
End Sub
Public Sub ProcessLinks()
Dim tbContent As String
For Each tbContent In Fetch.tbList
Process.Start(tbContent)
Next
End Sub
End Module
What does your ProcessLinks() method do? Is it accessing any UI elements - like setting some text in label, or adding text a TextBox, etc.? If that is the case, then that won't work. You should not access the UI elements from inside your BackgroundWorker DoWork.
Here is a small post I wrote about how to use the BackgroundWorker correctly. This might help you.
http://www.vbforums.com/showthread.php?680130-Correct-way-to-use-the-BackgroundWorker

BackgroundWorker 'DoWork' event not firing

I have a form that loads just fine, and I'm trying to fire off a task using a Background Worker as it loads.
I'm getting no errors with the code below, but the bw.DoWork event doesn't seem to be firing.
Am I missing something here? Thanks.
Here is my form Class -
Public Class mainForm
Dim objWorker As MyWorker
Private Sub mainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Call Me.loadForm()
End Sub
Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
Call Me.closeForm()
End Sub
Private Sub loadForm()
Me.objWorker = New MyWorker ' Invoke the background worker
End Sub
Private Sub closeForm()
Me.objWorker.bw_Cancel() ' Cancel the background worker
Me.Close() ' Close the form
End Sub
End Class
Here is my BackgroundWorker Class -
Imports System.ComponentModel
Partial Public Class MyWorker
Private bw As BackgroundWorker = New BackgroundWorker
Public Sub New()
bw.WorkerReportsProgress = False
bw.WorkerSupportsCancellation = True
AddHandler bw.DoWork, AddressOf bw_DoWork
AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted
End Sub
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
For i = 1 To 10
If bw.CancellationPending = True Then
e.Cancel = True
Exit For
Else
System.Threading.Thread.Sleep(500)
MsgBox("iteration " & i)
End If
Next
End Sub
Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)
MsgBox("Complete!")
End Sub
Public Sub bw_Cancel()
If bw.WorkerSupportsCancellation = True Then
bw.CancelAsync()
End If
End Sub
End Class
add to MyWorker constructor ('new' method) this line:
bw.RunWorkerAsync()

example of GeckoFX

I downloaded GeckoFX (ver 16), the XULRunner Dotnet wrapper to use in a winForms (VB.NET) application, but there are no instructions on usage anywhere (just the Initialize command).
I added the control onto my form and in the Form load event, put in the following:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Xpcom.Initialize(My.Application.Info.DirectoryPath & "/xulrunner")
InitializeComponent()
Me.GeckoWebBrowser1.Enabled = True
Me.GeckoWebBrowser1.Navigate("http://www.google.com")
End Sub
Nothing happens. The control is not visible, no navigation takes place.
Just a simple project (C# is fine too) that shows the control actually working would be nice (please do not answer with another URL that points to GeckoFx's wiki page as it is useless and no examples anywhere are shown)
Imports Gecko
Public Class Form1
Private myBrowser As GeckoWebBrowser
Public Sub New()
InitializeComponent()
Xpcom.Initialize(My.Application.Info.DirectoryPath & "\xulrunner")
myBrowser = New GeckoWebBrowser()
myBrowser.Parent = Me.SplitContainer1.Panel2
myBrowser.Dock = DockStyle.Fill
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
myBrowser.Navigate(TextBox1.Text)
End Sub
End Class
Just do it with Events. Im talking for withEvents:D
Imports Gecko
Public Class Form1
Private WithEvents myBrowser As GeckoWebBrowser
Public Sub New()
InitializeComponent()
Xpcom.Initialize(My.Application.Info.DirectoryPath & "\xulrunner")
myBrowser = New GeckoWebBrowser()
myBrowser.Parent = Me.SplitContainer1.Panel2
myBrowser.Dock = DockStyle.Fill
End Sub
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
myBrowser.Navigate(TextBox1.Text)
End Sub
End Class

Getting Build Errors in Program to Change Button Name When Clicked

Imports System
Imports System.Windows.Forms
Class MyButtonClass
Inherits Form
Private mrButton As Button
Public Sub MyButtonClass()
mrButton = New Button()
mrButton.Text = "Click me "
mrButton.Click += New System.EventHandler(MyButtonClickEventHandler)
Me.Controls.Add(mrButton)
End Sub
Shared Sub Main()
Application.Run(New MyButtonClass())
End Sub
Private Sub MyButtonClickEventHandler(ByVal sender As Object, ByVal e As EventArgs)
mrButton.Text = "You clicked me!"
End Sub
End Class
You're mixing C# and VB.Net code.
mrButton.Click += New system.EventHandler(MyButtonClickEventHandler)
Is C# syntax.
The button handler should either be declared as:
Private Sub MyButtonClickEventHandler(ByVal sender As Object, ByVal e As EventArgs) Handles mrButton.Click
Or you use the AddHandler as:
AddHandler mrButton.Click, AddressOf MyButtonClickEventHandler