- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am trying to implement a progress bar inside a Fortran DLL (CVF 6.6C3). The DLL is called from a VB6 dialog. I have tried to use Jugoslavs ThreadDlg, have tried to use the sample DLLPRGRS, have read almost all relevant topics in this forum and in on-line help, but I have been more and more confused:
- Jugoslavs example is called from a console;
- DLLPRGRS creates a main dialog and then calls the progress bar. This example uses WinMain function and calls DlgInit;
- On-line help states that one should rather call DlgInitWithResourceHandle and recommends DLLMain function;
- And I cannot find some how to in this forum either.
Could anyone please post a step-by-step how to here?
The structure of my application is as following:
A VB dialog containing text boxes and buttons calls a Fortran MyDLL;
MyDLL looks something like this:
Subroutine MyDLL (,,,,)
Use MyModule
Call Sub1
Call Sub2
Call Sub3(,,,)
END
Inside Sub3 I have time-consuming calculations and what I am trying to do is to show a progress bar from within this subroutine:
Subroutine Sub3(,,,)
Use MyModule
DO
-->Show the progress bar
END DO
End Subroutine Sub3
Any help would be appreciated.
Regards,
Sabalan.
Message Edited by Sabalan on 07-01-2004 05:20 AM
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Jugoslav for your response.
1) I suspect that callback from DLL to VB would make the thing more complicated. I think it would be much easier to open a new dialog from within DLL, show only the progress bar without any buttons, and kill this dialog when the loop is done and before returning to the VB interface;
2) I was more confused with DllPrgrs than with your ThreadDLL and I think your auxiliary thread is perhaps an easier solution.
Sabalan.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
integer function DMS_ProgressProc(nPercent)
!DEC$ATTRIBUTES STDCALL:: DMS_ProgressProc
integer:: nPercent
end function
end interface
pointer(pProgressProc, DMS_ProgressProc)
nIter = nIter + 1
iPercent = nint(100*real(nIter)/nTotalIter)
if (iPercent.ne.iPrevPercent) then
if (DMS_ProgressProc(iPercent).eq.0) then
iError = DMSERR_CANCELLED
call ErrHandler(1, iError)
return
end if
iPrevPercent = iPercent
end if
end if
Message Edited by JugoslavDujic on 06-29-2004 02:28 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much Jugoslav for your help. I had to find my own way anyway!
What got me most confused was the relationship between WinMain or DllMain described in the sample DllPrgrs or on-line documentation, and my own DLL. I wasnt sure if a WinMain or DllMain was needed except for my own DLL or not, and how I should call WinMain or DllMain. I discovered at last LoadLibrary and solved the problem. Now the progress bar works and I will try to write here a step-by-step instruction for a simplest possible (I think?) progress bar. Iask all experts here to look at this and let me know if I am doing something wrong (loading MyDLL twice, memory leak, etc.?).
1-Create a simple progress bar dialog without any buttons in CVF in a DLL or Win32 application. Save this project as ProgressBar;
2-Add the files ProgressBar.rc, Resource.fd and Resource.h to your project MyDLL if you created the ProgressBar in a separate project other than MyDLL;
3-You need a module MyGlobals for global variables in MyDLL if you plan not to showing the progress bar in the SUBROUTINE MyDLL itself and progress bar is going to appear later on in some other subroutine;
4-The above module is going to contain:
Module MyGlobals
(your other global variables)
Integer ghInst
End Module MyGlobals
5- Your main DLL is going to look like this:
Subroutine MyDLL (,,,,)
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL :: MyDLL
!DEC$ ATTRIBUTES ALIAS : 'MyDLL' :: MyDLL
Use DFWin
Use MyGlobals
Logical lret
ghInst = LoadLibrary("MyDLL.dll"C) ! ghInst is saved in MyGlobalsand will be used later
Call Sub1
Call Sub2
Call Sub3(,,,) ! In this sub. you want to show the progress bar
lret = FreeLibrary(ghInst)! You must run this after LoadLibrary
END
6- The Sub3 where you want to show the progress bar looks like this:
Subroutine Sub3(,,,)
Use DFWin
Use DFLOGM
Use MyGlobals
Include Resource.fd
Type (Dialog):: dlg
Type (T_MSG) :: mseg
Logical lret, lNotQuit
Integer Duration, Iter, iret
...
lret = DlgInitWithResourceHandle (IDD_DIALOG1, ghInst, Dlg) ! ghInst is used here
lret = DlgSet(Dlg, IDC_PROGRESS, 0, DLG_RANGEMIN)
Duration = (a number suitable for the duration of your long-lasting calculation, say, 100, 1000. Test to find!)
lret = DlgSet(Dlg, IDC_PROGRESS, Duration, DLG_RANGEMAX)
lret = DlgSet(Dlg, IDC_PROGRESS, 0)
lret = DlgModeless(Dlg)
Iter = 0
DO (your calculation)
! Show the progress bar here
Iter = Iter + 1
lret = DlgSet(Dlg, IDC_PROGRESS, Iter)
! Dispatch all pending window messages
lNotQuit = .true.
Do while ( lNotQuit .and. (PeekMessage(mesg, 0, 0, 0, PM_NOREMOVE) .ne. 0) )
lNotQuit = GetMessage(mesg, NULL, 0, 0)
if (lNotQuit) then
if ( DlgIsDlgMessage(mesg) .EQV. .FALSE. ) then
lret = TranslateMessage( mesg )
iret = DispatchMessage( mesg )
end if
end if
END DO
END DO
Call DlgExit(Dlg)
CALL DlgUnInit(Dlg) ! with these 2 CALLs you kill the progress bar dialog
End Subroutine Sub3
7- You declare MyDLL in VB as usaual and CALL it as usual!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I looked it and it's quite OK. Just a comment on message loop:
Do while ( lNotQuit .and. (PeekMessage(mesg, 0, 0, 0, PM_NOREMOVE) .ne. 0) )
lNotQuit = GetMessage(mesg, NULL, 0, 0)
if (lNotQuit) then
if (mesg.message .eq. WM_QUIT) then
The PostMessage(WM_QUIT) will end up in the "parent" message loop, properly terminating the application (provided that you don't call PeekMessage for it anymore).
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Jugoslav for all your comments.
I use now ghInst = GetModuleHandle("MyDLL.dll"C) inside SUB3 and this way the module MyGlobals and saving ghInst in it is not needed. I had to remove FreeLibrary too because I get access violation error for RETURN and/or END for the obvious reason that after FreeLibrary which is called after GetModuleHandle, there is no loaded DLL left to END.
Regarding WM_QUIT, i don't care about it because the user is not able to quit my application while the calcuations are going on! :-)
Sabalan.

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