My First VB Code
This is what happens when your Java application needs to interoperate with COM Objects. In normal case, you can solve the problem by using
However, in my case, it is not so simple. By doing normal procedure,
Older versions of COM4J could detect some interfaces, thus making statement in the
The newest version could generate definition for each class, but fail to make proper reference to each class in
As a workaround, I have to write VB class to wrap QTerm, make a dll out of it, then use Com4J to generate its Java definition.
So begin my days of learning VB.
Many would say that it is easy to learn but I beg to differ. Switching from Java to VB is like switching from French to Japanese. I know that I could find equivalent of things Java has in VB. In fact VB is no stranger to me because when I learnt about programming the procedural way, algorithms are mostly written in basic/pascal way.
However, there are several tidbits of this Microsoft technology that I have to deal with. To name some of them, registry and multi instance / multithreading environment.
(You could say "Wooooow, poor Umar, why do you sacrifice your soul in this programming altar?") Registry is something odd. You could not find registry in Java because Java use path name to find a class, thus you don't register classes like in COM context.
Concerning multi instance / multithreading, this is vague concept for me even in Java. The reason is, multithreading programming could be simplified using some approaches in such way that it would be transparent to developers. Sam said, "Penyakitnya VB ya multithreading". He pointed out the fact that I could run a single instance of my Qterm Adapter (my VB Class wrapping Qterm), but not more than one.
This is grave because I need to run several instances, each using different PID to connect to different airlines. So here I am, bitching about this hell, although I keep crossing my fingers that I might get out of it.
COM4J
. Use its tlbimp.jar
to generate Java definitions (classes and interfaces) which will act as proxies to COM Objects.However, in my case, it is not so simple. By doing normal procedure,
COM4J
coul not generate Java definitions for QTerm.exe
. Older versions of COM4J could detect some interfaces, thus making statement in the
ClassFactory
referring interfaces ITerminal
, ITerminals
, and IAutoHosts
but could not generate definitions for each of them.The newest version could generate definition for each class, but fail to make proper reference to each class in
Class Factory
. Instead of referring each interface by its proper name, the Class Factory only call a generic Com4JObject
, although Com4JObject
is the standard superinterface for every interface created by Com4J
. In standard Java code, I could do downcasting, but since in this case it involves messy codes (i.e VID and IID annotations), the problem could not be solved using this approach.As a workaround, I have to write VB class to wrap QTerm, make a dll out of it, then use Com4J to generate its Java definition.
So begin my days of learning VB.
Many would say that it is easy to learn but I beg to differ. Switching from Java to VB is like switching from French to Japanese. I know that I could find equivalent of things Java has in VB. In fact VB is no stranger to me because when I learnt about programming the procedural way, algorithms are mostly written in basic/pascal way.
However, there are several tidbits of this Microsoft technology that I have to deal with. To name some of them, registry and multi instance / multithreading environment.
(You could say "Wooooow, poor Umar, why do you sacrifice your soul in this programming altar?") Registry is something odd. You could not find registry in Java because Java use path name to find a class, thus you don't register classes like in COM context.
Concerning multi instance / multithreading, this is vague concept for me even in Java. The reason is, multithreading programming could be simplified using some approaches in such way that it would be transparent to developers. Sam said, "Penyakitnya VB ya multithreading". He pointed out the fact that I could run a single instance of my Qterm Adapter (my VB Class wrapping Qterm), but not more than one.
This is grave because I need to run several instances, each using different PID to connect to different airlines. So here I am, bitching about this hell, although I keep crossing my fingers that I might get out of it.
-- Class QTermAdapter
Public qterm As ApplicationQTermUTS
Public activeTerm As Terminal
Public Function openSessionStation(ByVal hostName As String, ByVal hostconIp As String, ByVal hostconPort As Long, ByVal hostconStation As String) As Long
Dim connectionDef As String
Dim connectionResult As Long
activeTerm.optAutoReconnect = True
activeTerm.termName = hostconStation
'activeTerm.termType = 0
'connectionDefinition = hostName,applicationName,ip,port,transport,csu
connectionDef = hostName & "," & "TIP" & "," & hostconIp & ","
& hostconPort & "," & "T" & "," & "TIPCSU"
connectionResult = activeTerm.Connect(connectionDef)
If (connectionResult <> 0) Then
'connection failed, return 0
openSessionStation = 0
Else
'connection successful
openSessionStation = 1
End If
End Function
Private Sub Class_Initialize()
On Error Resume Next
'If pathname is a zero-length string (""),
'GetObject returns a new object instance of the specified type.
'If the pathname argument is omitted, GetObject returns a currently active
'object of the specified type.
'If no object of the specified type exists, an error occurs
Set qterm = GetObject("", "QTermUTS.Application")
i = qterm.Caption
If Err.Number = 429 Then
' Create a new object
Err.Clear
Set qterm = CreateObject("QTermUTS.Application")
If Err.Number <> 0 Then
Exit Sub
End If
End If
' tell app to open config if 0 terminals
If (qterm.Terminals.Count = 0) Then
qterm.Open ("QTermUTS.cfg")
End If
' set activeTerm by application's front (active) terminal object
Set activeTerm = qterm.Terminals.ActiveTerminal
i = qterm.Terminals.Count
End Sub
Public Sub closeSession()
activeTerm.Disconnect
End Sub
Public Sub clientMode(ByVal value As Long)
'no equivalent in qterm
'qterm.Terminals.ActiveTerminal.termName = station
End Sub
Public Sub readOnly(ByVal value As Long)
'no equivalent in qterm
End Sub
Public Sub allowUserTransmit(ByVal value As Long)
'no equivalent in qterm
End Sub
Public Sub sitaOpenId(ByVal value As Long)
'no equivalent in qterm
End Sub
Public Sub setScreenText(ByVal textMessage As String)
activeTerm.Display (textMessage)
End Sub
Public Function keyboardLocked() As Boolean
Dim statusKeyboard As Integer
statusKeyboard = qterm.Terminals.ActiveTerminal.GetStatusFlags
If (statusKeyboard And QTermUTS.STATUS_KEYBD_LOCKED) Then
keyboardLocked = True
Else
keyboardLocked = False
End If
End Function
Public Sub receive(ByVal timeout As Long)
activeTerm.Wait (timeout)
End Sub
Public Function getScreenText(ByVal column As Long, ByVal row As Long, ByVal length As Long) As String
'qplexview accepts three parameters column, row and length
'while qterm accepts four parameters,
'start row, start column, end row, and end start
'thus, end row = start row, and end column = start column + length - 1
getScreenText = activeTerm.GetText(row, column, row, column + length - 1)
End Function
Public Function waitForString(ByVal column As Long, ByVal row As Long, ByVal textMessage As String, ByVal timeout As Long) As Long
Dim message As Boolean
message = qterm.Terminals.ActiveTerminal.WaitScreenText(
row, column, textMessage, timeout)
If (message = True) Then
waitForString = 1
Else
waitForString = 0
End If
End Function
Public Sub doTerminalKey(ByVal keyNumber As Long)
activeTerm.SendFkey (keyNumber)
End Sub
Public Sub unlockKeyboard()
activeTerm.unlockKeyboard
End Sub
Public Sub Transmit()
activeTerm.Xmit
End Sub
Public Sub clearDisplay()
activeTerm.EraseDisplay (True)
End Sub
Public Sub displaySOE()
activeTerm.displaySOE
End Sub
Public Sub returnKey()
activeTerm.SendFkey (QTermUTS.QID_RETURN)
End Sub
Public Sub moveToEOL()
activeTerm.SendFkey (QTermUTS.QID_MOVE_EOL)
End Sub
Public Sub moveToHome()
activeTerm.SendFkey (QTermUTS.QID_HOME)
End Sub
Public Function sessionOpen() As Integer
Dim connected As Long
Dim msgArrived As Long
msgArrived = 0
'While (msgArrived = 0)
' DoEvents
' activeTerm.GetStatus connected, msgArrived
'Wend
activeTerm.GetStatus connected, msgArrived
If (connected = 2) Then
sessionOpen = 1
Else
sessionOpen = 0
End If
End Function
--- Form1, calling QTermAdapter Class
Dim qtermScreen As QTermAdapter
Private Sub Clear_Click()
qtermScreen.clearDisplay
List1.Clear
End Sub
Private Sub Combo1_Change()
End Sub
Private Sub Connect_Click()
Dim PID As String
Dim SignIn As String
Connect.Enabled = False
Select Case Connections
Case "Mandala1"
PID = "P11219"
SignIn = "mdla/4lbe2ta"
Case "Mandala2"
PID = "P11353"
SignIn = "mdla/4lbe2ta"
Case "Sriwijaya1"
PID = "P10559"
SignIn = "sjair/8mrs8x"
Case "Sriwijaya2"
PID = "P10600"
SignIn = "sjair/8mrs8x"
Case Else
PID = ""
SignIn = ""
End Select
List1.AddItem (Connections)
message = qtermScreen.openSessionStation(Connections, "57.5.64.101", 102, PID)
qtermScreen.receive (6000)
result = qtermScreen.waitForString(1, 1, "ENTER USERID/PASSWORD:", 6000)
If (result = 1) Then
message = "Connection to " & Connections & " success"
Else
message = "Connection to " & Connections & " failed"
End If
List1.AddItem (message)
qtermScreen.setScreenText (SignIn)
qtermScreen.Transmit
result = qtermScreen.waitForString(18, 1, "Logged in to SITA system", 6000)
If (result = 1) Then
message = "Logged in to SITA system success"
Else
message = "Logged in to SITA system failed"
End If
List1.AddItem (message)
Connect.Enabled = True
End Sub
Private Sub Disconnect_Click()
List1.Clear
If (qtermScreen.sessionOpen = 0) Then
List1.AddItem ("Session has already been closed")
Else
qtermScreen.closeSession
List1.AddItem ("Session is closed")
End If
End Sub
Private Sub Form_Load()
Set qtermScreen = New QTermAdapter
Connections.AddItem ("Mandala1")
Connections.AddItem ("Mandala2")
Connections.AddItem ("Sriwijaya1")
Connections.AddItem ("Sriwijaya2")
End Sub
Private Sub Transmit_Click()
Dim i As Integer
List1.Clear
Transmit.Enabled = False
qtermScreen.clearDisplay
qtermScreen.moveToHome
qtermScreen.displaySOE
qtermScreen.setScreenText (Text1)
qtermScreen.Transmit
List1.AddItem (Text1)
qtermScreen.receive (6000)
'For i = 1 To 24
' message = qtermScreen.getScreenText(1, i, 80)
' List1.AddItem (message)
'Next i
printScreen
Transmit.Enabled = True
End Sub
Private Sub printScreen()
Dim i As Integer
For i = 1 To 24
message = qtermScreen.getScreenText(1, i, 80)
List1.AddItem (message)
Next i
End Sub
Comments