WinMain and Dll's

WinMain and Dll's

Community Admin的头像

I have a standard windows project I am working on and it works great as an exe. I would like to compile it as a DLL, but I'm not sure how to structure the begining of the main program. As it is now:

integer function WinMain( hInstance, hPrevInstance, lpCmdLine, nCmdShow )
!DEC$ IF DEFINED (_X86_)
!DEC$ attributes stdcall, alias: '_WinMain@16' :: WinMain
!DEC$ ELSE
!DEC$ attributes stdcall, alias: 'WinMain' :: WinMain
!DEC$ ENDIF

I am trying to create a DLL that I can pass two variables(file path, error flag) to. I can do this easily with a standard console app, but I'm not sure how to do it when you use winmain.

Any help would be greatly appreciated.

7 帖子 / 0 全新
最新文章
如需更全面地了解编译器优化,请参阅优化注意事项
Jugoslav Dujic的头像

WinMain is entry-point for all Windows executables. If you recompile your project as a dll WinMain will not be called, thus you can either leave it or delete it -- it won't change the substance.

However, it still depends whether you want the dll to create windows and perform graphical operations (which is not usual). Since WinMain won't be called, you (probably) won't get any windows. If that's the case, please repost with more detailed description what you want to do.

Jugoslav

Jugoslav www.xeffort.com
Community Admin的头像

Jugoslav,
That is my problem. I want to have a window created and have all of the graphics capabilities. I have a VB calling program where a user specifies a bunch of input parameters, one of which is the work path. I want to pass that work path to the DLL (so it knows where to find its input files) then open a window, run some graphics routines, then close the window and return to the VB calling program.

Jugoslav Dujic的头像

I see. I assume by "close the window" you meant "user closes the window"; otherwise, that would happen so fast that user could see only a window appearing and disappearing in a flash.

In theory, what you want is possible. As a first step, I suggest you just rename WinMain into something else, change arguments as you wish and dllexport it, then try calling it. Message loop in the WinMain should drive Fortran's and VB's windows just fine. You can even have modal appearance of your window if you EnableWindow(hVBParent, .FALSE.). PostQuitMessage for your main window should exit that message loop and cause WinMain to reach its end.

If your win32 app loads some resources (dialogs, bitmaps, icons), take care that you cannot use hInstance or GetModuleHandle(NULL). That'd be now the handle of VB caller exe. You either have to use GetModuleHandle("myapp.dll"C) or write a DllEntryPoint function and copy hinstDll into some global hgInstance. (VF provides a DllEntryPoint by default if you don't write one. See docs.)

Further, as happens with normal PROGRAMs when turned into subroutine, take care about cleanup at WinMain's end. Normally, you don't care about freeing resources/memory when exiting from an .exe -- Windows does it for you. But note that in this case you should properly clear after execution in case you'd be called for the second time. So, be careful to do DeleteObject, UnregisterClass, deallocate, close, etc. etc. after exiting message loop.

So, I suggest you try playing with it a little and come again if you encounter some serious problems.

HTH

Jugoslav

Jugoslav www.xeffort.com
Community Admin的头像

I actually don't want the user to see anything at all. I am just creating some bitmaps so I am really just writing to a buffer. I have it so the window never is shown to the user.

If I change :

integer function WinMain( hInstance, hPrevInstance, lpCmdLine, nCmdShow )

to have the peramiters I want to pass to it :

integer function MyDll( hInstance, hPrevInstance, lpCmdLine, nCmdShow, pathname, error_flag)

woun't that screw up the windows form? Also when I call it from VB do I have to pass hInstance, hPrevInstance, lpCmdLine, nCmdShow to it as well? My experience with the windows graphics API is limited.

Thanks!

Jugoslav Dujic的头像

If you want to keep the same source for dll and exe, that'll go a bit hard. Something can be done with preprocessor, i.e:

!DEC$IF DEFINED (DLL) 
subroutine foo(szPath, iError) 
!DEC$ATTRIBUTES DLLEXPORT:: foo 
character(*) szPath 
!DEC$ELSE 
integer function WinMain(hInst, hPrevInst, lpCmdLine, nCmdShow) 
... 
!DEC$ENDIF

Further, in dll version you wouldn't want message loop at all, etc. etc.

But why not simply extract the job with bitmap export in a separate routine in a separate source file and recompile only that file as a dll? Trying to convert WinMain to do a relatively simple single task looks like an overkill to me. Windows apps are supposed to be user-interactive; you're actually trying to remove user-interactivity and confine the code to a far simpler task.

Jugoslav www.xeffort.com
Community Admin的头像

It seems, you need to understand/explain clearly the algorithm/scheme you want to realize. There are two possible variants:
1. You could call your FORTRAN Windows application using for input parameters transfer the formal parameter of WinMain - lpCmdLine - pointer to command line string. But, if you want to organize some interaction VB<->FORTRAN, then you'll have problem with "output parameters" ( results ). So this variant looks like correct for "one-way" interaction.
2. You could transform your program into new form - actually WinMain is not necessary ( absolutely! ). Really, you need to create 3 main blocks in DLL - first one registers the window class and loads necessary resources; second one - some subroutine, which receives the VB calling window handle as input parameter and creates CHILD window, which realizes your algorithm etc. Very good choice - create this window as MODAL dialog. It'll allow you to ignore all problems with messages loop - VB'll perform all necessary actions for you. After this, you will create your previous window as child in this modal dialog. Such approach ( with modal dialog ) allows you to perform all necessary actions very correct: a) initialize/register window class; b) create modal dialog ( your VB block will be locked until FORTRAN program/window will be closed ); c) uninitialize/unregister all classes, resources etc. I think, that it's the way for you to realize your idea with minimal expences.

Hope this helps,
Vladimir V.Vasilchenko

Fortran Programmers Club

http://www.donpac.ru/usr/golub/fortran/

http://fortran-windows.tripod.com

登陆并发表评论。