GetElementById with CefSharp - vb.net

I'm trying to access to a website variable by it's ID in VB.net. The ID is "value", the data I'm trying to access is the stock price, and the website is linked in the code. I was using the built-in web browser with the next code:
Imports System.Xml
Imports System.Net
Public Class Bolsa
Public Sub New()
InitializeComponent()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
WebBrowser1.Navigate("https://www.ahorro.com/acnet/fichas/ficha_valor.acnet?isin=ES0113211835&marketCode=09&submarketId=09")
While Not WebBrowser1.ReadyState = WebBrowserReadyState.Complete
Application.DoEvents()
End While
Dim request As String = WebBrowser1.Document.GetElementById("value").InnerText
Dim s As String = request.Replace("<span>", Nothing)
Dim t As String = s.Replace("</span>", Nothing)
TextBox1.Text = t
End Sub
End Class
Now I'm using CefSharp plugin, because I need HTML5 support, but I cannot access the data, and I think the method is correct, I found it in the official site. The actual code:
Imports CefSharp.WinForms
Imports CefSharp
Imports System.Xml
Imports System.Net
Imports System.Treading
Imports System.Treading.Tasks
Public Class Bolsa
Private WithEvents WebClave As ChromiumWebBrowser
Dim cadena
Public Sub New()
InitializeComponent()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs)
InitializeComponent()
Dim settings As New CefSettings()
CefSharp.Cef.Initialize(settings)
WebClave = New ChromiumWebBrowser("https://www.ahorro.com/acnet/fichas/ficha_valor.acnet?isin=ES0113211835&marketCode=09&submarketId=09")
pANwEB.Controls.Add(WebClave)
End Sub
Private Sub WebClave_IsBrowserInitializedChanged(sender As Object, e As IsBrowserInitializedChangedEventArgs) Handles WebClave.IsBrowserInitializedChanged
If e.IsBrowserInitialized Then
cadena = WebClave.EvaluateScriptAsync("document.getElementById('value').innerHTML")
TextBox1.Text = cadena
End If
End Sub
End Class
Any advice?
Thanks in advance.
[EDIT]: Added full original code

Imports CefSharp
Imports CefSharp.WinForms
Public Class Form1
Public WithEvents browser As ChromiumWebBrowser
Public Sub New()
InitializeComponent()
Dim settings As New CefSettings()
CefSharp.Cef.Initialize(settings)
browser = New ChromiumWebBrowser("https://google.com") With {
.Dock = DockStyle.Fill
}
Panel1.Controls.Add(browser)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim cvbar = browser.EvaluateScriptAsync("document.getElementById(""lst-ib"").value;")
Dim response = cvbar.Result
If response.Success = True And response.Result <> "" Then
MsgBox(response.Result)
End If
End Sub
End Class

Related

How to add a chrome web browser control to my application in visual basic

