- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear All,
I'm having no success in initiating dialog boxes from a Fortran DLL used from VB6.
The DLGINITWITHRESOURCEHANDLE function always returns false. I've constructed
a simple example based on ones on the Compaq online documentation. Can anybody
see what I'm doing wrong?
Thanks,
Russell Millar
=================
Fortran Code
===================
!===================================================================
! Code copied from DLGINITWITHRESOURCEHANDLE documentation example
!===================================================================
module dll_globals
integer(4) ghInst ! DLL instance handle
end module dll_globals
!********************************************************************
!* FUNCTION: DllMain(HANDLE, DWORD, LPVOID)
!*
!* PURPOSE: DllMain is called by Windows when
!* the DLL is initialized, Thread Attached, and other times.
!* Refer to SDK documentation, as to the different ways this
!* may be called.
!*
!* The DllMain function should perform additional initialization
!* tasks required by the DLL. DllMain should return a value of 1
!* if the initialization is successful.
!*
!*********************************************************************
integer(4) function DllMain (hInst, ul_reason_being_called, lpReserved)
!DEC$ ATTRIBUTES DLLEXPORT :: DllMain
!DEC$ ATTRIBUTES ALIAS:'DllMain' :: DllMain
use dll_globals
integer(4) hInst
integer(4) ul_reason_being_called
integer(4) lpReserved
! Save the module instance handle in a global variable
! This would typically be in a Module or a COMMON block.
ghInst = hInst
DllMain = 1
return
end
!===================================================================
! Modified Compaq DLL VB6 example
! Fortran part of a VB-Fortran DLL example. This
! routine DLL_ROUT is called from a VB executable
! program.
!===================================================================
SUBROUTINE DLL_ROUT (STR_IN, STR_OUT)
! Specify that DLL_ROUT is exported to a DLL
! and that the external name is 'DLL_ROUT'
!DEC$ ATTRIBUTES DLLEXPORT :: DLL_ROUT
!DEC$ ATTRIBUTES ALIAS:'DLL_ROUT' :: DLL_ROUT
USE DFLOGM
USE dll_globals
IMPLICIT NONE
INCLUDE "resource.fd"
CHARACTER*(*) STR_IN, STR_OUT
type (DIALOG) dlg
logical lret
integer iret
lret = DLGINITWITHRESOURCEHANDLE (IDD_DIALOG1, ghInst, dlg)
if (lret) then
iret = DlgModal(dlg)
call DlgUninit(dlg)
STR_OUT=STR_IN // "succeeded"
else
STR_OUT=STR_IN // "failed"
end if
RETURN
END
================================
VB6 base module
=================================
Option Explicit
Declare Sub DLL_ROUT Lib _
"C:Documents and SettingsRussellMy DocumentsMyVBStuffDLLPlayFCALL4DebugFCALL4.dll" _
(ByVal STR_IN As String, ByVal STR_IN_LEN As Long, _
ByVal STR_OUT As String, ByVal STR_OUT_LEN As Long)
Declare Function DllMain Lib _
"C:Documents and SettingsRussellMy DocumentsMyVBStuffDLLPlayFCALL4DebugFCALL4.dll" _
(hInst As Long, Int1 As Long, Int2 As Long) As Long
====================
VB Form1
====================
Option Explicit
Private hInst As Long
Private Int1 A s Long
Private Int2 As Long
Private Flag As Long
Private Sub Command1_Click()
Static STR_IN As String * 10, STR_OUT As String * 20
STR_IN = "Test..."
Int1 = 1
Int2 = 2
hInst = App.hInstance
'TextBox1.Text = "hinstance=" & hInst & _
", Flag=" & Flag
Flag = DllMain(hInst, Int1, Int2)
'Pass lengths of string arguments
Call DLL_ROUT(STR_IN, Len(STR_IN), STR_OUT, Len(STR_OUT))
TextBox1.Text = STR_OUT & ", hinstance=" & hInst & _
", Flag=" & Flag
End Sub
I'm having no success in initiating dialog boxes from a Fortran DLL used from VB6.
The DLGINITWITHRESOURCEHANDLE function always returns false. I've constructed
a simple example based on ones on the Compaq online documentation. Can anybody
see what I'm doing wrong?
Thanks,
Russell Millar
=================
Fortran Code
===================
!===================================================================
! Code copied from DLGINITWITHRESOURCEHANDLE documentation example
!===================================================================
module dll_globals
integer(4) ghInst ! DLL instance handle
end module dll_globals
!********************************************************************
!* FUNCTION: DllMain(HANDLE, DWORD, LPVOID)
!*
!* PURPOSE: DllMain is called by Windows when
!* the DLL is initialized, Thread Attached, and other times.
!* Refer to SDK documentation, as to the different ways this
!* may be called.
!*
!* The DllMain function should perform additional initialization
!* tasks required by the DLL. DllMain should return a value of 1
!* if the initialization is successful.
!*
!*********************************************************************
integer(4) function DllMain (hInst, ul_reason_being_called, lpReserved)
!DEC$ ATTRIBUTES DLLEXPORT :: DllMain
!DEC$ ATTRIBUTES ALIAS:'DllMain' :: DllMain
use dll_globals
integer(4) hInst
integer(4) ul_reason_being_called
integer(4) lpReserved
! Save the module instance handle in a global variable
! This would typically be in a Module or a COMMON block.
ghInst = hInst
DllMain = 1
return
end
!===================================================================
! Modified Compaq DLL VB6 example
! Fortran part of a VB-Fortran DLL example. This
! routine DLL_ROUT is called from a VB executable
! program.
!===================================================================
SUBROUTINE DLL_ROUT (STR_IN, STR_OUT)
! Specify that DLL_ROUT is exported to a DLL
! and that the external name is 'DLL_ROUT'
!DEC$ ATTRIBUTES DLLEXPORT :: DLL_ROUT
!DEC$ ATTRIBUTES ALIAS:'DLL_ROUT' :: DLL_ROUT
USE DFLOGM
USE dll_globals
IMPLICIT NONE
INCLUDE "resource.fd"
CHARACTER*(*) STR_IN, STR_OUT
type (DIALOG) dlg
logical lret
integer iret
lret = DLGINITWITHRESOURCEHANDLE (IDD_DIALOG1, ghInst, dlg)
if (lret) then
iret = DlgModal(dlg)
call DlgUninit(dlg)
STR_OUT=STR_IN // "succeeded"
else
STR_OUT=STR_IN // "failed"
end if
RETURN
END
================================
VB6 base module
=================================
Option Explicit
Declare Sub DLL_ROUT Lib _
"C:Documents and SettingsRussellMy DocumentsMyVBStuffDLLPlayFCALL4DebugFCALL4.dll" _
(ByVal STR_IN As String, ByVal STR_IN_LEN As Long, _
ByVal STR_OUT As String, ByVal STR_OUT_LEN As Long)
Declare Function DllMain Lib _
"C:Documents and SettingsRussellMy DocumentsMyVBStuffDLLPlayFCALL4DebugFCALL4.dll" _
(hInst As Long, Int1 As Long, Int2 As Long) As Long
====================
VB Form1
====================
Option Explicit
Private hInst As Long
Private Int1 A s Long
Private Int2 As Long
Private Flag As Long
Private Sub Command1_Click()
Static STR_IN As String * 10, STR_OUT As String * 20
STR_IN = "Test..."
Int1 = 1
Int2 = 2
hInst = App.hInstance
'TextBox1.Text = "hinstance=" & hInst & _
", Flag=" & Flag
Flag = DllMain(hInst, Int1, Int2)
'Pass lengths of string arguments
Call DLL_ROUT(STR_IN, Len(STR_IN), STR_OUT, Len(STR_OUT))
TextBox1.Text = STR_OUT & ", hinstance=" & hInst & _
", Flag=" & Flag
End Sub
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
A brief explanation first: HINSTANCE or HMODULE is Windows' handle of a module -- an exe or a dll. Physically, it presents base (starting) address of module's code+data+resources. Resource-management function need this handle to "see" where they should start looking at requested resource (dialog in this case).
hInstance for .exes always have value of 0x00400000 because that's the default start of .exe's address space in virtual memory. For .dlls, it's another value.
Are you sure DllMain is actually being called? If I recall correctly, the compiler supplies the default entry-point function if you don't write it -- but if you do, you have to say it to the linker in Project Settings/Link/Output/Entry-point symbol.
Besides, your DllMain looks wrong: hInst is passed by value, but it isn't specified in your DllMain -- without a VALUE or STDCALL modifier, it is being read as by reference, i.e. it contains garbage.
So, it should be:
Jugoslav
hInstance for .exes always have value of 0x00400000 because that's the default start of .exe's address space in virtual memory. For .dlls, it's another value.
Are you sure DllMain is actually being called? If I recall correctly, the compiler supplies the default entry-point function if you don't write it -- but if you do, you have to say it to the linker in Project Settings/Link/Output/Entry-point symbol.
Besides, your DllMain looks wrong: hInst is passed by value, but it isn't specified in your DllMain -- without a VALUE or STDCALL modifier, it is being read as by reference, i.e. it contains garbage.
So, it should be:
integer(4) function DllMain (hInst, ul_reason, lpReserved) !DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: DllMain use dll_globals integer(4) hInst, ul_reason, lpReserved ghInst = hInst DllMain = 1 end function DllMainAlso, specify
dllmain@8(case matters) as entry-point symbol in linker settings.
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
...ah, I missed that call to DllMain in your VB code -- it explains a lot. You mustn't call DllMain explicitly -- you shouldn't even dllexport it. DllMain is automatically called by Windows when the dll is loaded (thus the need to specify it in linker settings). What you were doing is to pass hInstance of VB .exe -- DlgInitWithResourceHandle was trying to load the dialog from VB exe, not from your dll, and thus it failed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
...d'oh, it should be dllmain@12, obviously :-(
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jugoslav,
Thanks for the clear explanation - worked first time after making the changes.
I've been running DLL's that hadn't used a DllMain, and I hadn't realized
the special role of a DllMain when used in a DLL.
Russell
Thanks for the clear explanation - worked first time after making the changes.
I've been running DLL's that hadn't used a DllMain, and I hadn't realized
the special role of a DllMain when used in a DLL.
Russell

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page