This section describes general information about calling Win32 routines from Visual Fortran applications. It describes the following topics:
Visual Fortran provides Fortran 95/90 language elements (such as intrinsic procedures and statements) that conform to the Fortran 95 standard. Visual Fortran also provides language elements that are language extensions, including library routines.
The library routines provided by Visual Fortran:
In contrast, the Win32 Application Programming Interface (API) routines provided by the Windows operating system:
However, Visual Fortran provides interface block definitions that simplify calling Win32 routines from Visual Fortran (such as allowing you to specify Fortran data arguments as being passed by reference). To obtain these interface definitions, add the USE DFWIN line to your program (explained below).
There are many groups of Win32 routines (see the Platform SDK and other resources). Win32 routines provide sophisticated window management, memory management, graphics support, threading, security, and networking.
You can access many Win32 routines from any Fortran application, including Fortran Console and Fortran QuickWin applications. Only the Fortran Windows application project type provides access to the full set of Win32 routines needed to create GUI applications.
Fortran Console applications are text-only applications. Fortran QuickWin applications allow you to build Windows style applications easily, but access only a small subset of the available Win32 API features. (Fortran QuickWin applications also allow you to use graphics.) For differences between Fortran QuickWin and Fortran Windows applications, see Comparing QuickWin with Windows-Based Applications.
Visual Fortran provides interface definitions for both the Visual Fortran library routines and nearly all of the Win32 API routines in the standard include directory:
...\DF98\INCLUDE\
To include the Win32 interface definitions, do one of the following:
The USE DFWIN statement makes all parameters and interfaces for most Windows routines available to your Visual Fortran program. Any program or subprogram that uses the Windows features can include the statement USE DFWIN, which is needed in each subprogram that makes graphics calls.
Add the USE statement before any declaration statements (such as IMPLICIT NONE or INTEGER) or any other modules containing declaration statements.
...\DF98\INCLUDE\DFWIN.F90
).
To locate the specific libraries for the routines being called, view the QuickInfo at the bottom of the routine page in the Platform SDK documentation, which lists the import library name. For example, to call only GetSystemTime, you need the interface definitions provided in kernel32.mod (binary form). To do this, add the following USE statement:
USE KERNEL32
If you want to further minimize compile time, add the ONLY keyword to the USE statement. For example:
USE KERNEL32, only: GetSystemTime, GetLastError
To call the appropriate Win32 routine after including the Visual Fortran interface definitions, follow these guidelines:
If character arguments are present, add a null character as a terminator to the character variable before calling the Win32 routine.
...\DF98\INCLUDE\
. For example, to view
the interface definition for GetSystemTime:
...\DF98\INCLUDE\
....\DF98\INCLUDE\
. For example, to view
the data type definition for the T_SYSTEMTIME type used in GetSystemTime:
...\DF98\INCLUDE\
.TYPE (T_SYSTEMTIME) MYTIME
! Getsystime.f90 file, shows how to call a Win32 routine
!
! Since the only routine called is GetSystemTime, only include
! interface definitions from kernel32.mod instead of all modules
! included by dfwin.f90. Type definitions are defined in DFWINTY,
! which is used within KERNEL32.
PROGRAM Getsystime
USE KERNEL32
TYPE (T_SYSTEMTIME) MYTIME
CALL GetSystemTime(MYTIME)
WRITE (*,*) 'Current UTC time hour and minute:', Mytime.wHour, Mytime.Wminute
END PROGRAM
You might create a new Fortran Console (or QuickWin) application project, add the code shown above as a source file, build it, and view the result.
Most QuickWin routines have a QQ appended to their name ito differentiate them from equivalent Win32 operating system routines. However, a small group of QuickWin graphics routines have the same name as the Win32 routines, causing a potential naming conflict if your program unit includes both USE DFLIBS (which includes QuickWin routine interface definitions) and USE DFWIN (which includes Win32 API routine interface definitions).
The QuickWin routines perform the same functions as the SDK routines but take a unit number, or use the unit in focus at the time of call, instead of taking a device context (DC) as one of their arguments.
To handle this situation, a special MSFWIN$ prefix is used for the Win32 routines. These prefixed names must be used even if you only specify USE DFWIN.
For example, Rectangle is a QuickWin routine, not a Win32 SDK routine, and you must use the name MSFWIN$Rectangle to refer to the SDK routine:
QuickWin Routine | Win32 API Routine |
---|---|
ARC | MSFWIN$Arc |
ELLIPSE | MSFWIN$Ellipse |
FLOODFILL | MSFWIN$FloodFill |
GETBKCOLOR | MSFWIN$GetBkColor |
GETPIXEL | MSFWIN$GetPixel |
GETTEXTCOLOR | MSFWIN$GetTextColor |
LINETO | MSFWIN$LineTo |
PIE | MSFWIN$Pie |
POLYGON | MSFWIN$Polygon |
RECTANGLE | MSFWIN$Rectangle |
1 | MSFWIN$SelectPalette |
SETBKCOLOR | MSFWIN$SetBkColor |
SETPIXEL | MSFWIN$SetPixel |
SETTEXTCOLOR | MSFWIN$SetTextColor |
1 There is no longer a QuickWin routine named SELECTPALLETE.
The files referenced by the DFWIN module are a Fortran version (a subset) of the Win32 WINDOWS.H header file. The correspondence of data types is given in the following table:
Win32 Data Type | Equivalent Fortran Data Type |
---|---|
BOOL, BOOLEAN | LOGICAL(4) |
BYTE | BYTE |
CHAR, CCHAR, UCHAR | CHARACTER |
COLORREF | INTEGER(4) |
DWORD, INT, LONG, ULONG | INTEGER(4) |
SHORT, USHORT, WORD | INTEGER(2) |
FLOAT | REAL(4) |
All Handles | INTEGER(4) |
All Pointers (LP*, P*) | INTEGER(4) (Integer Pointers) |
Other notes about equivalent data types for arguments:
DATA forstring /'This is a null-terminated string.'C/
You can also use the CHAR intrinsic:
character(LEN=32) forstring
forstring= "Courier New" // CHAR(0)
The structures in WINDOWS.H have been converted to derived types in DFWINTY. Unions in structures are converted to union/maps within the derived type. Names of components are unchanged. Bit fields are converted to Fortran's INTEGER(4). Functions accessing bit fields are contained in the DFWIN.F90 module with names of the form:
StructureName$BitfieldName
These bit field functions take an integer argument and return an integer. All bit fields are unsigned integers. The following shows the WINDOWS.H definition. It is followed by an example program where Win32 structures are represented as Fortran derived types.
WINDOWS.H Definition
typedef struct _LDT_ENTRY {
WORD LimitLow;
WORD BaseLow;
union {
struct {
BYTE BaseMid;
BYTE Flags1;
BYTE Flags2;
BYTE BaseHi;
} Bytes;
struct {
DWORD BaseMid : 8;
DWORD Type : 5;
DWORD Opl : 2;
DWORD Pres : 1;
DWORD LimitHi : 4;
DWORD Sys : 1;
DWORD Reserved_0 : 1;
DWORD Default_Big : 1;
DWORD Granularity : 1;
DWORD BaseHi : 8;
} Bits;
} HighWord;
} LDT_ENTRY, *PLDT_ENTRY;
Note that _LDT_ENTRY
and PLDT_ENTRY
do not exist
in the Fortran definition. Also note that Bits.xxx
is not the
same as the C version. In the Fortran case, the bit field functions must
be used. For example, the C variable yyy.HighWord.Bits.BaseHi
is
represented in Fortran by LDT_ENTRY$BaseHi(ldtentry%HighWord%bits).
The following Fortran example shows the use of the corresponding Fortran data definitions and the use of a bit extraction utility routine:
Program Test
type T_LDT_ENTRY$HIGHWORD_BYTES
sequence
BYTE BaseMid
BYTE Flags1
BYTE Flags2
BYTE BaseHi
end type T_LDT_ENTRY$HIGHWORD_BYTES
type T_LDT_ENTRY$HIGHWORD
sequence
union
map
type (T_LDT_ENTRY$HIGHWORD_BYTES) Bytes
end map
map
integer(4) Bits
end map
end union
end type T_LDT_ENTRY$HIGHWORD
type T_LDT_ENTRY
sequence
integer(2) LimitLow
integer(2) BaseLow
type (T_LDT_ENTRY$HIGHWORD) HighWord
end type T_LDT_ENTRY
type(T_LDT_ENTRY) ldtentry
integer(4) thebits
external LDT_ENTRY$BaseHi
integer(4) LDT_ENTRY$BaseHi
ldtentry%HighWord%bits = #ABFFFFFF
thebits = LDT_ENTRY$BaseHi(ldtentry%HighWord%bits)
write(*,'(Z)') thebits
end program Test
integer(4) function LDT_ENTRY$BaseHi (Bits)
integer(4) Bits
LDT_ENTRY$BaseHi = IAND(ISHFT(bits,-24),#FF)
end function LDT_ENTRY$BaseHi
In addition to using the TYPE statement, you can use the STRUCTURE statement as shown by the following example. If you have embedded data types, the data type definitions are easier to read. Also, selecting the components is more natural. For example:
program struct
STRUCTURE /T_LDT_ENTRY/
integer(2) LimitLow
integer(2) BaseLow
UNION
MAP
STRUCTURE /f_Bytes/ Bytes
BYTE BaseMid
BYTE Flags1
BYTE Flags2
BYTE BaseHi
END STRUCTURE
END MAP
MAP
STRUCTURE /f_Bits/ Bits
INTEGER(4) Bits
END STRUCTURE
END MAP
END UNION
END STRUCTURE
type(T_LDT_ENTRY) ldtentry
ldtentry%Bits%Bits = #7f6f5f4f
write(*,'(8Z)') ldtentry%Bits%Bits
write(*,'(8Z)') ldtentry%Bytes%BaseMid
end program
The expected program output follows:
7F6F5F4F
4F
You can create a data object defined by a STRUCTURE statement in two ways, by using one of the following:
type(T_LDT_ENTRY) ldtentry
RECORD /T_LDT_ENTRY/ ldtentry
The example program shows how to access a field in a structured data object, for example:
I4=ldtentry%Bits%Bits
Visual Fortran provides many Sample programs that show Fortran Windows applications that call Win32 routines, such as the following:
...\Df98\Misc
, such as
Console and Forprint....\Df98\QuickWin
, such as
Conapp, Cleanwin, and Testscrl....\Df98\Advanced\Win32
, such as
Generic and Bounce.For more information about Win32 API routines and Windows programming, see the following:
Visual Fortran provides an online bookstore that lists suggested titles: