!Generate a QuickWin app with access to a console window.
!Compile:
! f90 confunc.f90 /dll !generate confunc.lib, confunc.dll
! f90 /libs:qwin conapp.f90 confunc.lib 
!
!This program shows how to read and write a text-only window from a
!QuickWin program.
!
!This dll behaves like a console application, and it has a
!separate copy of the Fortran runtime system which will direct
!input and output to the console for *, 5, and 6.  The main
!program, conapp.f90, is compiled as a QuickWin application.
!The main program has its own copy of the Fortran runtime system
!which will treat *,5,6 as QuickWin windows.
!
!Normally, users are warned to link their main program against
!the Fortran dll libraries if they are using a separately compiled
!dll.  If this is done, then there is only one copy of the Fortran
!runtime system, and both the main program and the dll routines
!will share units.  In this sample, the rule is ignored since we want
!the QuickWin main application to treat *, 5, and 6 as QuickWin
!windows, and the dll to treat *,5,6 as a console.  This happens
!because confunc will be linked against dfordll.lib, and conapp will
!be linked against dformt.lib, the static multithreaded library. It
!is as though the programs in the dll are in a separate parallel
!universe from those in the QuickWin program.
!
!Just a word of caution:  Do not try to link QuickWin programs with
!dfordll.lib.  Unlike the configuration above, this will not work.
!Also, do not expect to use QuickWin routines in a dll.  A dll is
!not a QuickWin application, and, for various reasons, cannot be
!a QuickWin application.


Module ConFunc
     use dfwin
     use dflib
     Contains

!WriteConsoleLine is a sample routine to show that you can write a
!line of text to the console window.  You can write to a text buffer
!with various formats in your QuickWin program, and then call
!WriteConsoleLine with the text buffer.  Or you could code a number
!of specialized routines in confunc taking different types of arguments,
!and using formats other than the string format.

     Integer Function WriteConsoleLine(line, lineno)
     character*(*) line
     integer lineno ! just for testing, remove for real output
     integer ISTAT
!DEC$ ATTRIBUTES DLLEXPORT :: WriteConsoleLine
!DEC$ ATTRIBUTES ALIAS:'WRITECONSOLELINE' :: WriteConsoleLine

     write(*,*,IOSTAT=ISTAT) line," ",lineno
     WriteConsoleLine = ISTAT
     End Function

!ReadConsoleLine is a sample routine to show that you can read a line of
!text from the console window.  You may code similar routines to input
!reals or integers with specific formats, and place put them in Confunc
!if you wish.

     Integer Function ReadConsoleLine(line)
     character*(*) line
     integer ISTAT
!DEC$ ATTRIBUTES DLLEXPORT :: ReadConsoleLine
!DEC$ ATTRIBUTES ALIAS:'READCONSOLELINE' :: ReadConsoleLine

     read(*,*,IOSTAT=ISTAT) line
     ReadConsoleLine = ISTAT
     End Function


!GetCon allocates a console and sets its size.

     Logical Function GetCon(lines,length)
     integer lines,length
     logical status
     integer handle
     Type(T_COORD) wsize
!DEC$ ATTRIBUTES DLLEXPORT :: GetCon
!DEC$ ATTRIBUTES ALIAS:'GETCON' :: GetCon

     status = AllocConsole() ! get a console window of the currently set size
     handle = GetStdHandle(STD_OUTPUT_HANDLE)
     wsize.x = length   ! must be >= currently set console window line length
     wsize.y = lines    ! must be >= currently set console window no of lines

     ! get a console buffer bigger than the console window which will give
     ! scroll bars on the console window to scroll through the console buffer

     status = SetConsoleScreenBufferSize(handle, wsize)
     GetCon = status
     End Function
     

!FreeCon deallocates a console.  

     Logical Function FreeCon()
     logical status
!DEC$ ATTRIBUTES DLLEXPORT :: FreeCon
!DEC$ ATTRIBUTES ALIAS:'FREECON' :: FreeCon

     status = FreeConsole() 
     FreeCon = status
     End Function
     
     End Module