i want to add a google chrome control to my application because internet explorer control isnt very good.It shows the web pages wrong etc.Some help please
if you want replace internet explorer with chrome in your winforms you must have to include third party tool (library). now a days there many some of that are
1] Selenium
2] CefSharp
3] DotNet Browser
4] OpenWebKitSharp
given list are only some browser . you could also google it out "winform replace webbrowser with chrome".
Thanks
my friend please refere to code given below.
Imports Microsoft.Win32
Imports System
Imports System.Collections
Imports System.ComponentModel
Imports System.Drawing
Imports System.Runtime.CompilerServices
Imports System.Windows.Forms
Imports mshtml
Imports System.Net
Imports System.IO
Imports System.Text
Imports System.Drawing.Imaging
Imports OpenQA.Selenium.Chrome.ChromeDriver
Imports OpenQA.Selenium
Imports OpenQA.Selenium.Interactions
Imports OpenQA.Selenium.Interactions.Actions
Imports OpenQA.Selenium.Support.UI
Imports OpenQA.Selenium.Chrome
Imports OpenQA.Selenium.Support.Events
Imports System.Text.RegularExpressions
Public Class CLOGIN
Public MASTERID As String = ""
Public MASTERPASSWORD As String = ""
Dim webbrowse As New WebBrowser()
Private _DOCUMENTREADY As Integer
Private ERRORSFOUND As Boolean
Private RequestID As String
Private READYSTATE As Boolean
Public mconfig As New MasterConfig()
Public GSTCAPTCHA As New CommonCaptcha()
Private CaptchaCookie = ""
Private WEBSTATEINC As Boolean = True
Public wbr As New Chrome.ChromeDriver(mconfig.MASTERSERVICE, mconfig.MASTEROPTION)
Public WithEvents driver As New EventFiringWebDriver(wbr)
Private Sub CLOGIN_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
AddHandler driver.Navigated, AddressOf OnNavigated
RECALL()
End Sub
Public Function CropImage(ByVal source As Bitmap, ByVal section As Rectangle) As Bitmap
Dim bmp As New Bitmap(section.Width, section.Height)
Dim g As Graphics = Graphics.FromImage(bmp)
g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel)
Return bmp
End Function
Private Sub WebBrowser1_DocumentCompleted(ByVal sender As System.Object, ByVal e As System.Windows.Forms.WebBrowserDocumentCompletedEventArgs)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
End Sub
Public Sub RECALL()
INITLABEL:
wbr.Url = "https://example.com/services/do_login"
wbr.Navigate()
System.Threading.Thread.Sleep(2500)
Application.DoEvents()
If Not wbr.Url.Contains("/do_login") Then
GoTo INITLABEL
End If
Dim origialheight = Me.MdiParent.Height
Dim dblheight = origialheight * 0.75
Dim proportedration = origialheight - dblheight
Dim maxwidth = Me.MdiParent.Width
Me.MdiParent.WindowState = FormWindowState.Normal
Me.MdiParent.Location = New Point(0, dblheight + 1)
Me.MdiParent.Size = New Size(maxwidth, proportedration) 'dblheight
wbr.Manage().Window().Size = New System.Drawing.Size(maxwidth, dblheight) 'dblheight
wbr.Manage().Window().Position = New Point(0, 0)
Dim action As New Actions(wbr)
Dim wait As New WebDriverWait(wbr, System.TimeSpan.FromSeconds(5))
wait.Until(ExpectedConditions.ElementExists(By.Id("username")))
wbr.FindElement(By.XPath("//*[#id='username']")).SendKeys(MASTERID) 'txtuserid.Text
wbr.FindElement(By.XPath("//*[#id='user_pass']")).SendKeys(MASTERPASSWORD)
Threading.Thread.Sleep(3000)
Application.DoEvents()
Dim master = ""
wbr.FindElement(By.XPath("//*[#id='captcha']")).SendKeys(OpenQA.Selenium.Keys.Tab)
End Sub
Private Sub btnlogout_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnlogout.Click
End Sub
Private Sub lblshowpass_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lblshowpass.CheckedChanged
If lblshowpass.Checked Then
txtpassword.PasswordChar = ""
Else
txtpassword.PasswordChar = "*"
End If
End Sub
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click, Button5.Click
wbr.FindElement(By.XPath("//*[#id='captcha']")).SendKeys(TextBox2.Text)
wbr.FindElement(By.XPath("//*[#type='submit']")).Submit()
WaitUntilDocumentIsReady(TimeSpan.FromSeconds(5))
System.Threading.Thread.Sleep(1500)
Application.DoEvents()
If wbr.Url.Contains("/login") Then
Dim wait As New WebDriverWait(wbr, System.TimeSpan.FromSeconds(3)) 'you can play with the time integer to wait for longer than 15 seconds.`
Try
Dim myLink = wbr.FindElementByXPath("//*[#data-ng-if='loginform.captcha.$error.invalid_captcha']")
If Not myLink Is Nothing Then 'wbr.PageSource.Contains("Enter valid Letters shown") Then
MsgBox("Invalid Captcha Code", MsgBoxStyle.Critical, "Application Error")
wbr.FindElement(By.XPath("//*[#id='user_pass']")).SendKeys(txtpassword.Text)
Me.TextBox1.Text = ""
Me.TextBox1.Focus()
End If
Catch ex As Exception
End Try
Try
If wbr.PageSource.Contains("class=""alert alert-danger""") Then
MsgBox("Invalid User ID or Password", MsgBoxStyle.Critical, "Application Error")
wbr.Dispose()
Application.Exit()
End If
Catch ex As Exception
End Try
Else
wbr.Manage().Window().Maximize()
Me.MdiParent.WindowState = FormWindowState.Minimized
End If
End Sub
Public Sub ReCaptcha(ByVal wbr As ChromeDriver)
End Sub
Public Sub OnNavigated(ByVal sender As Object, ByVal e As Support.Events.WebDriverNavigationEventArgs) Handles driver.Navigated
If wbr.Url.Contains("/do_login") Then
Dim wait As New WebDriverWait(wbr, System.TimeSpan.FromSeconds(3))
Try
Dim myLink = wbr.FindElementByXPath("//*[#data-ng-if='loginform.captcha.$error.invalid_captcha']")
If Not myLink Is Nothing Then 'wbr.PageSource.Contains("Enter valid Letters shown") Then
MsgBox("Invalid Captcha Code", MsgBoxStyle.Critical, "Application Error")
wbr.FindElement(By.XPath("//*[#id='user_pass']")).SendKeys(txtpassword.Text)
Me.TextBox1.Text = ""
Me.TextBox1.Focus()
End If
Catch ex As Exception
End Try
Try
If wbr.PageSource.Contains("class=""alert alert-danger""") Then
MsgBox("Invalid User ID or Password", MsgBoxStyle.Critical, "Application Error")
wbr.Dispose()
Application.Exit()
End If
Catch ex As Exception
End Try
Else
End If
End Sub
Public Sub truncateUnfinish(ByVal string1 As String)
If Not IsNumeric(string1) Then
Return
End If
Dim answer = Regex.Replace(string1, "\D", "")
If string1.Length > 6 Then
TextBox2.Text = answer.Substring(0, 6)
End If
End Sub
Function AllCaps(ByVal stringToCheck As String) As Boolean
AllCaps = StrComp(stringToCheck, UCase(stringToCheck), vbBinaryCompare) = 0
End Function
End Class
Thanks.

