Custom Clarify Classic Client command line parameters
Most of you know that there a bunch of command line options available for the Clarify Classic Client.
Some of the more common ones include:
- cbtrace
- CBDebugger
- clfy
- waggle
- debug
- debugCB
- msg
- nocache
- sqlhint
- sqllog
But did you also know you can pass your own parameters and evaluate them?
Lets take a simple example
Lets start clarify, passing in a case ID number. We’ll do this by coming up with our own custom URL format.
Custom URL Format? OMGWTFBBQ!
Everyone’s familiar with URL formats such as:
But we can also define custom URL formats, such as:
Not that it does anything, yet. But it looks cool, no?
Back to clarify.exe params
OK, so lets pass that as param to clarify.exe
From a command line, start clarify.exe with that custom URL as a param, like so:
OK, so that just starts clarify. What happens with that URL?
Well, at this point, nothing. Yet.
Lets make it do something with that param.
Initialize_app subroutine
In Clarify, the initialize_app subroutine (in ClearBasic) gets executed when the Clarify client starts up. So lets see if we can grab that param and do something with it.
First, we have our initialize_app subroutine, adding in a call to Process Command Line Arguments:
Public Sub initialize_app() Call ProcessCommandLineArgs() End Sub
Next, we have a subroutine to process the command line args:
Sub ProcessCommandLineArgs()
'Process any clarify URLS that were passed in on the command line
'(such as clarify://case/12345)
dim cmdLine as String
dim url as String
dim result as integer
dim num as Integer
dim listWords as new List
dim pos as integer
cmdLine = GetCommandLine();
pos = InStr(cmdLine, "clarify://")
if pos >= 0 Then
url = Mid$(cmdLine, pos)
Call handle_clarify_url(url)
End If
End Sub
So, we need a function to GetCommandLine, and one to handle_clarify_url.
This *should* work to get the command line:
Function GetCommandLine() As String GetCommandLine = Command$ End Function
Notice that we’re using the Command$ statement built into BasicScript to get the command line arguments. But this doesn’t work (at least for me, in Clarify 11.5 on Win7 64-bit). YMMV.
Bummer.
Instead, we can do it using win32 calls, like so:
Declare Function lstrcpyn_long_string Lib "kernel32" Alias "lstrcpynA" (ByVal DestString As String, ByVal SourcePointer As Long, ByVal MaxLen As Long) As Long
Declare Function lstrlen_long Lib "kernel32" Alias "lstrlenA" (ByVal SourcePointer As Long) As Long
Declare Function GetCommandLine_long Lib "kernel32" Alias "GetCommandLineA" () As Long
Declare Function parse_string(str_input as String, str_delim as String, _
int_count as Integer, lst_words as List) as Integer
Function GetCommandLine() As String
'Get a pointer to process commandline as Long
Dim ptrCommandLine As Long
ptrCommandLine = GetCommandLine_long
If ptrCommandLine > 0 Then 'GetCommandLine ok
Dim Buffer As String, BufferLength As Long
'Get a length of the command line using Long pointer
'Returns the length without the zero terminating char
BufferLength = lstrlen_long(ptrCommandLine)
If BufferLength > 0 Then
'Allocate a space for the command line
Buffer = Space(BufferLength + 1)
'Copy the command line to a buffer using Long + String pointers.
ptrCommandLine = lstrcpyn_long_string(Buffer, ptrCommandLine, BufferLength + 1)
'The copy SHOULD be OK. Zero means some error, not enough of space
If ptrCommandLine > 0 Then 'lstrcpyn
'Remove the zero terminator from the copied string
Dim PosZero As Long
PosZero = InStr(Buffer, Chr$(0))
If PosZero > 0 Then Buffer = Left(Buffer, PosZero - 1)
GetCommandLine = Buffer
End If 'If ptrCommandLine > 0 Then 'lstrcpyn
End If 'If BufferLength > 0 Then
End If 'If ptrCommandLine > 0 Then 'GetCommandLine ok
End Function
Great!
Now that we have the command line, we can pass that string off to handle_clarify_url, where we’ll either open a new case form or open an existing case form.
Sub handle_clarify_url(url as String)
dim result as integer
dim num as Integer
dim listWords as new List
dim id as String
dim objectType as String
dim winName as String
result = parse_string(url, "/", num, listWords)
objectType = listWords.ItemByIndex(2)
id = listWords.ItemByIndex(3)
if objectType = "case" Then
if id = "new" then
App.NewCase
else
show_case id
end if
end if
End Sub
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Show an Existing Case
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub show_case(case_id As String)
Dim t_ret As New BulkRetrieve ' Structure to query the DB
Dim case_list As List ' List of returned cases
Dim case_rec As Record ' One returned case
' Query for the case
' Get the results
t_ret.SimpleQuery 0, "case"
t_ret.AppendFilter 0, "id_number", cbEqual, case_id
t_ret.RetrieveRecords
Set case_list = t_ret.GetRecordList(0)
' If case not found, error message
' Else, post the case
If case_list.Count = 0 Then
App.MsgBox "Customer keyed in case " + case_id + ", but that case is not found in the database."
Else
Set case_rec = case_list.ItemByIndex(0)
App.ShowCase case_rec
End If
End Sub
Lets see it work – Open an existing case
command: clarify.exe clarify://case/149
Lets see it work – Open a new case
command: clarify.exe clarify://case/new
OK, that’s some pretty cool stuff!
Code
I realize there’s a bunch of code there. Don’t worry, I’ve shared it all.
The entire code is available on github: https://gist.github.com/gsherman/2839349
What now?
Well, now that we’ve proved that we can pass in a param to Clarify and do something with it, lets do something more interesting.
But that’ll have to happen in the next post. Stay tuned. And stay thirsty.
Rock on.
