Windows API programming with gfortran or g95

  • Follow


This issue hasn't been mentioned for a while so I hope you don't mind
me bringing it up again. Has there been any progress made on writing
windows api programs using one of the free compilers (g95 or
gfortran)? I remember there was some discussion about "decorating"
function names and stdcall calling convention.. but it all seemed to
come to nothing.

Currently I can program windows apps in Intel Fortran or in gcc (using
C language) but not in gfortran.

Also, is it possible to call OpenGL or DirectX from fortran (Intel or
gfortran/gcc?). I'd like to do some 3D graphics eventually.

Thanks for your help with this.
0
Reply The 7/19/2010 3:13:07 PM

On Jul 19, 8:13=A0am, The Star King <j...@npl.co.uk> wrote:
> This issue hasn't been mentioned for a while so I hope you don't mind
> me bringing it up again. Has there been any progress made on writing
> windows api programs using one of the free compilers (g95 or
> gfortran)? I remember there was some discussion about "decorating"
> function names and stdcall calling convention.. but it all seemed to
> come to nothing.

Have you checked the gfortran wiki?

--
steve
0
Reply steve 7/19/2010 3:35:43 PM


On Jul 19, 4:35=A0pm, steve <kar...@comcast.net> wrote:
> On Jul 19, 8:13=A0am, The Star King <j...@npl.co.uk> wrote:
>
> > This issue hasn't been mentioned for a while so I hope you don't mind
> > me bringing it up again. Has there been any progress made on writing
> > windows api programs using one of the free compilers (g95 or
> > gfortran)? I remember there was some discussion about "decorating"
> > function names and stdcall calling convention.. but it all seemed to
> > come to nothing.
>
> Have you checked the gfortran wiki?
>
> --
> steve

Yes, can't find any mention of Windows API programming there. Am I
missing something?
0
Reply The 7/19/2010 3:57:10 PM

"The Star King" <jfb@npl.co.uk> wrote in message 
news:631eeb7e-fcef-4c40-9e1f-c51a4650200a@e5g2000yqn.googlegroups.com...

> This issue hasn't been mentioned for a while so I hope you don't mind
> me bringing it up again. Has there been any progress made on writing
> windows api programs using one of the free compilers (g95 or
> gfortran)? I remember there was some discussion about "decorating"
> function names and stdcall calling convention.. but it all seemed to
> come to nothing.

> Currently I can program windows apps in Intel Fortran or in gcc (using
> C language) but not in gfortran.

> Also, is it possible to call OpenGL or DirectX from fortran (Intel or
> gfortran/gcc?). I'd like to do some 3D graphics eventually.

> Thanks for your help with this.

I posted an example just a couple of days ago:

http://groups.google.com/group/comp.lang.fortran/msg/fd9d74e75d8fcb23?hl=en

OK, so it was a couple of weeks ago.  If all you need to work with
is 64-bit Windows, it's easy with standard f03 in any compiler that
implements ISO_C_BINDING.  The example quoted above shows that
gfortran only needs one extra extension statement per interface
block to also work with 32-bit Windows.  It's pretty easy to
convert OpenGL or DirectX C header files to Fortran modules as long
as you're only trying to do it for the couple of functions that you
need and not everything at once.

-- 
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


0
Reply James 7/19/2010 4:36:57 PM

On 7/19/2010 11:13 AM, The Star King wrote:
> Also, is it possible to call OpenGL or DirectX from fortran (Intel or
> gfortran/gcc?).

Intel Fortran supports OpenGL calls using the IFOPNGL module.  There's 
also f90gl (http://math.nist.gov/f90gl/) though I don't see a build 
script for gfortran on Windows there.  (There is one for Linux.)

Intel Fortran doesn't provide DirectX interfaces, but it should be 
possible to construct your own.

-- 
Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH

For email address, replace "invalid" with "com"

User communities for Intel Software Development Products
   http://software.intel.com/en-us/forums/
Intel Software Development Products Support
   http://software.intel.com/sites/support/
My Fortran blog
   http://www.intel.com/software/drfortran
0
Reply Steve.Lionel5921 (403) 7/19/2010 4:58:54 PM

On Jul 19, 5:36=A0pm, "James Van Buskirk" <not_va...@comcast.net> wrote:
> "The Star King" <j...@npl.co.uk> wrote in messagenews:631eeb7e-fcef-4c40-=
9e1f-c51a4650200a@e5g2000yqn.googlegroups.com...
>
> > This issue hasn't been mentioned for a while so I hope you don't mind
> > me bringing it up again. Has there been any progress made on writing
> > windows api programs using one of the free compilers (g95 or
> > gfortran)? I remember there was some discussion about "decorating"
> > function names and stdcall calling convention.. but it all seemed to
> > come to nothing.
> > Currently I can program windows apps in Intel Fortran or in gcc (using
> > C language) but not in gfortran.
> > Also, is it possible to call OpenGL or DirectX from fortran (Intel or
> > gfortran/gcc?). I'd like to do some 3D graphics eventually.
> > Thanks for your help with this.
>
> I posted an example just a couple of days ago:
>
> http://groups.google.com/group/comp.lang.fortran/msg/fd9d74e75d8fcb23...
>
> OK, so it was a couple of weeks ago. =A0If all you need to work with
> is 64-bit Windows, it's easy with standard f03 in any compiler that
> implements ISO_C_BINDING. =A0The example quoted above shows that
> gfortran only needs one extra extension statement per interface
> block to also work with 32-bit Windows. =A0It's pretty easy to
> convert OpenGL or DirectX C header files to Fortran modules as long
> as you're only trying to do it for the couple of functions that you
> need and not everything at once.
>
> --
> write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
> 6.0134700243160014d-154/),(/'x'/)); end

Thanks for this advice. Have you tried using this technique for
Windows Api programming? I think the key thing is the command

!GCC$ ATTRIBUTES STDCALL

which i wasn't aware of but which is reminiscent of the Intel Fortran !
DEC$ command. (is this a new thing in gcc?). It looks as though I
would have to write a large module full of interface statements
(rather like the one Intel Fortran provides). But has anyone already
written such a module?
0
Reply The 7/19/2010 5:22:36 PM

The Star King wrote:
> Thanks for this advice. Have you tried using this technique for
> Windows Api programming? I think the key thing is the command
> 
> !GCC$ ATTRIBUTES STDCALL
> 
> which i wasn't aware of but which is reminiscent of the Intel Fortran !
> DEC$ command. (is this a new thing in gcc?).

Support for the GCC$ directive was added about a year ago (in GCC 4.5),
cf. the release notes: http://gcc.gnu.org/gcc-4.5/changes.html

And indeed GCC$ were motivated by the DEC$ attributes. For GCC/gfortran,
the idea is to use most of BIND(C) and only add the GCC$ attributes on
top of it. For BIND(C) and the GCC$ directives have a look at the first
two items at

http://gcc.gnu.org/onlinedocs/gfortran/Mixed_002dLanguage-Programming.html

Tobias
0
Reply Tobias 7/19/2010 5:42:26 PM