Trouble with OnLoad Sub (Visual Basic)

I have some trouble with declaring a default path file on startup.
Everytime I run the program, it's saying that pathFile is null.
Does someone know what I need to change in my code?
Imports System
Imports System.IO
Imports System.Text
Public Class GlobalVariables
Public Shared pathFile As String
End Class
Public Class Form1
Protected Overridable Sub OnLoad(e As EventArgs)
GlobalVariables.pathFile = My.Computer.FileSystem.SpecialDirectories.Desktop
End Sub
Private Sub btnSave_Click(sender As Object, e As EventArgs) Handles btnSave.Click
' create or overwrite the file
Dim fs As FileStream = File.Create(GlobalVariables.pathFile)
' add text to file
Dim info As Byte() = New UTF8Encoding(True).GetBytes(rtbText.Text)
fs.Write(info, 0, info.Length)
fs.Close()
End Sub
End Class
Thanks in advance!
- Xaaf Code
Instead of trying to override OnLoad (which would be Overrides instead of Overridable), I would handle the load event:
Private Sub Form_Load(sender As Object, e As System.EventArgs) Handles Me.Load
GlobalVariables.pathFile = My.Computer.FileSystem.SpecialDirectories.Desktop
End Sub
You could probably just set the value where pathFile is declared instead:
Public Class GlobalVariables
Public Shared pathFile As String = My.Computer.FileSystem.SpecialDirectories.Desktop
End Class

Closing form after printing a web browser control contained in it

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

Two way client and server?

