- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am using DF 5.0. I have a problem to call a simple Dialog Box written in DLL from VB. It can be compiled, but can not be called by VB. (just shutdown the VB project). It appears DlgInit can not initialize the Dialog box. Maybe in version 6.x, one can use DlgInitWithResourcehandle, but in version 5.0D, there is no such function. From reference manual, I found Dlginit is compatible with Window Dll. My example below is working perfectly in QuickWin, but not in DLL. Can anyone help?
subroutine dgbox1()
use dfwin
use dflogm
implicit none
!dec$ attributes dllexport, alias : "dgbox1" :: dgbox1
!DEC$OBJCOMMENT LIB:"USER32.LIB"
include 'resource.fd'
type (dialog) dlg
logical retlog
integer retint
retlog = DlgInit(idd_box,dlg)
if (.not. retlog) then
write (*,*) "Error: dialog not found"
endif
retint = dlgmodal(dlg)
call dlguninit(dlg)
end
Also I used resource editor to created a Dialog and my VB codes are
Declare sub dgbox1 lib "dgbox.dll" () in Module and
call dgbox in Form
subroutine dgbox1()
use dfwin
use dflogm
implicit none
!dec$ attributes dllexport, alias : "dgbox1" :: dgbox1
!DEC$OBJCOMMENT LIB:"USER32.LIB"
include 'resource.fd'
type (dialog) dlg
logical retlog
integer retint
retlog = DlgInit(idd_box,dlg)
if (.not. retlog) then
write (*,*) "Error: dialog not found"
endif
retint = dlgmodal(dlg)
call dlguninit(dlg)
end
Also I used resource editor to created a Dialog and my VB codes are
Declare sub dgbox1 lib "dgbox.dll" () in Module and
call dgbox in Form
Link Copied
10 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Um, the only place I'd expect DFLOGM to fail is DlgModal,
not DlgInit. Having taken a look into DlgInit, the only place
that might fail is call to .cpp routine DlgGetRes. Its equivalent
in Fortran is:
The documentation for FindResource says that, quote,
"hModule - A handle to the module whose executable file contains the resource. A value of NULL specifies the module handle associated with the image file that the operating system used to create the current process. "
It's not very clear, but it looks that the NULL in FindResource call
specifies that the resource should be looked for in calling VB program,
not in DLL itself.
If you're brave enough - and if it's important - I'd suggest that you
try to fix the problem by tweaking DFLOGM a little (my favourite sport :-)).
to
4) Add the following code at the beginning of DlgGetRes1:
replace NULLs in calls to FindResource and LoadResource with
hModule.
5) Compile the DLL & prey. In any case, try to debug carefully and
step into all functions in DFLOGM. I'm 99% sure I screwed up something
in the explanation above. The basic idea was to replace the DlgGetRes
with the one that searches for resource in DLL, not in calling VB exe...
Perhaps the last piece of code (involving GetModuleHandle) could have
been written more ellegantly, but right now I can't recall the way to
get the name of "this" module (exe or dll). Perhaps renaming of MODULE DFLOGM into something else will be necessary (I don't know the default search rules for modules). Even if this succeeds, you might have a problem later in DlgModal, since it calls GetHwndQQ(QWIN$FRAMEWINDOW), but then... post another message.
Regards
Jugoslav
P.S. Try to enclose the posted code in
not DlgInit. Having taken a look into DlgInit, the only place
that might fail is call to .cpp routine DlgGetRes. Its equivalent
in Fortran is:
LOGICAL FUNCTION DlgGetRes(ID,lpDlgRsrc) USE DFWIN INTEGER:: hRsrc, hGlob INTEGER:: lpDlgRsrc hrsrc = FindResource( NULL, ID, RT_DIALOG ); IF (hrsrc == NULL) THEN DlgGetRes=.FALSE. RETURN END IF hGlob = LoadResource( NULL, hrsrc ) IF (hGlob == NULL) THEN DlgGetRes=.FALSE. RETURN END IF lpDlgRsrc = LockResource( hGlob ) END FUNCTION
The documentation for FindResource says that, quote,
"hModule - A handle to the module whose executable file contains the resource. A value of NULL specifies the module handle associated with the image file that the operating system used to create the current process. "
It's not very clear, but it looks that the NULL in FindResource call
specifies that the resource should be looked for in calling VB program,
not in DLL itself.
If you're brave enough - and if it's important - I'd suggest that you
try to fix the problem by tweaking DFLOGM a little (my favourite sport :-)).
1) Copy DFLOGM.f90 from DevStudio/DF/Include into your project directory. Add it to the project.
2) Add the above code somewhere inside MODULE DFLOGM. Rename it
to, say, DlgGetRes1.
3) Change the following lines in DlgInit from
type (DialogResource) dlgres, dlgres2 ... if ( .not. DlgGetRes( id, dlgres ) ) then ... dlgres=dlgres2
to
type (DialogResource) dlgres, dlgres2 pointer(pdlgres,dlgres) pointer(pdlgres2,dlgres2) ... if ( .not. DlgGetRes1( id, pdlgres) ) then ... pdlgres2=pdlgres
4) Add the following code at the beginning of DlgGetRes1:
integer hModule hModule=GetModuleHandle('MyDllName.dll')
replace NULLs in calls to FindResource and LoadResource with
hModule.
5) Compile the DLL & prey. In any case, try to debug carefully and
step into all functions in DFLOGM. I'm 99% sure I screwed up something
in the explanation above. The basic idea was to replace the DlgGetRes
with the one that searches for resource in DLL, not in calling VB exe...
Perhaps the last piece of code (involving GetModuleHandle) could have
been written more ellegantly, but right now I can't recall the way to
get the name of "this" module (exe or dll). Perhaps renaming of MODULE DFLOGM into something else will be necessary (I don't know the default search rules for modules). Even if this succeeds, you might have a problem later in DlgModal, since it calls GetHwndQQ(QWIN$FRAMEWINDOW), but then... post another message.
Regards
Jugoslav
P.S. Try to enclose the posted code in
andHTML tags (replace ['s with <'s)... Forum software... sigh.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jugoslav, thanks for the help. I need to study your approach. But I think DlgInit is the problem. Try this
subroutine dgbox()
use dfwin
use dflogm
!dec$ attributes dllexport, alias: "dgbox" :: dgbox
!dec$objcomment lib: "user32.lib"
logical retlog
integer retint
type(dialog) dlg
retlog = dlginit(idd_box, dlg)
if (.not. retlog) then
retlog = AllocConsole()
write(*,*) "Error, resource not found"
retlog = FreeConsole
else
retlog = dlgmodal(dlg)
endif
end subroutine dgbox
You can see it DlgInit = false.
subroutine dgbox()
use dfwin
use dflogm
!dec$ attributes dllexport, alias: "dgbox" :: dgbox
!dec$objcomment lib: "user32.lib"
logical retlog
integer retint
type(dialog) dlg
retlog = dlginit(idd_box, dlg)
if (.not. retlog) then
retlog = AllocConsole()
write(*,*) "Error, resource not found"
retlog = FreeConsole
else
retlog = dlgmodal(dlg)
endif
end subroutine dgbox
You can see it DlgInit = false.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jugoslav, it does not work when I tried your approach. I can not even compiled the code. I got error message like Error: This statement is invalid in an INTERFACE block.
hModule = GetModuleHandle('MyDllName.dll')
Is there any other way to do this. I wish someone from Compaq can give an answer.
hModule = GetModuleHandle('MyDllName.dll')
Is there any other way to do this. I wish someone from Compaq can give an answer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, I did say "if you're brave enough" :-). And, as I promised, I did
screwed up something in the code. Finally, I did actually try to
modify DFLOGM.
Apparently, you inserted the DlgGetRes1 into INTERFACE section,
not into module itself. Let's start from the beginning... so, re-copy
original DFLOGM.f90, and do _only_ these two modifications:
Add the following DlgGetRes1 immediately before line
"END MODULE DFLOGM" (at the end of file):
And only replace call to DlgGetRes (in DlgInit) with
call to DlgGetRes1. (Do not insert POINTER declarations etc.).
Now, recompile and try. It would be a good idea to put a
breakpoint at first line of DlgGetRes1 and watch return values
of functions, especially hModule.
I did not find time to try it with DLL - it
works in an .exe... I just think it should work in the DLL
also. Of course, the method is not universal, since it depends
on value of szModuleName (i.e. name of the dll itself)...
Regards
Jugoslav
screwed up something in the code. Finally, I did actually try to
modify DFLOGM.
Apparently, you inserted the DlgGetRes1 into INTERFACE section,
not into module itself. Let's start from the beginning... so, re-copy
original DFLOGM.f90, and do _only_ these two modifications:
Add the following DlgGetRes1 immediately before line
"END MODULE DFLOGM" (at the end of file):
LOGICAL FUNCTION DlgGetRes1(ID,DlgRsrc) USE DFWIN CHARACTER(LEN=20):: szModuleName='dgbox.dll'C INTEGER:: ID, hRsrc, hGlob, hModule TYPE(DialogResource):: DlgRsrc hModule=GetModuleHandle(LOC(szModuleName)) hrsrc = FindResource( hModule, ID, RT_DIALOG ); IF (hrsrc == NULL) THEN DlgGetRes1=.FALSE. RETURN END IF hGlob = LoadResource( hModule, hrsrc ) IF (hGlob == NULL) THEN DlgGetRes1=.FALSE. RETURN END IF DlgRsrc%ptr = LockResource( hGlob ) DlgGetRes1 = DlgRsrc%ptr .NE. 0 END FUNCTION DlgGetRes1
And only replace call to DlgGetRes (in DlgInit) with
call to DlgGetRes1. (Do not insert POINTER declarations etc.).
Now, recompile and try. It would be a good idea to put a
breakpoint at first line of DlgGetRes1 and watch return values
of functions, especially hModule.
I did not find time to try it with DLL - it
works in an .exe... I just think it should work in the DLL
also. Of course, the method is not universal, since it depends
on value of szModuleName (i.e. name of the dll itself)...
Regards
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jugoslav, following the procedures you provided, it passed compile, and it seems DlgInit is initializing, but the Dialog Box is still not shown up. I guess it is what you talked erlier that DlgModal is a problem. Anyway to fix it? I really appreciate your time and help.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What is the return value of DlgModal? Is it -1? If so, perhaps the problem is similar to the previous one: DialogBox tries to locate the resource in VB caller, not in Dll itself. Try adding the following lines in DlgModal:
(Replace existing if (DlgDoModal...else...endif with the above block.)
Also, find the body of DlgProc function and add the following line immediately after "recursive function DlgProc(..."
!DEC$ATTRIBUTES STDCALL:: DlgProc
I hope that would finally fix the thing.
Regards
Jugoslav
recursive function DlgModal ( dlg, hwndParent ) result use dfwin integer hModule character*20:: szModuleName='dgbox.dll'C ... hModule=GetModuleHandle(LOC(szModuleName)) if ( DialogBox (hModule, MAKEINTRESOURCE(dlg % dlgid), hwndParent, LOC(DlgProc) ) .eq. -1 ) then r=-1 else r = dlg % retval end if ...
(Replace existing if (DlgDoModal...else...endif with the above block.)
Also, find the body of DlgProc function and add the following line immediately after "recursive function DlgProc(..."
!DEC$ATTRIBUTES STDCALL:: DlgProc
I hope that would finally fix the thing.
Regards
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Something was wrong when compile it. I got 58 error messages. I could not find Dialogbox defined anywhere in Dflogm.f90. Is that a problem? I tried several ways but got nowhere. I still need your kind help. Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
BTW, the return value is -1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Unfortunately, time-zone difference makes this discussion lasting
for days. It looks as if I leave my job about at the same time when
you start yours :-(.
The fragment from DlgModal I posted yesterday is syntactically OK
(I tested it) and I think it does the job. You just have to be more
careful when editing. DlgModal already exists in DFLOGM; just
add lines
and replace the if-block in the original DlgModal with
the if-block in the above code.
DialogBox is not part of the DFLOGM module; it is a system
(API) function which can be accessed by putting USE DFWIN
as the first line of FUNCTION or MODULE.
If you still cannot solve the problem, please post first 4-5
error messages you get - and/or please leave your e-mail so
I could send you the working DFLOGM.
Regards
Jugoslav
for days. It looks as if I leave my job about at the same time when
you start yours :-(.
The fragment from DlgModal I posted yesterday is syntactically OK
(I tested it) and I think it does the job. You just have to be more
careful when editing. DlgModal already exists in DFLOGM; just
add lines
use dfwin integer:: hModule character(len=20):: szModuleName="dgbox.dll"C
and replace the if-block in the original DlgModal with
the if-block in the above code.
DialogBox is not part of the DFLOGM module; it is a system
(API) function which can be accessed by putting USE DFWIN
as the first line of FUNCTION or MODULE.
If you still cannot solve the problem, please post first 4-5
error messages you get - and/or please leave your e-mail so
I could send you the working DFLOGM.
Regards
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is the error:
dflogm.lib(dflogm.obj) : error LNK2005: _DFLOGM_mp_LOG2INT@4 already defined in Dflogm.obj
dflogm.lib(dflogm.obj) : error LNK2005: _DFLOGM_mp_STRFOR2C@12 already defined in Dflogm.obj
dflogm.lib(dflogm.obj) : error LNK2005: _DFLOGM_mp_STRC2FOR@4 already defined in Dflogm.obj
dflogm.lib(dflogm.obj) : error LNK2005: _DFLOGM_mp_PADSTRFOR@8 already defined in Dflogm.obj
I really appreciate if you can e-maol me the DFLOmG.f90. My e-mail address is
rshen@hotmail.com
dflogm.lib(dflogm.obj) : error LNK2005: _DFLOGM_mp_LOG2INT@4 already defined in Dflogm.obj
dflogm.lib(dflogm.obj) : error LNK2005: _DFLOGM_mp_STRFOR2C@12 already defined in Dflogm.obj
dflogm.lib(dflogm.obj) : error LNK2005: _DFLOGM_mp_STRC2FOR@4 already defined in Dflogm.obj
dflogm.lib(dflogm.obj) : error LNK2005: _DFLOGM_mp_PADSTRFOR@8 already defined in Dflogm.obj
I really appreciate if you can e-maol me the DFLOmG.f90. My e-mail address is
rshen@hotmail.com
![](/skins/images/C4F7392A5C68ACA60290C9576F107044/responsive_peak/images/icon_anonymous_message.png)
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