On Jul 19, 5:58=A0pm, Steve Lionel <steve.lio...@intel.invalid> wrote:
> On 7/19/2010 11:13 AM, The Star King wrote:
>
> > Also, is it possible to call OpenGL or DirectX from fortran (Intel or
> > gfortran/gcc?).
>
> Intel Fortran supports OpenGL calls using the IFOPNGL module. =A0There's
> also f90gl (http://math.nist.gov/f90gl/) though I don't see a build
> script for gfortran on Windows there. =A0(There is one for Linux.)
>
> Intel Fortran doesn't provide DirectX interfaces, but it should be
> possible to construct your own.
>
> --
> Steve Lionel
> Developer Products Division
> Intel Corporation
> Nashua, NH
>
> For email address, replace "invalid" with "com"
>
> User communities for Intel Software Development Products
> =A0 =A0http://software.intel.com/en-us/forums/
> Intel Software Development Products Support
> =A0 =A0http://software.intel.com/sites/support/
> My Fortran blog
> =A0 =A0http://www.intel.com/software/drfortran

Thanks for that, Steve. I've only recently got IVF and didn't notice
the OpenGL support! I'm now going through the OpenGL code in the
Samples directory. Are there any OpenGL tutorials you would recommend?
Preferably specific to Fortran, though that may be asking too much!
0
Reply jfb (23) 7/19/2010 5:45:16 PM

James Van Buskirk <not_valid@comcast.net> wrote:
(snip)

> It's pretty easy to
> convert OpenGL or DirectX C header files to Fortran modules as long
> as you're only trying to do it for the couple of functions that you
> need and not everything at once.

It shouldn't be hard to automate the process.  Though it may
take some time to check that the automated conversion gave
the right result in all cases.

-- glen 
0
Reply glen 7/19/2010 6:04:29 PM

On Jul 19, 12:45=A0pm, The Star King <j...@npl.co.uk> wrote:
> On Jul 19, 5:58=A0pm, Steve Lionel <steve.lio...@intel.invalid> wrote:
>
>
>
>
>
> > On 7/19/2010 11:13 AM, The Star King wrote:
>
> > > Also, is it possible to call OpenGL or DirectX from fortran (Intel or
> > > gfortran/gcc?).
>
> > Intel Fortran supports OpenGL calls using the IFOPNGL module. =A0There'=
s
> > also f90gl (http://math.nist.gov/f90gl/) though I don't see a build
> > script for gfortran on Windows there. =A0(There is one for Linux.)
>
> > Intel Fortran doesn't provide DirectX interfaces, but it should be
> > possible to construct your own.
>
> > --
> > Steve Lionel
> > Developer Products Division
> > Intel Corporation
> > Nashua, NH
>
> > For email address, replace "invalid" with "com"
>
> > User communities for Intel Software Development Products
> > =A0 =A0http://software.intel.com/en-us/forums/
> > Intel Software Development Products Support
> > =A0 =A0http://software.intel.com/sites/support/
> > My Fortran blog
> > =A0 =A0http://www.intel.com/software/drfortran
>
> Thanks for that, Steve. I've only recently got IVF and didn't notice
> the OpenGL support! I'm now going through the OpenGL code in the
> Samples directory. Are there any OpenGL tutorials you would recommend?
> Preferably specific to Fortran, though that may be asking too much!- Hide=
 quoted text -
>
> - Show quoted text -

You might also consider GINO which integrates OPENGL (depending on
your budget).  With GINO, you program to a single (GINO) API and just
change the driver call at the beginning to switch between for example
win32 GDI or OpenGL.  Of course I don't off hand know where the
boundaries are of things you can do with the OpenGl driver that you
can't with the GDI, but its probably in the documentation somewhere.
0
Reply garylscott (1357) 7/19/2010 6:21:43 PM

On 7/19/2010 1:45 PM, The Star King wrote:

> Thanks for that, Steve. I've only recently got IVF and didn't notice
> the OpenGL support! I'm now going through the OpenGL code in the
> Samples directory. Are there any OpenGL tutorials you would recommend?
> Preferably specific to Fortran, though that may be asking too much!

I have found that tutorial information on using OpenGL from C translates 
very well into Fortran.  The major thing to be aware of is that, due to 
a choice Microsoft made back in the PowerStation days, the IFOPNGL 
declarations of OpenGL routines all have an "f" prefix in their names, 
but otherwise map directly onto standard OpenGL functions.  The type 
names typically have a "T_" prefix.  You'll want to have the sources for 
ifopngl.f90 and ifopnglt.f90 open for reference.

Many years ago, I bought "OpenGL SuperBible" and found it served me well 
in understanding OpenGL programming concepts.

Oh, and forget about using any of the "Aux" routines - Microsoft removed 
support for them in VS2008.

-- 
Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH

For email address, replace "invalid" with "com"

User communities for Intel Software Development Products
   http://software.intel.com/en-us/forums/
Intel Software Development Products Support
   http://software.intel.com/sites/support/
My Fortran blog
   http://www.intel.com/software/drfortran
0
Reply Steve.Lionel5921 (403) 7/19/2010 7:03:12 PM

On Jul 19, 8:03=A0pm, Steve Lionel <steve.lio...@intel.invalid> wrote:
> On 7/19/2010 1:45 PM, The Star King wrote:
>
> > Thanks for that, Steve. I've only recently got IVF and didn't notice
> > the OpenGL support! I'm now going through the OpenGL code in the
> > Samples directory. Are there any OpenGL tutorials you would recommend?
> > Preferably specific to Fortran, though that may be asking too much!
>
> I have found that tutorial information on using OpenGL from C translates
> very well into Fortran. =A0The major thing to be aware of is that, due to
> a choice Microsoft made back in the PowerStation days, the IFOPNGL
> declarations of OpenGL routines all have an "f" prefix in their names,
> but otherwise map directly onto standard OpenGL functions. =A0The type
> names typically have a "T_" prefix. =A0You'll want to have the sources fo=
r
> ifopngl.f90 and ifopnglt.f90 open for reference.
>
> Many years ago, I bought "OpenGL SuperBible" and found it served me well
> in understanding OpenGL programming concepts.
>
> Oh, and forget about using any of the "Aux" routines - Microsoft removed
> support for them in VS2008.
>
> --
> Steve Lionel
> Developer Products Division
> Intel Corporation
> Nashua, NH
>
> For email address, replace "invalid" with "com"
>
> User communities for Intel Software Development Products
> =A0 =A0http://software.intel.com/en-us/forums/
> Intel Software Development Products Support
> =A0 =A0http://software.intel.com/sites/support/
> My Fortran blog
> =A0 =A0http://www.intel.com/software/drfortran

I'd like to thank everyone for their help with this.

I wonder: has anyone tried the approach suggested by James Van Buskirk
to generate windows programs in gfortran (using ISO_C_BINDINGS + !GCC
$)? Does it work? Has anyone prepared a substantial set of interfaces
for the api functions?
0
Reply The 7/19/2010 8:07:15 PM

"The Star King" <jfb@npl.co.uk> wrote in message 
news:35ab2a26-37e5-4002-bd81-8042d299375a@g19g2000yqc.googlegroups.com...

> On Jul 19, 5:36 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:

> > I posted an example just a couple of days ago:

> > http://groups.google.com/group/comp.lang.fortran/msg/fd9d74e75d8fcb23...

> Thanks for this advice. Have you tried using this technique for
> Windows Api programming?

In fact the whole point of the example quoted above was to invoke
the Win32 API functions LoadLibrary, GetLastError, and GetProcAddress.

>                          I think the key thing is the command

> !GCC$ ATTRIBUTES STDCALL

> which i wasn't aware of but which is reminiscent of the Intel Fortran !
> DEC$ command.

Unfortunately the extensions are not identical.  ifort doesn't have
the possibility to mix STDCALL with BIND(C).  I think that was originally
a consequence of a misunderstanding about how BIND(C) was supposed to
work with CHARACTER arguments and function results, but Intel by now
has cleared up that misunderstanding and conforms to the standard which
to my mind should allow for mixing STDCALL with BIND(C) (see gfortran's
handling of the issue, for example) but they still don't.

As I said before, this problem only arises in 32-bit Windows; in 64-bit
Windows simply using BIND(C) works the same way in both compilers
because there is only one calling convention on that platform.  In my
opinion, BIND(C) with no extensions could be made to work even in
32-bit Windows; just compile the module of interface blocks with a
compiler switch that specifies STDCALL.  If it's required to compile
a callback function that must be STDCALL, then put that in a file
that has that switch.  gfortran bombs when you do this because it
starts compiling calls to intrinsic functions as STDCALL which it
shouldn't do because it should have available to it an explicit
interface that specifies that the calling convention of instrisics
is CDECL, but it's probably way more work than it's worth to fix
that issue...

>               (is this a new thing in gcc?). It looks as though I
> would have to write a large module full of interface statements
> (rather like the one Intel Fortran provides). But has anyone already
> written such a module?

As I said, you don't need the whole thing, just the interfaces and
derived types that your program actually uses.

-- 
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


0
Reply James 7/19/2010 8:08:49 PM

On 19 Jul, 21:03, Steve Lionel <steve.lio...@intel.invalid> wrote:

> I have found that tutorial information on using OpenGL from C translates
> very well into Fortran. =A0

Given that Irix GL started as a Fortran 77 library on SGI Iris, that
does not come as a huge surprise. E.g. consider the order by which
OpenGL stores buffers and matrices.

0
Reply sturlamolden 7/19/2010 8:47:22 PM

On Jul 19, 9:08=A0pm, "James Van Buskirk" <not_va...@comcast.net> wrote:
> "The Star King" <j...@npl.co.uk> wrote in messagenews:35ab2a26-37e5-4002-=
bd81-8042d299375a@g19g2000yqc.googlegroups.com...
>
> > On Jul 19, 5:36 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:
> > > I posted an example just a couple of days ago:
> > >http://groups.google.com/group/comp.lang.fortran/msg/fd9d74e75d8fcb23.=
...
> > Thanks for this advice. Have you tried using this technique for
> > Windows Api programming?
>
> In fact the whole point of the example quoted above was to invoke
> the Win32 API functions LoadLibrary, GetLastError, and GetProcAddress.
>
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0I think the key thin=
g is the command
> > !GCC$ ATTRIBUTES STDCALL
> > which i wasn't aware of but which is reminiscent of the Intel Fortran !
> > DEC$ command.
>
> Unfortunately the extensions are not identical. =A0ifort doesn't have
> the possibility to mix STDCALL with BIND(C). =A0I think that was original=
ly
> a consequence of a misunderstanding about how BIND(C) was supposed to
> work with CHARACTER arguments and function results, but Intel by now
> has cleared up that misunderstanding and conforms to the standard which
> to my mind should allow for mixing STDCALL with BIND(C) (see gfortran's
> handling of the issue, for example) but they still don't.
>
> As I said before, this problem only arises in 32-bit Windows; in 64-bit
> Windows simply using BIND(C) works the same way in both compilers
> because there is only one calling convention on that platform. =A0In my
> opinion, BIND(C) with no extensions could be made to work even in
> 32-bit Windows; just compile the module of interface blocks with a
> compiler switch that specifies STDCALL. =A0If it's required to compile
> a callback function that must be STDCALL, then put that in a file
> that has that switch. =A0gfortran bombs when you do this because it
> starts compiling calls to intrinsic functions as STDCALL which it
> shouldn't do because it should have available to it an explicit
> interface that specifies that the calling convention of instrisics
> is CDECL, but it's probably way more work than it's worth to fix
> that issue...
>
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 (is this a new thing in gcc?). It looks as =
though I
> > would have to write a large module full of interface statements
> > (rather like the one Intel Fortran provides). But has anyone already
> > written such a module?
>
> As I said, you don't need the whole thing, just the interfaces and
> derived types that your program actually uses.
>
> --
> write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
> 6.0134700243160014d-154/),(/'x'/)); end