I created a one way client server communication so that the client can send messages to the server which just receives them. How can I modify the code so that both the server and the client can send and receive messages.
Client Code:
TCPControl.vb
Imports System.Net
Imports System.Net.Sockets
Imports System.IO
Public Class TCPControl
Public Client As TcpClient
Public DataStream As StreamWriter
Public Sub New(Host As String, Port As Integer)
' CLIENT
Client = New TcpClient(Host, Port)
DataStream = New StreamWriter(Client.GetStream)
End Sub
Public Sub Send(Data As String)
DataStream.Write(Data & vbCrLf)
DataStream.Flush()
End Sub
End Class
Form1.vb
Public Class Form1
Private Client As TCPControl
Private Sub cmdSend_Click(sender As System.Object, e As System.EventArgs) Handles cmdSend.Click
SendMessage()
txtMessage.Clear()
txtMessage.Focus()
End Sub
Private Sub cmdConnect_Click(sender As System.Object, e As System.EventArgs) Handles cmdConnect.Click
Client = New TCPControl("10.0.0.253", 64555)
If Client.Client.Connected Then cmdConnect.Text = "Connected"
End Sub
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
If Client.Client.Connected = True Then
Client.DataStream.Close()
Client.Client.Close()
End If
End Sub
Private Sub txtMessage_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles txtMessage.KeyDown
If e.KeyCode = Keys.Enter Then SendMessage()
End Sub
Private Sub SendMessage()
If Client.Client.Connected = True Then Client.Send(txtMessage.Text)
End Sub
End Class
Server Code:
TCPControl.vb
Imports System.IO
Imports System.Net
Imports System.Net.Sockets
Imports System.Threading
Public Class TCPControl
Public Event MessageReceived(sender As TCPControl, Data As String)
' SERVER CONFIG
Public ServerIP As IPAddress = IPAddress.Parse("10.0.0.253")
Public ServerPort As Integer = 64555
Public Server As TcpListener
Private CommThread As Thread
Public IsListening As Boolean = True
' CLIENTS
Private Client As TcpClient
Private ClientData As StreamReader
Public Sub New()
Server = New TcpListener(ServerIP, ServerPort)
Server.Start()
CommThread = New Thread(New ThreadStart(AddressOf Listening))
CommThread.Start()
End Sub
Private Sub Listening()
' CREATE LISTENER LOOP
Do Until IsListening = False
' ACCEPT INCOMING CONNECTIONS
If Server.Pending = True Then
Client = Server.AcceptTcpClient
ClientData = New StreamReader(Client.GetStream)
End If
' RAISE EVENT FOR INCOMING MESSAGES
Try
RaiseEvent MessageReceived(Me, ClientData.ReadLine)
Catch ex As Exception
End Try
' REDUCE CPU USAGE
'Thread.Sleep(100)
Loop
End Sub
End Class
Public Class Form1
Private Server As TCPControl
Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
Server.IsListening = False
End Sub
TCPControl.vb
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Server = New TCPControl
txtChat.Text = ":: SERVER STARTED ::" & vbCrLf
AddHandler Server.MessageReceived, AddressOf OnLineReceived
End Sub
' ALLOW THREAD TO COMMUNICATE WITH FORM CONTROL
Private Delegate Sub UpdateTextDelegate(TB As TextBox, txt As String)
' UPDATE TEXTBOX
Private Sub UpdateText(TB As TextBox, txt As String)
If TB.InvokeRequired Then
TB.Invoke(New UpdateTextDelegate(AddressOf UpdateText), New Object() {TB, txt})
Else
If txt IsNot Nothing Then TB.AppendText(txt & vbCrLf)
End If
End Sub
' UPDATE TEXT WHEN DATA IS RECEIVED
Private Sub OnLineReceived(sender As TCPControl, Data As String)
UpdateText(txtChat, Data)
End Sub
End Class

VB Unable to access instance of another class from one method but can from another

I have 2 main classes. The first launches the second which implements a FIX dll. I would like to be able to set variables/textbox.text in the first from the second. I am able to do so from te OnCreate method in the second, but for some reason cannot from the OnLogon method. Any ideas ?
Thanks
Imports QuickFix
Public Class GlobalVariable
Inherits MainFIXClass
Public Shared instance As MainFIXClass
End Class
Public Class MainFIXClass
Private Sub CurrencyArb_Load(sender As Object, e As EventArgs) Handles MyBase.Load
GlobalVariable.instance = Me
Connect({"D:\\Config.txt"})
End Sub
Private Sub Connect(args As String())
Dim settings As New QuickFix.SessionSettings(args(0))
Dim myApp As IApplication = New MyQuickFixApp()
Dim storeFactory As QuickFix.IMessageStoreFactory = New FileStoreFactory(settings)
Dim logFactory As QuickFix.ILogFactory = New FileLogFactory(settings)
Dim initiator As New QuickFix.Transport.SocketInitiator(myApp, storeFactory, settings, logFactory)
Try
initiator.Start()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
End Class
Public Class MyQuickFixApp
Inherits MainFIXClass
Implements IApplication
Private _session As Session = Nothing
Private _settings As QuickFix.Session = Nothing
Private _Store As QuickFix.IMessageStore = Nothing
Private _instance As MainFIXClass
Public Sub OnCreate(sessionID As SessionID) Implements IApplication.OnCreate
_instance = GlobalVariable.instance
_session = Session.LookupSession(sessionID)
_instance.OutputTB.Text = "On Create - " & sessionID.ToString & " " & _session.ToString ' **************************** this line works
End Sub
Public Sub OnLogon(sessionID As SessionID) Implements IApplication.OnLogon
_instance.OutputTB.Text = "Logged On" ' **************************** this line does not work ?????
MsgBox("Logged On")
End Sub
End Class
Imports System.ComponentModel
Imports System.Threading
Imports QuickFix
Imports QuickFix.Fields
Imports QuickFix.MessageCracker
Public Class MainFIXClass
Private WithEvents bw As BackgroundWorker
Delegate Sub ShowOutputDelegate(value As String)
Private Sub CurrencyArb_Load(sender As Object, e As EventArgs) Handles MyBase.Load
GlobalVariable.instance = Me
bw = New BackgroundWorker
bw.RunWorkerAsync()
End Sub
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bw.DoWork
Dim settings As New QuickFix.SessionSettings("D:\\CurrencyArb.txt")
Dim myApp As IApplication = New MyQuickFixApp()
Dim storeFactory As QuickFix.IMessageStoreFactory = New FileStoreFactory(settings)
Dim logFactory As QuickFix.ILogFactory = New FileLogFactory(settings)
Dim initiator As New QuickFix.Transport.SocketInitiator(myApp, storeFactory, settings, logFactory)
Try
'If Not TypeOf e.Argument Is String() Then 'only take valid input
' Throw New ArgumentException("Invalid argument")
'End If
'Dim args As String() = DirectCast(e.Argument, String()) 'you can pass your arguments here
initiator.Start()
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Private Sub bw_WorkCompleted(source As Object, e As RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
If e.Error IsNot Nothing Then
'and exception occured
Else
'everything was fine, you can use the result
Dim result As Object = e.Result
End If
End Sub
Public Sub ShowOutput(msg As String)
If InvokeRequired Then
Invoke(New ShowOutputDelegate(AddressOf ShowOutput), msg)
Else
Me.OutputTB.Text = msg
End If
Me.OutputTB.Text = msg
End Sub
End Class
Public Class MyQuickFixApp
Implements IApplication
Private _session As Session = Nothing
Private _settings As QuickFix.Session = Nothing
Private _Store As QuickFix.IMessageStore = Nothing
Private _instance As MainFIXClass
Public Sub OnCreate(sessionID As SessionID) Implements IApplication.OnCreate
_instance = GlobalVariable.instance
_session = Session.LookupSession(sessionID)
_instance.ShowOutput("On Create - " & sessionID.ToString & " " & _session.ToString)
End Sub
Public Sub OnLogon(sessionID As SessionID) Implements IApplication.OnLogon
_instance.ShowOutput("Logged On")
End Sub
End Class
Public Class GlobalVariable
Public Shared instance As MainFIXClass
End Class
To prevent the Window from blocking, you can use Threads or a BackgroundWorker. I prepared a small code snippet that demonstrates how you can use the BackgroundWorker. Please note how the DoWork and WorkCompleted methods are wired to the worker instance by using Handles.
Imports System.ComponentModel
Imports System.Threading
Imports QuickFix
Imports QuickFix.Fields
Imports QuickFix.MessageCracker
Public Class MainFIXClass
Implements IApplication
Private WithEvents bw As BackgroundWorker
Private _session As Session = Nothing
Private _settings As QuickFix.Session = Nothing
Private _Store As QuickFix.IMessageStore = Nothing
#Region "IApplication Methods"
Public Sub OnCreate(sessionID As SessionID) Implements IApplication.OnCreate
_session = Session.LookupSession(sessionID)
Me.ShowOutput("On Create - " & sessionID.ToString & " " & _session.ToString)
End Sub
Public Sub OnLogon(sessionID As SessionID) Implements IApplication.OnLogon
Me.ShowOutput("Logged On")
End Sub
#End Region
Private Sub CurrencyArb_Load(sender As Object, e As EventArgs) Handles MyBase.Load
bw = New BackgroundWorker
bw.WorkerReportsProgress = True
bw.RunWorkerAsync()
End Sub
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bw.DoWork
Dim settings As New QuickFix.SessionSettings("D:\\CurrencyArb.txt")
Dim myApp As IApplication = New MyQuickFixApp()
Dim storeFactory As QuickFix.IMessageStoreFactory = New FileStoreFactory(settings)
Dim logFactory As QuickFix.ILogFactory = New FileLogFactory(settings)
Dim initiator As New QuickFix.Transport.SocketInitiator(myApp, storeFactory, settings, logFactory)
bw.ReportProgress(0, "Starting initiator")
initiator.Start()
bw.ReportProgress(0, "Initiator started successfully")
End Sub
Private Sub bw_ReportProgress(source As Object, e As ProgressChangedEventArgs) Handles bw.ProgressChanged
Me.ShowOutput(e.UserState.ToString())
End Sub
Private Sub bw_WorkCompleted(source As Object, e As RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
If e.Error IsNot Nothing Then
'and exception occured
MsgBox(e.Error.Message)
Else
'everything was fine, you can use the result
Dim result As Object = e.Result
End If
Me.ShowOutput("Worker finished")
End Sub
Public Sub ShowOutput(msg As String)
Me.OutputTB.Text = msg
End Sub
End Class
Here is a snippet when merging both classes
Imports System.ComponentModel
Imports System.Threading
Imports QuickFix
Imports QuickFix.Fields
Imports QuickFix.MessageCracker
Public Class MainFIXClass
Implements IApplication
Private WithEvents bw As BackgroundWorker
Private _session As Session = Nothing
Private _settings As QuickFix.Session = Nothing
Private _Store As QuickFix.IMessageStore = Nothing
#Region "IApplication Methods"
Public Sub OnCreate(sessionID As SessionID) Implements IApplication.OnCreate
_session = Session.LookupSession(sessionID)
Me.ShowOutput("On Create - " & sessionID.ToString & " " & _session.ToString)
End Sub
Public Sub OnLogon(sessionID As SessionID) Implements IApplication.OnLogon
Me.ShowOutput("Logged On")
End Sub
#End Region
Private Sub CurrencyArb_Load(sender As Object, e As EventArgs) Handles MyBase.Load
bw = New BackgroundWorker
bw.WorkerReportsProgress = True
bw.RunWorkerAsync()
End Sub
Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles bw.DoWork
Dim settings As New QuickFix.SessionSettings("D:\\CurrencyArb.txt")
Dim myApp As IApplication = New MyQuickFixApp()
Dim storeFactory As QuickFix.IMessageStoreFactory = New FileStoreFactory(settings)
Dim logFactory As QuickFix.ILogFactory = New FileLogFactory(settings)
Dim initiator As New QuickFix.Transport.SocketInitiator(myApp, storeFactory, settings, logFactory)
bw.ReportProgress(0, "Starting initiator")
initiator.Start()
bw.ReportProgress(0, "Initiator started successfully")
End Sub
Private Sub bw_ReportProgress(source As Object, e As ProgressChangedEventArgs) Handles bw.ProgressChanged
Me.ShowOutput(e.UserState.ToString())
End Sub
Private Sub bw_WorkCompleted(source As Object, e As RunWorkerCompletedEventArgs) Handles bw.RunWorkerCompleted
If e.Error IsNot Nothing Then
'and exception occured
MsgBox(e.Error.Message)
Else
'everything was fine, you can use the result
Dim result As Object = e.Result
End If
Me.ShowOutput("Worker finished")
End Sub
Public Sub ShowOutput(msg As String)
Me.OutputTB.Text = msg
End Sub
End Class