vbBdFtVolClient is a PowerBASIC 9 client that connects to the ActiveX Visual Basic Dll and does about the same thing the Visual Basic client prjVolume does, i.e., it prints a few lines of output to the Form/Window. The three files are…
vbBFVolClient.bas -- Main source code file with windowing code, i.e., WinMain(), etc.
Main.inc -- Main include file for vbBFVolClient.bas with a few Types, declares, etc.
vbVolumes.inc -- Interface declarations from Type Library created in vbVolumes.dll
…and are found in vbBdFtVolClient.zip (attached). To get this to work you will need to create your own interface definition file using either the PowerBASIC COM browser or Jose Roca’s TypeLib browser. Here are the directions for using the PowerBASIC COM Browser. Go to the Tools Menu and select ‘PowerBASIC COM Browser’. Since its in alphabetical order you’ll find vbVolumes about 95% of the way to the bottom of the list so you’ll have to scroll way on down. Note that to locate vbVolumes in the COM Browser you will have had to have compiled it first into a dll as per my earlier instructions. Once you locate it in the listview double click on it and magically a whole new window will open up and you’ll see all kinds of wonderful information from the ActiveX Dll. You need to copy the entirety of that information in the right pane to a text file which you’ll need to name vbVolumes.inc and that will need to replace the one referred to above in the zip. Again, the reason you need to do this and the reason you can’t use mine is that when you compile the vbVolumes.dll file on your computer you will have different Guids than mine. If you were installing your Dll on someone else’s machine you would register your Dll on theirs with RegSvr32.exe and then they would be able to use your Dll with their computer because your Guids would be written to their registry.
If you’ve followed these steps you should be able to compile vbBdFtVolClient.bas and connect to the Visual Basic 6 ActiveX Dll. Just click on the Form when it becomes visible. Here are the contents of the vbBdFtVolClient project…
‘Main.inc
Type WndEventArgs
wParam As Long
lParam As Long
hWnd As Dword
hInst As Dword
End Type
Declare Function FnPtr(wea As WndEventArgs) As Long
Type MessageHandler
wMessage As Long
dwFnPtr As Dword
End Type
Global MsgHdlr() As MessageHandler
‘vbVolumes.inc !!!IMPORTANT!!! You need to make your own vbVolumes.inc from your computer!
'Visual Basic will have created different Guids on compile than these below!
'VB6 Interface Definitions -- vbVolumes.inc
$IID_IBdFtVols = GUID$("{22B0BB0B-8900-495B-99FF-8658A159A314}")
$IID_ICuFtVols = GUID$("{BF4CF49C-FCB2-484C-ACC5-D12AC8F95087}")
Interface IBdFtVols $IID_IBdFtVols : Inherit IDispatch
Property Get Species <1745027076> () As Integer
Property Set Species <1745027076> (ByVal Rhs As Integer)
Property Get Dbh <1745027075> () As Single
Property Set Dbh <1745027075> (ByVal Rhs As Single)
Property Get SawlogHeight <1745027074> () As Single
Property Set SawlogHeight <1745027074> (ByVal Rhs As Single)
Property Get Cull <1745027073> () As Integer
Property Set Cull <1745027073> (ByVal Rhs As Integer)
Property Get FormClass <1745027072> () As Integer
Property Set FormClass <1745027072> (ByVal Rhs As Integer)
Method PsuVolume <1610809350> () As Single
Method FormClassVolume <1610809351> () As Single
End Interface
Interface ICuFtVols $IID_ICuFtVols : Inherit IDispatch
Property Get Species <1745027075> () As Integer
Property Set Species <1745027075> (ByVal Rhs As Integer)
Property Get Dbh <1745027074> () As Single
Property Set Dbh <1745027074> (ByVal Rhs As Single)
Property Get SawlogHeight <1745027073> () As Single
Property Set SawlogHeight <1745027073> (ByVal Rhs As Single)
Property Get Cull <1745027072> () As Integer
Property Set Cull <1745027072> (ByVal Rhs As Integer)
Method PsuVolume <1610809349> () As Single
End Interface
‘vbBdFtVolClient.bas
#Compile Exe "vbBFVolClient"
#Include "Win32api.inc"
#Include "Main.inc"
#Include "vbVolumes.inc"
Function fnWndProc_OnLButtonDown(Wea As WndEventArgs) As Long ''This is vb's Form_Click()
Local szText As Asciiz*128
Local oBFVol As IBdFtVols
Local oCFVol As ICuFtVols
Local hDC As Dword
hDC=GetDC(Wea.hWnd)
Call SetBkMode(hDC,%TRANSPARENT)
oBFVol=NewCom "vbVolumes.vbBdFtVols"
If IsObject(oBFVol) Then
'Print "oBFVol Is An Object!"
oBFVol.Species = 30
oBFVol.Dbh = 16.0
oBFVol.SawlogHeight = 48.0
oBFVol.Cull = 0
oBFVol.FormClass = 78
szText="oBFVol.PsuVolume() = " & Str$(oBFVol.PsuVolume())
TextOut(hDC,0,0,szText,Len(szText))
szText="oBFVol.FormClassVolume() = " & Str$(oBFVol.FormClassVolume())
TextOut(hDC,0,18,szText,Len(szText))
Set oBFVol=Nothing
Else
MsgBox("Couldn't Connect To IBdFtVols!")
End If
oCFVol=NewCom "vbVolumes.vbCuFtVols"
If IsObject(oCFVol) Then
oCFVol.Species = 30
oCFVol.Dbh = 10.0
oCFVol.SawlogHeight = 48.0
oCFVol.Cull
szText="oCFVol.PsuVolume() = " & Str$(oCFVol.PsuVolume())
TextOut(hDC,0,36,szText,Len(szText))
Set oCFVol=Nothing
Else
MsgBox("Couldn't Connect To ICuFtVols!")
End If
Call ReleaseDC(Wea.hWnd,hDC)
fnWndProc_OnLButtonDown=0
End Function
Function fnWndProc_OnClose(Wea As WndEventArgs) As Long
Call PostQuitMessage(0)
Call DestroyWindow(Wea.hWnd)
fnWndProc_OnClose=0
End Function
Function fnWndProc(ByVal hWnd As Long,ByVal wMsg As Long,ByVal wParam As Long,ByVal lParam As Long) As Long
Local wea As WndEventArgs
Register iReturn As Long
Register i As Long
For i=0 To 1
If wMsg=MsgHdlr(i).wMessage Then
wea.hWnd=hWnd: wea.wParam=wParam: wea.lParam=lParam
Call Dword MsgHdlr(i).dwFnPtr Using FnPtr(wea) To iReturn
fnWndProc=iReturn
Exit Function
End If
Next i
fnWndProc=DefWindowProc(hWnd,wMsg,wParam,lParam)
End Function
Sub AttachMessageHandlers()
ReDim MsgHdlr(1) As MessageHandler 'Associate Windows Message With Message Handlers
MsgHdlr(0).wMessage=%WM_LBUTTONDOWN : MsgHdlr(0).dwFnPtr=CodePtr(fnWndProc_OnLButtonDown)
MsgHdlr(1).wMessage=%WM_CLOSE : MsgHdlr(1).dwFnPtr=CodePtr(fnWndProc_OnClose)
End Sub
Function WinMain(ByVal hIns As Long,ByVal hPrev As Long,ByVal lpCL As Asciiz Ptr,ByVal iShow As Long) As Long
Local szAppName As Asciiz*24,szTitle As Asciiz*64
Local wc As WndClassEx
Local hWnd As Dword
Local Msg As tagMsg
Call AttachMessageHandlers() : szAppName="vbVolumesClient"
wc.lpszClassName=VarPtr(szAppName) : wc.lpfnWndProc=CodePtr(fnWndProc)
wc.cbSize=SizeOf(wc) : wc.style=%CS_HREDRAW Or %CS_VREDRAW
wc.cbClsExtra=0 : wc.cbWndExtra=0
wc.hInstance=hIns : wc.hIcon=LoadIcon(%NULL, ByVal %IDI_APPLICATION)
wc.hCursor=LoadCursor(%NULL, ByVal %IDC_ARROW) : wc.hbrBackground=%COLOR_BTNFACE+1
wc.lpszMenuName=%NULL
Call RegisterClassEx(wc)
szTitle="Click Form To Connect To ActiveX Dll"
hWnd=CreateWindow(szAppName,szTitle,%WS_OVERLAPPEDWINDOW,200,100,325,300,0,0,hIns,ByVal 0)
Call ShowWindow(hWnd,iShow)
While GetMessage(Msg,%NULL,0,0)
TranslateMessage Msg
DispatchMessage Msg
Wend
Function=msg.wParam
End Function
I want to address a problem you might have. These two lines in fnWndProc_OnLButtonDown()…
Local oBFVol As IBdFtVols
Local oCFVol As IcuFtVols
Must correspond to the interface names in your vbVolumes.inc file. When it comes out of the COM Browser it likely won’t be as shown above. So it might be something that looks like this…
' Interface Name : I_vbBdFtVols
' Class Name : vbBdFtVols
' ClassID : $CLSID_vbBdFtVols
Interface I_vbBdFtVols $IID_I_vbBdFtVols
Inherit Idispatch
.
.
.
In that case, if you don’t change it, you would need this interface variable declaration…
Local oBFVol As I_vbBdFtVols
At this point you might be wondering how a person is supposed to know what can be changed and what can’t. All I can say is it’ll come to you eventually (maybe!). Actually, with COM the actual names of things aren’t as important as their GUIDs and memory layouts/structures.