James, thanks very much for your reply. Sorry, I didn't realise the
functions you mentioned were win32 functions. However, to get a
program running in a window a little more "magic" is needed. You need
to prepare a WinMain function and at least one callback function for
Windows to call. These are generally written in C as

int WINAPI WinMain (HINSTANCE hinstance, HINSTANCED hPrevInstance,
PSTR szCmdLine, int iCmdShow);
LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM
lParam);

This means that the Fortran program will not have a main "program"
declaration. How can gfortran cope with this?
0
Reply jfb (23) 7/20/2010 9:43:00 AM

In article
<8bb49fdc-7788-477f-94c5-c1af4d21e809@z10g2000yqb.googlegroups.com>, The
Star King <jfb@npl.co.uk> writes: 

> > > !GCC$ ATTRIBUTES STDCALL
> > > which i wasn't aware of but which is reminiscent of the Intel Fortran 
> > > !DEC$ command.

Aahhh yes---Directive-Enhanced Compilation.  I'm sure Steve Lionel can 
give us some of the history of this preprocessor command.  :-)

0
Reply helbig 7/20/2010 10:27:13 AM

The Star King wrote:
....

> This means that the Fortran program will not have a main "program"
> declaration. How can gfortran cope with this?

Same way as for any other Win32 API declaration -- build what you need.

Sotoo (CVF-compatible; do whatever it is in your compiler to get similar 
results)

integer function WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow )
!DEC$ ATTRIBUTES STDCALL, ALIAS : 'WinMain' :: WinMain
....
   integer :: hInstance, hPrevInstance, nCmdShow
   integer :: lpCmdLine
....
   integer hInstance, hPrevInstance, nCmdShow, lpCmdLine

   type (T_MSG) ::   mesg
....
   if (hPrevInstance .eq. 0) then
     if (InitApplication(hInstance)== 0) then
       WinMain = FALSE
       return
     end if
   end if
   hInst = hInstance
....
   do while (GetMessage(mesg, NULL, 0, 0))
     i = TranslateMessage(mesg)
     i = DispatchMessage(mesg)
   end do
   WinMain = mesg%wParam
end

etc., ...

If there hasn't been a module built for WinMain and friends specific for 
the particular compiler, your mission, should you choose to accept it, 
....  :)

It's tedious but basically a straightforward process, much of which can 
be automated.  What's actually available as starting points in the open 
source genre I'm not aware but I'd think somebody would have a pretty 
good handle on it that could be modified to any particular compiler's 
extensions.

This does assume there is a way to do the name-mangling required...

--
0
Reply dpb 7/20/2010 12:20:51 PM

On 7/20/2010 6:27 AM, Phillip Helbig---undress to reply wrote:
> In article
> <8bb49fdc-7788-477f-94c5-c1af4d21e809@z10g2000yqb.googlegroups.com>, The
> Star King<jfb@npl.co.uk>  writes:
>
>>>> !GCC$ ATTRIBUTES STDCALL
>>>> which i wasn't aware of but which is reminiscent of the Intel Fortran
>>>> !DEC$ command.
>
> Aahhh yes---Directive-Enhanced Compilation.  I'm sure Steve Lionel can
> give us some of the history of this preprocessor command.  :-)
>

Certainly I could, but I think you know it already.  I will comment that 
pretty much all Fortran compilers with comment-like directives follow 
the general format of ! (or C) followed by three letters and then $. 
(An exception is OpenMP which uses !$OMP.) !DIR$ is another popular 
"introducer" and Intel Fortran also recognizes it.

-- 
Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH

For email address, replace "invalid" with "com"

User communities for Intel Software Development Products
   http://software.intel.com/en-us/forums/
Intel Software Development Products Support
   http://software.intel.com/sites/support/
My Fortran blog
   http://www.intel.com/software/drfortran
0
Reply Steve.Lionel5921 (403) 7/20/2010 7:50:59 PM

> You need to prepare a WinMain function and at least one callback
> function for Windows to call.

If you have a main PROGRAM in your Fortran code (as opposed to only
subroutines and functions), your compiler has the task of getting the OS
to run it appropriately (creating whatever machine code entry point is
expected by the application loader).

-- 
FX
0
Reply FX 7/20/2010 7:58:21 PM

"The Star King" <jfb@npl.co.uk> wrote in message 
news:8bb49fdc-7788-477f-94c5-c1af4d21e809@z10g2000yqb.googlegroups.com...

> James, thanks very much for your reply. Sorry, I didn't realise the
> functions you mentioned were win32 functions. However, to get a
> program running in a window a little more "magic" is needed. You need
> to prepare a WinMain function and at least one callback function for
> Windows to call. These are generally written in C as

> int WINAPI WinMain (HINSTANCE hinstance, HINSTANCED hPrevInstance,
> PSTR szCmdLine, int iCmdShow);
> LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM
> lParam);

> This means that the Fortran program will not have a main "program"
> declaration. How can gfortran cope with this?

It just can these days.  I updated my Fortran adaptation of Petzold's
Hello, world program.  Comcast seems to have made it more difficult
to update my web page just now, however, so here it comes:

C:\gfortran\clf\HelloWin>type HelloWin2.f90
! HelloWin2.f90
! Public domain 2007-2010 James Van Buskirk
! Compiled with:
! gfortran -Wall -mwindows HelloWin2.f90 -oHelloWin2 -lgdi32

module win32_types
   use ISO_C_BINDING
   implicit none
   private

   public WNDCLASSEX_T
   type, bind(C) :: WNDCLASSEX_T
      integer(C_INT) cbSize
      integer(C_INT) style
      type(C_FUNPTR) lpfnWndProc
      integer(C_INT) cbClsExtra
      integer(C_INT) cbWndExtra
      integer(C_INTPTR_T) hInstance
      integer(C_INTPTR_T) hIcon
      integer(C_INTPTR_T) hCursor
      integer(C_INTPTR_T) hbrBackground
      type(C_PTR) lpszMenuName
      type(C_PTR) lpszClassName
      integer(C_INTPTR_T) hIconSm
   end type WNDCLASSEX_T

   public POINT_T
   type, bind(C) :: POINT_T
      integer(C_LONG) x
      integer(C_LONG) y
   end type POINT_T

   public MSG_T
   type, bind(C) :: MSG_T
      integer(C_INTPTR_T) hwnd
      integer(C_INT) message
      integer(C_INTPTR_T) wParam
      integer(C_INTPTR_T) lParam
      integer(C_LONG) time
      type(POINT_T) pt
   end type MSG_T

   public RECT_T
   type, bind(C) :: RECT_T
      integer(C_LONG) left
      integer(C_LONG) top
      integer(C_LONG) right
      integer(C_LONG) bottom
   end type RECT_T

   public PAINTSTRUCT_T
   type, bind(C) :: PAINTSTRUCT_T
      integer(C_INTPTR_T) hdc
      integer(C_INT) fErase
      type(RECT_T) rcPaint
      integer(C_INT) fRestore
      integer(C_INT) fIncUpdate
      integer(C_INT8_T) rgbReserved(32)
   end type PAINTSTRUCT_T
end module win32_types

module win32
   use ISO_C_BINDING
   implicit none
   private

   public GetModuleHandle
   interface
      function GetModuleHandle(lpModuleName) &
         bind(C,name='GetModuleHandleA')

         use ISO_C_BINDING
         implicit none
!GCC$ ATTRIBUTES STDCALL :: GetModuleHandle
         integer(C_INTPTR_T) GetModuleHandle
         character(kind=C_CHAR) lpModuleName(*)
      end function GetModuleHandle
   end interface

   public GetCommandLine
   interface
      function GetCommandLine() &
         bind(C,name='GetCommandLineA')

         use ISO_C_BINDING
         implicit none
!GCC$ ATTRIBUTES STDCALL :: GetCommandLine
         type(C_PTR) GetCommandLine
      end function GetCommandLine
   end interface

   public DefWindowProc
   interface
      function DefWindowProc(hwnd, Msg, wParam, lParam) &
         bind(C,name='DefWindowProcA')

         use ISO_C_BINDING
         implicit none
!GCC$ ATTRIBUTES STDCALL :: DefWindowProc
         integer(C_LONG) DefWindowProc
         integer(C_INTPTR_T), value :: hwnd
         integer(C_INT), value :: Msg
         integer(C_INTPTR_T), value :: wParam
         integer(C_INTPTR_T), value :: lParam
      end function DefWindowProc
   end interface

   public LoadIcon
   interface
      function LoadIcon(hInstance, lpIconName) &
         bind(C,name='LoadIconA')

         use ISO_C_BINDING
         implicit none
!GCC$ ATTRIBUTES STDCALL :: LoadIcon
         integer(C_INTPTR_T) LoadIcon
         integer(C_INTPTR_T), value :: hInstance
         character(kind=C_CHAR) lpIconName(*)
      end function LoadIcon
   end interface

   public LoadCursor
   interface
      function LoadCursor(hInstance, lpCursorName) &
         bind(C,name='LoadCursorA')

         use ISO_C_BINDING
         implicit none
!GCC$ ATTRIBUTES STDCALL :: LoadCursor
         integer(C_INTPTR_T) LoadCursor
         integer(C_INTPTR_T), value :: hInstance
         character(kind=C_CHAR) lpCursorName(*)
      end function LoadCursor
   end interface

   public GetStockObject
   interface
      function GetStockObject(fnObject) &
         bind(C,name='GetStockObject')

         use ISO_C_BINDING
         implicit none
!GCC$ ATTRIBUTES STDCALL :: GetStockObject
         integer(C_INTPTR_T) GetStockObject
         integer(C_INT), value :: fnObject
      end function GetStockObject
   end interface

   integer(C_INT), parameter, public :: WHITE_BRUSH = 0 ! Stock object

   public RegisterClassEx
   interface
      function RegisterClassEx(WndClass) &
         bind(C,name='RegisterClassExA')

         use ISO_C_BINDING
         use win32_types
         implicit none
!GCC$ ATTRIBUTES STDCALL :: RegisterClassEx
         integer(C_SHORT) RegisterClassEx
         type(WNDCLASSEX_T) WndClass
      end function RegisterClassEx
   end interface

! Work around bug in libuser32.a
!   public CreateWindow
!   interface
!      function CreateWindow(lpClassName, lpWindowName, dwStyle, &
!      x, y, nWidth, nHeight, hwndParent, hMenu, hInstance, &
!      lpParam) bind(C,name='CreateWindow')
!
!         use ISO_C_BINDING
!         implicit none
!!GCC$ ATTRIBUTES STDCALL :: CreateWindow
!         integer(C_INTPTR_T) CreateWindow
!         character(kind=C_CHAR) lpClassName(*)
!         character(kind=C_CHAR) lpWindowName(*)
!         integer(C_LONG), value :: dwStyle
!         integer(C_INT), value :: x
!         integer(C_INT), value :: y
!         integer(C_INT), value :: nWidth
!         integer(C_INT), value :: nHeight
!         integer(C_INTPTR_T), value :: hWndParent
!         integer(C_INTPTR_T), value :: hMenu
!         integer(C_INTPTR_T), value :: hInstance
!         type(C_PTR), value :: lpParam
!      end function CreateWindow
!   end interface

   public CreateWindowEx
   interface
      function CreateWindowEx(dwExStyle, lpClassName, &
      lpWindowName, dwStyle, x, y, nWidth, nHeight, &
      hwndParent, hMenu, hInstance, lpParam) &
      bind(C,name='CreateWindowExA')

         use ISO_C_BINDING
         implicit none
!GCC$ ATTRIBUTES STDCALL :: CreateWindowEx
         integer(C_INTPTR_T) CreateWindowEx
         integer(C_LONG), value :: dwExStyle
         character(kind=C_CHAR) lpClassName(*)
         character(kind=C_CHAR) lpWindowName(*)
         integer(C_LONG), value :: dwStyle
         integer(C_INT), value :: x
         integer(C_INT), value :: y
         integer(C_INT), value :: nWidth
         integer(C_INT), value :: nHeight
         integer(C_INTPTR_T), value :: hWndParent
         integer(C_INTPTR_T), value :: hMenu
         integer(C_INTPTR_T), value :: hInstance
         type(C_PTR), value :: lpParam
      end function CreateWindowEx
   end interface

   public ShowWindow
   interface
      function ShowWindow(hWnd,nCmdShow) bind(C,name='ShowWindow')
         use ISO_C_BINDING
         implicit none
!GCC$ ATTRIBUTES STDCALL :: ShowWindow
         integer(C_INT) ShowWindow
         integer(C_INTPTR_T), value :: hWnd
         integer(C_INT), value :: nCmdShow
      end function ShowWindow
   end interface

   public UpdateWindow
   interface
      function UpdateWindow(hWnd) bind(C,name='UpdateWindow')
         use ISO_C_BINDING
         implicit none
!GCC$ ATTRIBUTES STDCALL :: UpdateWindow
         integer(C_INT) UpdateWindow
         integer(C_INTPTR_T), value :: hWnd
      end function UpdateWindow
   end interface

   public GetMessage
   interface
      function GetMessage(lpMsg,hWnd,wMsgFilterMin,wMsgFilterMax) &
         bind(C,name='GetMessageA')

         use ISO_C_BINDING
         use win32_types
         implicit none
!GCC$ ATTRIBUTES STDCALL :: GetMessage
         integer(C_INT) GetMessage
         type(MSG_T) lpMsg
         integer(C_INTPTR_T), value :: hWnd
         integer(C_INT), value :: wMsgFilterMin
         integer(C_INT), value :: wMsgFilterMax
      end function GetMessage
   end interface

   public TranslateMessage
   interface
      function TranslateMessage(lpMsg) bind(C,name='TranslateMessage')
         use ISO_C_BINDING
         use win32_types
         implicit none
!GCC$ ATTRIBUTES STDCALL :: TranslateMessage
         integer(C_INT) TranslateMessage
         type(MSG_T) lpMsg
      end function TranslateMessage
   end interface

   public DispatchMessage
   interface
      function DispatchMessage(lpMsg) bind(C,name='DispatchMessageA')
         use ISO_C_BINDING
         use win32_types
         implicit none
!GCC$ ATTRIBUTES STDCALL :: DispatchMessage
         integer(C_LONG) DispatchMessage
         type(MSG_T) lpMsg
      end function DispatchMessage
   end interface

   public ExitProcess
   interface
      subroutine ExitProcess(uExitCode) bind(C,name='ExitProcess')
         use ISO_C_BINDING
         implicit none
!GCC$ ATTRIBUTES STDCALL :: ExitProcess

         integer(C_INT), value :: uExitCode
      end subroutine ExitProcess
   end interface

   public BeginPaint
   interface
      function BeginPaint(hwnd,lpPaint) bind(C,name='BeginPaint')
         use ISO_C_BINDING
         use win32_types
         implicit none
!GCC$ ATTRIBUTES STDCALL :: BeginPaint
         integer(C_INTPTR_T) BeginPaint
         integer(C_INTPTR_T), value :: hwnd
         type(PAINTSTRUCT_T) lpPaint
      end function BeginPaint
   end interface

   public GetClientRect
   interface
      function GetClientRect(hwnd,lpRect) bind(C,name='GetClientRect')
         use ISO_C_BINDING
         use win32_types
         implicit none
!GCC$ ATTRIBUTES STDCALL :: GetClientRect
         integer(C_INT) GetClientRect
         integer(C_INTPTR_T), value :: hwnd
         type(RECT_T) lpRect
      end function GetClientRect
   end interface

   public DrawText
   interface
      function DrawText(hdc, lpString, nCount, lpRect, &
         uFormat) bind(C,name='DrawTextA')

         use ISO_C_BINDING
         use win32_types
         implicit none
!GCC$ ATTRIBUTES STDCALL :: DrawText
         integer(C_INT) DrawText
         integer(C_INTPTR_T), value :: hdc
         character(kind=C_CHAR) lpString(*)
         integer(C_INT), value :: nCount
         type(RECT_T) lpRect
         integer(C_INT), value :: uFormat
      end function DrawText
   end interface

   public EndPaint
   interface
      function EndPaint(hwnd,lpPaint) bind(C,name='EndPaint')
         use ISO_C_BINDING
         use win32_types
         implicit none
!GCC$ ATTRIBUTES STDCALL :: EndPaint
         integer(C_INT) EndPaint
         integer(C_INTPTR_T), value :: hwnd
         type(PAINTSTRUCT_T) lpPaint
      end function EndPaint
   end interface

   public PostQuitMessage
   interface
      subroutine PostQuitMessage(nExitCode) bind(C,name='PostQuitMessage')
         use ISO_C_BINDING
         implicit none
!GCC$ ATTRIBUTES STDCALL :: PostQuitMessage

         integer(C_INT), value :: nExitCode
      end subroutine PostQuitMessage
   end interface
end module win32

module procs
   use win32
   use win32_types
   use ISO_C_BINDING
   implicit none
   private
   public WndProc
   contains
      function WndProc(hwnd, iMsg, wParam, lParam) bind(C)
!GCC$ ATTRIBUTES STDCALL :: WndProc
         integer(C_LONG) WndProc
         integer(C_INTPTR_T), value :: hwnd
         integer(C_INT), value :: iMsg
         integer(C_INTPTR_T), value :: wParam
         integer(C_INTPTR_T), value :: lParam
         integer(C_INTPTR_T) hdc
         type(PAINTSTRUCT_T) ps
         type(RECT_T) rect
         integer(C_INT) result4
         character(kind=C_CHAR) message*(80)

         select case(iMsg)
            case(1) ! WM_CREATE
               WndProc = 0
               return
            case(15) ! WM_PAINT
               hdc = BeginPaint(hwnd, ps)
               result4 = GetClientRect(hwnd, rect)
               message = 'Hello, gfortran!'//achar(0)
               result4 = DrawText(hdc, message, -1, rect, 37)
               result4 = EndPaint(hwnd, ps)
               WndProc = 0
               return
            case(2) ! WM_DESTROY
               call PostQuitMessage(0)
               WndProc = 0
               return
         end select

         WndProc = DefWindowProc(hwnd, iMsg, wParam, lParam)
      end function WndProc
end module procs

function WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) bind(C, 
name='Wi
nMain')
!program WinMain
   use win32
   use win32_types
   use procs
   use ISO_C_BINDING
   implicit none
!GCC$ ATTRIBUTES STDCALL :: WinMain
   integer(C_INT) WinMain
   integer(C_INTPTR_T), value :: hInstance
   integer(C_INTPTR_T), value :: hPrevInstance
   type(C_PTR), value :: lpCmdLine
   integer(C_INT), value :: nCmdShow
   character(kind=C_CHAR), pointer :: pcNull(:)
!   integer(C_INTPTR_T) hInstance
!   type(C_PTR) szCommandLine
   type(WNDCLASSEX_T) WndClass
   character(kind=C_CHAR), pointer :: cDefault(:)
   character(kind=C_CHAR), target :: szAppName*(80)
   integer(C_SHORT) result2
   integer(C_INTPTR_T) hwnd
   character(kind=C_CHAR), target :: szWindowCaption*(80)
   integer(C_INT) result4
   type(MSG_T) msg
   integer(C_INT) argh4

   nullify(pcNull)
!   hInstance = GetModuleHandle(pcNull)
!   szCommandLine = GetCommandLine()
   call C_F_POINTER(lpCmdLine,cDefault,[0])
!   call C_F_POINTER(szCommandLine,cDefault,[0])
   szAppName = 'HelloWin'//achar(0)
   WndClass%cbSize = size(transfer(Wndclass,[0_C_INT8_T]))
   WndClass%style = 3 ! ior(CS_HREDRAW, CS_VREDRAW)
   WndClass%lpfnWndProc = C_FUNLOC(WndProc)
   WndClass%cbClsExtra = 0
   WndClass%cbWndExtra = 0
   WndClass%hInstance = hInstance
   WndClass%hIcon = LoadIcon(0_C_INTPTR_T, cDefault) ! IDI_APPLICATION
   WndClass%hCursor = LoadCursor(0_C_INTPTR_T, cDefault) ! IDC_ARROW
   WndClass%hbrBackground = GetStockObject(WHITE_BRUSH)
   WndClass%lpszMenuName = C_NULL_PTR
   WndClass%lpszClassName = C_LOC(szAppName(1:1))
   WndClass%hIconSm = LoadIcon(0_C_INTPTR_T, cDefault) ! IDI_APPLICATION

   result2 = RegisterClassEx(WndClass)

   szWindowCaption = 'The Hello Program'//achar(0)
! Workaround for bug
!   hwnd = CreateWindow(szAppName, szWindowCaption, &
!      13565952, -2147483648, -2147483648, -2147483648, &
!      -2147483648, 0_C_INTPTR_T, 0_C_INTPTR_T, hInstance, &
!      C_NULL_PTR)
   argh4 = -2147483647-1
! Workaround for libuser32.a bug
!   hwnd = CreateWindow(szAppName, szWindowCaption, &
!      13565952, argh4, argh4, argh4, argh4, 0_C_INTPTR_T, &
!      0_C_INTPTR_T, hInstance, C_NULL_PTR)
   hwnd = CreateWindowEx(0, szAppName, szWindowCaption, &
      13565952, argh4, argh4, argh4, argh4, 0_C_INTPTR_T, &
      0_C_INTPTR_T, hInstance, C_NULL_PTR)

   result4 = ShowWindow(hwnd, 10) ! SW_SHOWDEFAULT
   result4 = UpdateWindow(hwnd)

   do while(GetMessage(msg, 0_C_INTPTR_T, 0, 0) /= 0)
      result4 = TranslateMessage(msg)
      result4 = DispatchMessage(msg)
   end do

   call ExitProcess(int(msg%wParam, C_INT))
   WinMain = 0
end function WinMain
!end program WinMain

C:\gfortran\clf\HelloWin>gfortran -Wall -mwindows 
HelloWin2.f90 -oHelloWin2 -lgd
i32
HelloWin2.f90:403.41:

function WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) bind(C, 
name='W
                                         1
Warning: Unused dummy argument 'hprevinstance' at (1)
HelloWin2.f90:403.62:

function WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) bind(C, 
name='W
                                                              1
Warning: Unused dummy argument 'ncmdshow' at (1)

C:\gfortran\clf\HelloWin>HelloWin2

C:\gfortran\clf\HelloWin>gfortran -v
Built by Equation Solution < http://www.Equation.com>.
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=c:/gcc_equation/bin/../libexec/gcc/x86_64-pc-mingw32/4.5.0/l
to-wrapper.exe
Target: x86_64-pc-mingw32
Configured with: 
.../gcc-4.5-20091217-mingw/configure --host=x86_64-pc-mingw32 --
build=x86_64-unknown-linux-gnu --target=x86_64-pc-mingw32 --prefix=/home/gfortra
n/gcc-home/binary/mingw32/native/x86_64/gcc/4.5-20091217 --with-gmp=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_64/gmp --with-mpfr=/home/gfortran/gcc-home
/binary/mingw32/native/x86_64/mpfr --with-mpc=/home/gfortran/gcc-home/binary/min
gw32/native/x86_64/mpc --with-sysroot=/home/gfortran/gcc-home/binary/mingw32/cro
ss/x86_64/gcc/4.5-20091217 --with-gcc --with-gnu-ld --with-gnu-as --disable-shar
ed --disable-nls --disable-tls --enable-libgomp --enable-languages=c,fortran,c++
 --enable-threads=win32 --disable-win32-registry
Thread model: win32
gcc version 4.5.0 20091217 (experimental) (GCC)

Well, you can't see what it did because it popped up a command window
and that was the 64-bit compiler.  Results for the 32-bit compiler:

C:\gfortran\clf\HelloWin>gfortran -Wall -mwindows 
HelloWin2.f90 -oHelloWin2 -lgd
i32
HelloWin2.f90:403.41:

function WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) bind(C, 
name='W
                                         1
Warning: Unused dummy argument 'hprevinstance' at (1)
HelloWin2.f90:403.62:

function WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) bind(C, 
name='W
                                                              1
Warning: Unused dummy argument 'ncmdshow' at (1)

C:\gfortran\clf\HelloWin>HelloWin2

C:\gfortran\clf\HelloWin>gfortran -v
Built by Equation Solution <http://www.Equation.com>.
Using built-in specs.
Target: i386-pc-mingw32
Configured with: 
.../gcc-4.5-20090813-mingw/configure --host=i386-pc-mingw32 --bu
ild=x86_64-unknown-linux-gnu --target=i386-pc-mingw32 --prefix=/home/gfortran/gc
c-home/binary/mingw32/native/x86_32/gcc/4.5-20090813 --with-gcc --with-gnu-ld 
 --
with-gnu-as --disable-shared --disable-nls --disable-tls --with-gmp=/home/gfortr
an/gcc-home/binary/mingw32/native/x86_32/gmp --with-mpfr=/home/gfortran/gcc-home
/binary/mingw32/native/x86_32/mpfr --enable-languages=c,fortran,c++ --with-sysro
ot=/home/gfortran/gcc-home/binary/mingw32/cross/x86_32/gcc/4.5-20090813 --enable
-libgomp --enable-threads=win32 --disable-win32-registry
Thread model: win32
gcc version 4.5.0 20090813 (experimental) (GCC)

You will have to try it out for yourself as again the program popped
up a window.  Also I checked with Task Manager that this program was
indeed 32-bit (and the other was 64-bit.)  If all you need is OpenGL,
I am not sure that you really need a Windows program; maybe OpenGL
can pop up a graphics window from a console program.

-- 
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


0
Reply not_valid (1681) 7/20/2010 10:27:43 PM

On 7/20/2010 5:27 PM, James Van Buskirk wrote:
> "The Star King"<jfb@npl.co.uk>  wrote in message
> news:8bb49fdc-7788-477f-94c5-c1af4d21e809@z10g2000yqb.googlegroups.com...
>
>> James, thanks very much for your reply. Sorry, I didn't realise the
>> functions you mentioned were win32 functions. However, to get a
>> program running in a window a little more "magic" is needed. You need
>> to prepare a WinMain function and at least one callback function for
>> Windows to call. These are generally written in C as
>
>> int WINAPI WinMain (HINSTANCE hinstance, HINSTANCED hPrevInstance,
>> PSTR szCmdLine, int iCmdShow);
>> LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM
>> lParam);
>
>> This means that the Fortran program will not have a main "program"
>> declaration. How can gfortran cope with this?
>
> It just can these days.  I updated my Fortran adaptation of Petzold's
> Hello, world program.  Comcast seems to have made it more difficult
> to update my web page just now, however, so here it comes:
>
> C:\gfortran\clf\HelloWin>type HelloWin2.f90
> ! HelloWin2.f90
> ! Public domain 2007-2010 James Van Buskirk
> ! Compiled with:
> ! gfortran -Wall -mwindows HelloWin2.f90 -oHelloWin2 -lgdi32
>
> module win32_types
>     use ISO_C_BINDING
>     implicit none
>     private
>
>     public WNDCLASSEX_T
>     type, bind(C) :: WNDCLASSEX_T
>        integer(C_INT) cbSize
>        integer(C_INT) style
>        type(C_FUNPTR) lpfnWndProc
>        integer(C_INT) cbClsExtra
>        integer(C_INT) cbWndExtra
>        integer(C_INTPTR_T) hInstance
>        integer(C_INTPTR_T) hIcon
>        integer(C_INTPTR_T) hCursor
>        integer(C_INTPTR_T) hbrBackground
>        type(C_PTR) lpszMenuName
>        type(C_PTR) lpszClassName
>        integer(C_INTPTR_T) hIconSm
>     end type WNDCLASSEX_T
>
>     public POINT_T
>     type, bind(C) :: POINT_T
>        integer(C_LONG) x
>        integer(C_LONG) y
>     end type POINT_T
>
>     public MSG_T
>     type, bind(C) :: MSG_T
>        integer(C_INTPTR_T) hwnd
>        integer(C_INT) message
>        integer(C_INTPTR_T) wParam
>        integer(C_INTPTR_T) lParam
>        integer(C_LONG) time
>        type(POINT_T) pt
>     end type MSG_T
>
>     public RECT_T
>     type, bind(C) :: RECT_T
>        integer(C_LONG) left
>        integer(C_LONG) top
>        integer(C_LONG) right
>        integer(C_LONG) bottom
>     end type RECT_T
>
>     public PAINTSTRUCT_T
>     type, bind(C) :: PAINTSTRUCT_T
>        integer(C_INTPTR_T) hdc
>        integer(C_INT) fErase
>        type(RECT_T) rcPaint
>        integer(C_INT) fRestore
>        integer(C_INT) fIncUpdate
>        integer(C_INT8_T) rgbReserved(32)
>     end type PAINTSTRUCT_T
> end module win32_types
>
> module win32
>     use ISO_C_BINDING
>     implicit none
>     private
>
>     public GetModuleHandle
>     interface
>        function GetModuleHandle(lpModuleName)&
>           bind(C,name='GetModuleHandleA')
>
>           use ISO_C_BINDING
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: GetModuleHandle
>           integer(C_INTPTR_T) GetModuleHandle
>           character(kind=C_CHAR) lpModuleName(*)
>        end function GetModuleHandle
>     end interface
>
>     public GetCommandLine
>     interface
>        function GetCommandLine()&
>           bind(C,name='GetCommandLineA')
>
>           use ISO_C_BINDING
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: GetCommandLine
>           type(C_PTR) GetCommandLine
>        end function GetCommandLine
>     end interface
>
>     public DefWindowProc
>     interface
>        function DefWindowProc(hwnd, Msg, wParam, lParam)&
>           bind(C,name='DefWindowProcA')
>
>           use ISO_C_BINDING
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: DefWindowProc
>           integer(C_LONG) DefWindowProc
>           integer(C_INTPTR_T), value :: hwnd
>           integer(C_INT), value :: Msg
>           integer(C_INTPTR_T), value :: wParam
>           integer(C_INTPTR_T), value :: lParam
>        end function DefWindowProc
>     end interface
>
>     public LoadIcon
>     interface
>        function LoadIcon(hInstance, lpIconName)&
>           bind(C,name='LoadIconA')
>
>           use ISO_C_BINDING
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: LoadIcon
>           integer(C_INTPTR_T) LoadIcon
>           integer(C_INTPTR_T), value :: hInstance
>           character(kind=C_CHAR) lpIconName(*)
>        end function LoadIcon
>     end interface
>
>     public LoadCursor
>     interface
>        function LoadCursor(hInstance, lpCursorName)&
>           bind(C,name='LoadCursorA')
>
>           use ISO_C_BINDING
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: LoadCursor
>           integer(C_INTPTR_T) LoadCursor
>           integer(C_INTPTR_T), value :: hInstance
>           character(kind=C_CHAR) lpCursorName(*)
>        end function LoadCursor
>     end interface
>
>     public GetStockObject
>     interface
>        function GetStockObject(fnObject)&
>           bind(C,name='GetStockObject')
>
>           use ISO_C_BINDING
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: GetStockObject
>           integer(C_INTPTR_T) GetStockObject
>           integer(C_INT), value :: fnObject
>        end function GetStockObject
>     end interface
>
>     integer(C_INT), parameter, public :: WHITE_BRUSH = 0 ! Stock object
>
>     public RegisterClassEx
>     interface
>        function RegisterClassEx(WndClass)&
>           bind(C,name='RegisterClassExA')
>
>           use ISO_C_BINDING
>           use win32_types
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: RegisterClassEx
>           integer(C_SHORT) RegisterClassEx
>           type(WNDCLASSEX_T) WndClass
>        end function RegisterClassEx
>     end interface
>
> ! Work around bug in libuser32.a
> !   public CreateWindow
> !   interface
> !      function CreateWindow(lpClassName, lpWindowName, dwStyle,&
> !      x, y, nWidth, nHeight, hwndParent, hMenu, hInstance,&
> !      lpParam) bind(C,name='CreateWindow')
> !
> !         use ISO_C_BINDING
> !         implicit none
> !!GCC$ ATTRIBUTES STDCALL :: CreateWindow
> !         integer(C_INTPTR_T) CreateWindow
> !         character(kind=C_CHAR) lpClassName(*)
> !         character(kind=C_CHAR) lpWindowName(*)
> !         integer(C_LONG), value :: dwStyle
> !         integer(C_INT), value :: x
> !         integer(C_INT), value :: y
> !         integer(C_INT), value :: nWidth
> !         integer(C_INT), value :: nHeight
> !         integer(C_INTPTR_T), value :: hWndParent
> !         integer(C_INTPTR_T), value :: hMenu
> !         integer(C_INTPTR_T), value :: hInstance
> !         type(C_PTR), value :: lpParam
> !      end function CreateWindow
> !   end interface
>
>     public CreateWindowEx
>     interface
>        function CreateWindowEx(dwExStyle, lpClassName,&
>        lpWindowName, dwStyle, x, y, nWidth, nHeight,&
>        hwndParent, hMenu, hInstance, lpParam)&
>        bind(C,name='CreateWindowExA')
>
>           use ISO_C_BINDING
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: CreateWindowEx
>           integer(C_INTPTR_T) CreateWindowEx
>           integer(C_LONG), value :: dwExStyle
>           character(kind=C_CHAR) lpClassName(*)
>           character(kind=C_CHAR) lpWindowName(*)
>           integer(C_LONG), value :: dwStyle
>           integer(C_INT), value :: x
>           integer(C_INT), value :: y
>           integer(C_INT), value :: nWidth
>           integer(C_INT), value :: nHeight
>           integer(C_INTPTR_T), value :: hWndParent
>           integer(C_INTPTR_T), value :: hMenu
>           integer(C_INTPTR_T), value :: hInstance
>           type(C_PTR), value :: lpParam
>        end function CreateWindowEx
>     end interface
>
>     public ShowWindow
>     interface
>        function ShowWindow(hWnd,nCmdShow) bind(C,name='ShowWindow')
>           use ISO_C_BINDING
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: ShowWindow
>           integer(C_INT) ShowWindow
>           integer(C_INTPTR_T), value :: hWnd
>           integer(C_INT), value :: nCmdShow
>        end function ShowWindow
>     end interface
>
>     public UpdateWindow
>     interface
>        function UpdateWindow(hWnd) bind(C,name='UpdateWindow')
>           use ISO_C_BINDING
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: UpdateWindow
>           integer(C_INT) UpdateWindow
>           integer(C_INTPTR_T), value :: hWnd
>        end function UpdateWindow
>     end interface
>
>     public GetMessage
>     interface
>        function GetMessage(lpMsg,hWnd,wMsgFilterMin,wMsgFilterMax)&
>           bind(C,name='GetMessageA')
>
>           use ISO_C_BINDING
>           use win32_types
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: GetMessage
>           integer(C_INT) GetMessage
>           type(MSG_T) lpMsg
>           integer(C_INTPTR_T), value :: hWnd
>           integer(C_INT), value :: wMsgFilterMin
>           integer(C_INT), value :: wMsgFilterMax
>        end function GetMessage
>     end interface
>
>     public TranslateMessage
>     interface
>        function TranslateMessage(lpMsg) bind(C,name='TranslateMessage')
>           use ISO_C_BINDING
>           use win32_types
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: TranslateMessage
>           integer(C_INT) TranslateMessage
>           type(MSG_T) lpMsg
>        end function TranslateMessage
>     end interface
>
>     public DispatchMessage
>     interface
>        function DispatchMessage(lpMsg) bind(C,name='DispatchMessageA')
>           use ISO_C_BINDING
>           use win32_types
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: DispatchMessage
>           integer(C_LONG) DispatchMessage
>           type(MSG_T) lpMsg
>        end function DispatchMessage
>     end interface
>
>     public ExitProcess
>     interface
>        subroutine ExitProcess(uExitCode) bind(C,name='ExitProcess')
>           use ISO_C_BINDING
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: ExitProcess
>
>           integer(C_INT), value :: uExitCode
>        end subroutine ExitProcess
>     end interface
>
>     public BeginPaint
>     interface
>        function BeginPaint(hwnd,lpPaint) bind(C,name='BeginPaint')
>           use ISO_C_BINDING
>           use win32_types
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: BeginPaint
>           integer(C_INTPTR_T) BeginPaint
>           integer(C_INTPTR_T), value :: hwnd
>           type(PAINTSTRUCT_T) lpPaint
>        end function BeginPaint
>     end interface
>
>     public GetClientRect
>     interface
>        function GetClientRect(hwnd,lpRect) bind(C,name='GetClientRect')
>           use ISO_C_BINDING
>           use win32_types
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: GetClientRect
>           integer(C_INT) GetClientRect
>           integer(C_INTPTR_T), value :: hwnd
>           type(RECT_T) lpRect
>        end function GetClientRect
>     end interface
>
>     public DrawText
>     interface
>        function DrawText(hdc, lpString, nCount, lpRect,&
>           uFormat) bind(C,name='DrawTextA')
>
>           use ISO_C_BINDING
>           use win32_types
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: DrawText
>           integer(C_INT) DrawText
>           integer(C_INTPTR_T), value :: hdc
>           character(kind=C_CHAR) lpString(*)
>           integer(C_INT), value :: nCount
>           type(RECT_T) lpRect
>           integer(C_INT), value :: uFormat
>        end function DrawText
>     end interface
>
>     public EndPaint
>     interface
>        function EndPaint(hwnd,lpPaint) bind(C,name='EndPaint')
>           use ISO_C_BINDING
>           use win32_types
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: EndPaint
>           integer(C_INT) EndPaint
>           integer(C_INTPTR_T), value :: hwnd
>           type(PAINTSTRUCT_T) lpPaint
>        end function EndPaint
>     end interface
>
>     public PostQuitMessage
>     interface
>        subroutine PostQuitMessage(nExitCode) bind(C,name='PostQuitMessage')
>           use ISO_C_BINDING
>           implicit none
> !GCC$ ATTRIBUTES STDCALL :: PostQuitMessage
>
>           integer(C_INT), value :: nExitCode
>        end subroutine PostQuitMessage
>     end interface
> end module win32
>
> module procs
>     use win32
>     use win32_types
>     use ISO_C_BINDING
>     implicit none
>     private
>     public WndProc
>     contains
>        function WndProc(hwnd, iMsg, wParam, lParam) bind(C)
> !GCC$ ATTRIBUTES STDCALL :: WndProc
>           integer(C_LONG) WndProc
>           integer(C_INTPTR_T), value :: hwnd
>           integer(C_INT), value :: iMsg
>           integer(C_INTPTR_T), value :: wParam
>           integer(C_INTPTR_T), value :: lParam
>           integer(C_INTPTR_T) hdc
>           type(PAINTSTRUCT_T) ps
>           type(RECT_T) rect
>           integer(C_INT) result4
>           character(kind=C_CHAR) message*(80)
>
>           select case(iMsg)
>              case(1) ! WM_CREATE
>                 WndProc = 0
>                 return
>              case(15) ! WM_PAINT
>                 hdc = BeginPaint(hwnd, ps)
>                 result4 = GetClientRect(hwnd, rect)
>                 message = 'Hello, gfortran!'//achar(0)
>                 result4 = DrawText(hdc, message, -1, rect, 37)
>                 result4 = EndPaint(hwnd, ps)
>                 WndProc = 0
>                 return
>              case(2) ! WM_DESTROY
>                 call PostQuitMessage(0)
>                 WndProc = 0
>                 return
>           end select
>
>           WndProc = DefWindowProc(hwnd, iMsg, wParam, lParam)
>        end function WndProc
> end module procs
>
> function WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) bind(C,
> name='Wi
> nMain')
> !program WinMain
>     use win32
>     use win32_types
>     use procs
>     use ISO_C_BINDING
>     implicit none
> !GCC$ ATTRIBUTES STDCALL :: WinMain
>     integer(C_INT) WinMain
>     integer(C_INTPTR_T), value :: hInstance
>     integer(C_INTPTR_T), value :: hPrevInstance
>     type(C_PTR), value :: lpCmdLine
>     integer(C_INT), value :: nCmdShow
>     character(kind=C_CHAR), pointer :: pcNull(:)
> !   integer(C_INTPTR_T) hInstance
> !   type(C_PTR) szCommandLine
>     type(WNDCLASSEX_T) WndClass
>     character(kind=C_CHAR), pointer :: cDefault(:)
>     character(kind=C_CHAR), target :: szAppName*(80)
>     integer(C_SHORT) result2
>     integer(C_INTPTR_T) hwnd
>     character(kind=C_CHAR), target :: szWindowCaption*(80)
>     integer(C_INT) result4
>     type(MSG_T) msg
>     integer(C_INT) argh4
>
>     nullify(pcNull)
> !   hInstance = GetModuleHandle(pcNull)
> !   szCommandLine = GetCommandLine()
>     call C_F_POINTER(lpCmdLine,cDefault,[0])
> !   call C_F_POINTER(szCommandLine,cDefault,[0])
>     szAppName = 'HelloWin'//achar(0)
>     WndClass%cbSize = size(transfer(Wndclass,[0_C_INT8_T]))
>     WndClass%style = 3 ! ior(CS_HREDRAW, CS_VREDRAW)
>     WndClass%lpfnWndProc = C_FUNLOC(WndProc)
>     WndClass%cbClsExtra = 0
>     WndClass%cbWndExtra = 0
>     WndClass%hInstance = hInstance
>     WndClass%hIcon = LoadIcon(0_C_INTPTR_T, cDefault) ! IDI_APPLICATION
>     WndClass%hCursor = LoadCursor(0_C_INTPTR_T, cDefault) ! IDC_ARROW
>     WndClass%hbrBackground = GetStockObject(WHITE_BRUSH)
>     WndClass%lpszMenuName = C_NULL_PTR
>     WndClass%lpszClassName = C_LOC(szAppName(1:1))
>     WndClass%hIconSm = LoadIcon(0_C_INTPTR_T, cDefault) ! IDI_APPLICATION
>
>     result2 = RegisterClassEx(WndClass)
>
>     szWindowCaption = 'The Hello Program'//achar(0)
> ! Workaround for bug
> !   hwnd = CreateWindow(szAppName, szWindowCaption,&
> !      13565952, -2147483648, -2147483648, -2147483648,&
> !      -2147483648, 0_C_INTPTR_T, 0_C_INTPTR_T, hInstance,&
> !      C_NULL_PTR)
>     argh4 = -2147483647-1
> ! Workaround for libuser32.a bug
> !   hwnd = CreateWindow(szAppName, szWindowCaption,&
> !      13565952, argh4, argh4, argh4, argh4, 0_C_INTPTR_T,&
> !      0_C_INTPTR_T, hInstance, C_NULL_PTR)
>     hwnd = CreateWindowEx(0, szAppName, szWindowCaption,&
>        13565952, argh4, argh4, argh4, argh4, 0_C_INTPTR_T,&
>        0_C_INTPTR_T, hInstance, C_NULL_PTR)
>
>     result4 = ShowWindow(hwnd, 10) ! SW_SHOWDEFAULT
>     result4 = UpdateWindow(hwnd)
>
>     do while(GetMessage(msg, 0_C_INTPTR_T, 0, 0) /= 0)
>        result4 = TranslateMessage(msg)
>        result4 = DispatchMessage(msg)
>     end do
>
>     call ExitProcess(int(msg%wParam, C_INT))
>     WinMain = 0
> end function WinMain
> !end program WinMain
>
> C:\gfortran\clf\HelloWin>gfortran -Wall -mwindows
> HelloWin2.f90 -oHelloWin2 -lgd
> i32
> HelloWin2.f90:403.41:
>
> function WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) bind(C,
> name='W
>                                           1
> Warning: Unused dummy argument 'hprevinstance' at (1)
> HelloWin2.f90:403.62:
>
> function WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) bind(C,
> name='W
>                                                                1
> Warning: Unused dummy argument 'ncmdshow' at (1)
>
> C:\gfortran\clf\HelloWin>HelloWin2
>
> C:\gfortran\clf\HelloWin>gfortran -v
> Built by Equation Solution<  http://www.Equation.com>.
> Using built-in specs.
> COLLECT_GCC=gfortran
> COLLECT_LTO_WRAPPER=c:/gcc_equation/bin/../libexec/gcc/x86_64-pc-mingw32/4.5.0/l
> to-wrapper.exe
> Target: x86_64-pc-mingw32
> Configured with:
> ../gcc-4.5-20091217-mingw/configure --host=x86_64-pc-mingw32 --
> build=x86_64-unknown-linux-gnu --target=x86_64-pc-mingw32 --prefix=/home/gfortra
> n/gcc-home/binary/mingw32/native/x86_64/gcc/4.5-20091217 --with-gmp=/home/gfortr
> an/gcc-home/binary/mingw32/native/x86_64/gmp --with-mpfr=/home/gfortran/gcc-home
> /binary/mingw32/native/x86_64/mpfr --with-mpc=/home/gfortran/gcc-home/binary/min
> gw32/native/x86_64/mpc --with-sysroot=/home/gfortran/gcc-home/binary/mingw32/cro
> ss/x86_64/gcc/4.5-20091217 --with-gcc --with-gnu-ld --with-gnu-as --disable-shar
> ed --disable-nls --disable-tls --enable-libgomp --enable-languages=c,fortran,c++
>   --enable-threads=win32 --disable-win32-registry
> Thread model: win32
> gcc version 4.5.0 20091217 (experimental) (GCC)
>
> Well, you can't see what it did because it popped up a command window
> and that was the 64-bit compiler.  Results for the 32-bit compiler:
>
> C:\gfortran\clf\HelloWin>gfortran -Wall -mwindows
> HelloWin2.f90 -oHelloWin2 -lgd
> i32
> HelloWin2.f90:403.41:
>
> function WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) bind(C,
> name='W
>                                           1
> Warning: Unused dummy argument 'hprevinstance' at (1)
> HelloWin2.f90:403.62:
>
> function WinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow) bind(C,
> name='W
>                                                                1
> Warning: Unused dummy argument 'ncmdshow' at (1)
>
> C:\gfortran\clf\HelloWin>HelloWin2
>
> C:\gfortran\clf\HelloWin>gfortran -v
> Built by Equation Solution<http://www.Equation.com>.
> Using built-in specs.
> Target: i386-pc-mingw32
> Configured with:
> ../gcc-4.5-20090813-mingw/configure --host=i386-pc-mingw32 --bu
> ild=x86_64-unknown-linux-gnu --target=i386-pc-mingw32 --prefix=/home/gfortran/gc
> c-home/binary/mingw32/native/x86_32/gcc/4.5-20090813 --with-gcc --with-gnu-ld
>   --
> with-gnu-as --disable-shared --disable-nls --disable-tls --with-gmp=/home/gfortr
> an/gcc-home/binary/mingw32/native/x86_32/gmp --with-mpfr=/home/gfortran/gcc-home
> /binary/mingw32/native/x86_32/mpfr --enable-languages=c,fortran,c++ --with-sysro
> ot=/home/gfortran/gcc-home/binary/mingw32/cross/x86_32/gcc/4.5-20090813 --enable
> -libgomp --enable-threads=win32 --disable-win32-registry
> Thread model: win32
> gcc version 4.5.0 20090813 (experimental) (GCC)
>
> You will have to try it out for yourself as again the program popped
> up a window.  Also I checked with Task Manager that this program was
> indeed 32-bit (and the other was 64-bit.)  If all you need is OpenGL,
> I am not sure that you really need a Windows program; maybe OpenGL
> can pop up a graphics window from a console program.
>
!
! GINO
!
! Initialize (initialization varies with whether you need only GUI or 
whether you need more expansive graphics
!
    call gino        !Initialize graphics interface
    call guiwin     !Select output device (Windows)
    call menu       !Initialize "widget" interface

    call master(5,5,imast)
    call guierr("Hello World","Nothin to it!")

    call manage

    do
       call action(icall)

       select case(icall)

          case default

             call menend
             call ginend
             stop

       case(10) !... other processing

    end select

end
0
Reply garylscott (1357) 7/20/2010 11:48:45 PM

"James Van Buskirk" <not_valid@comcast.net> wrote in message 
news:i257t2$3pa$1@news.eternal-september.org...

>                          I updated my Fortran adaptation of Petzold's
> Hello, world program.  Comcast seems to have made it more difficult
> to update my web page just now, however, so here it comes:

I finally did manage to break through the latest barriers Comcast
has erected to hinder my web page management and the link is now:

http://home.comcast.net/~kmbtib/Fortran_stuff/HelloWin2.f90

-- 
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


0
Reply James 7/21/2010 12:28:47 AM

On Jul 20, 3:27=A0pm, "James Van Buskirk" <not_va...@comcast.net> wrote:
> "The Star King" <j...@npl.co.uk> wrote in messagenews:8bb49fdc-7788-477f-=
94c5-c1af4d21e809@z10g2000yqb.googlegroups.com...
> > You need
> > to prepare a WinMain function and at least one callback function for
> > Windows to call. ...
> > This means that the Fortran program will not have a main "program"
> > declaration. How can gfortran cope with this?
>
> It just can these days. =A0I updated my Fortran adaptation of Petzold's
> Hello, world program. =A0Comcast seems to have made it more difficult
> to update my web page just now, however, so here it comes:
[Snip a couple hundred lines of code]

This reminds me of a perhaps apocryphal story in which an interviewer
presented Brian Kernighan with a printout of Petzold's Microsoft
Windows "hello world" and asked how it compared with the half-dozen
lines of the text-mode Unix equivalent. Kernighan thought for a moment
and said, "I don't think they've quite found the right level of
abstraction."


0
Reply Steven 7/21/2010 4:19:52 AM

Steven Correll wrote:
> On Jul 20, 3:27 pm, "James Van Buskirk" <not_va...@comcast.net> wrote:
>> "The Star King" <j...@npl.co.uk> wrote in messagenews:8bb49fdc-7788-477f-94c5-c1af4d21e809@z10g2000yqb.googlegroups.com...
>>> You need
>>> to prepare a WinMain function and at least one callback function for
>>> Windows to call. ...
>>> This means that the Fortran program will not have a main "program"
>>> declaration. How can gfortran cope with this?
>> It just can these days.  I updated my Fortran adaptation of Petzold's
>> Hello, world program.  Comcast seems to have made it more difficult
>> to update my web page just now, however, so here it comes:
> [Snip a couple hundred lines of code]
> 
> This reminds me of a perhaps apocryphal story in which an interviewer
> presented Brian Kernighan with a printout of Petzold's Microsoft
> Windows "hello world" and asked how it compared with the half-dozen
> lines of the text-mode Unix equivalent. Kernighan thought for a moment
> and said, "I don't think they've quite found the right level of
> abstraction."

All those lines are the main reason I've steered clear of Windows programming. 
Recently I started using Qt (for GUI creation), which takes care of almost all 
of that nasty business, making C++ much more approachable.
0
Reply Gib 7/21/2010 5:55:34 AM

In article <8amd16Fns1U1@mid.individual.net>, Steve Lionel
<steve.lionel@intel.invalid> writes: 

> > Aahhh yes---Directive-Enhanced Compilation.  I'm sure Steve Lionel can
> > give us some of the history of this preprocessor command.  :-)
> 
> Certainly I could, but I think you know it already.  

I was thinking about the proposed name change after the ownership 
changed when a new acronym came to the rescue.

0
Reply helbig 7/21/2010 7:28:43 AM

24 Replies
1015 Views

(page loaded in 0.261 seconds)

Similiar Articles:


















7/22/2012 3:35:36 AM


Reply: