|
KFWIN
History
Originally the KFWIN functions were developed for internal use to reduce
the developement time creating true Windows programs in Fortran using the
Win32 API.
Background
There are at least three general methods for creating Window's programs:
1) Using classes, such as MFC and OWL. This method is popular with
object oriented languages. In our view it adds another layer of complexity
without significantly simplifying the process. On the contrary, it is still
complicated enough to justify the use of one of several "wizards", further
obscuring the whole programming process.
2) Using 3rd part functions as intermediate layer. We have never used
any of these, but think programs like Quickwin, Realwin and many others
falls in this catagory. They hide the Win API from the user, making it
simpler, but at the expense of learning new commands and reduced flexibility.
A major benefit of these programs is that some of them allow the same commands
to be used for Window or Lunix applications.
3) Using the Win32 API. With this method the user create Window programs
by calling the API's directly. Initially it may seem like an overwhelming
task, but several things simplify the process. Firstly, the process is
almost identical irrespective of the programming language. Secondly, this
process is very well documented, albeit mostly for C or C++ programming.
There are numerous resources on the internet covering this subject. Thirdly,
you need to learn the API only once and that is it. No other layer of complication
with it's associated frustrations.
KFWIN Structure
The KFWIN functions are based on using the Win32 API's directly. All
we have done is to standardize the structure for internal use, thus enabling
the reuse of existing code. For example, there is only one function that
parses the windows message. This function is used by all windows and dialogs
and is accessed by adding the command, include 'WinParse.f90'to
the callback function.
The structure we decided apon is as follows:
-
One file, called winmain.f90, containing the general WinMain function.
This function is used for Dialog, SDI and MDI based applications.
-
One file for each form and dialog. This file consists of only one external
callback function. The external function contains (in the fortran sense)
all the subroutines to handle events. We decided to call them frmMain,
frmAbout,
etc.
-
One global module where all the control ID's are declared. Window handles
are not stored, but always retrieved from the corresponding control ID,
which are integer constants.
-
In addition, there is another module called msfwin2 for declarations not
included with Powerstation. Other compilers may not need this module.
WinMain Function
KFWIN includes a generic winmain function. This is the entry
point for Windows and it stays in this function until the application quits.
The primary task of this function is to display the main window/form and
to translate and dispatch the window messages.
For a SDI application, all the user has to do is to add the file to
the project. The user can switch between Dialog, SDI and MDI applications
by simply changing the compiler metastatement:
!Type of Main Window. 0=Dialog(modeless), 1=SDI, 2=MDI
!MS$DEFINE MainWndType = 1
In addition to this, the user may want to edit this file to reference
the actual menu or acelerator ID from the resource file, or to change the
name of the main and child (MDI only) functions.
Form/Dialog Function
KFWIN includes and example of a very simple callback function that
is used for all windows and dialogs. The simplest function for the main
SDI window is:
!------------------------------------------------------------------------------
!Window Type: 0=Modal Dialog, 1=Modeless Dialog,
2=SDI, 3=MDI Frame, 4=MDI Child
!------------------------------------------------------------------------------
!MS$DEFINE WndType = 2
integer(4) function frmMain (hWnd, iMsg, wParam,
lParam)
!MS$ ATTRIBUTES STDCALL, ALIAS : '_frmMain@16' ::
frmMain
!All modules used by this
form/window, incl winparse
use WinGlobal
use msfwin
use msfwin2 !For stuff
not in MSPS4
!Function parameters.
integer(4),intent(in) ::
hWnd, iMsg, wParam, lParam
!Call WinParse in 'WinParse.f90'
frmMain = WinParse (hWnd,
iMsg, wParam, lParam)
return
contains
!MS$DEFINE Form_Destroy
subroutine Form_Destroy(hWnd)
!Called
after window is removed - Function is REQUIRED.
integer(4), intent(in) :: hWnd
call PostQuitMessage(0)
end subroutine
!Main function to do parsing -
must be at end
include 'WinParse.f90'
end function
For dialog functions the function is even simpler, as the Form_Destroy
subroutine is not required. All the work is done by the WinParse
function in the WinParse.f90 file, which does not need editing. Except
if the user wants to parse more messages than those already provided.
Now, suppose the user wants to program the Click even on the form. All
he has to do, is to add the following to the function above:
!MS$DEFINE Form_LButtonDown
subroutine Form_LButtonDown(hWnd, Flag, X, Y)
integer(4), intent(in) :: hWnd, Flag, X, Y
call msgbox("Left button: Flag="//trim(str(Flag))//",
X="//trim(str(X))//", Y="//trim(str(Y)))
end subroutine
This will cause a message box to display the mouse position and SHIFT-CTRL-ALT
status whenever the left mouse button is pressed.
This is very similar to the way Visual Basic works. There are however
two main differences:
Firstly, all programming in KFWIN is using the Win API. For example,
to set the caption in VB you can use Form.Caption = "New caption".
In KFWIN you have to use iret = Sendmessage(hWnd, WM_SETTEXT, 0, loc("New
caption"//char(0))).
Secondly, in Visual Basic all controls have their own events. For example,
if you have a button called btmOK, then VB will have an event called btmOK_Click.
KFWIN only parses the message down to the specific class, and will thus
call the Button_Click event for all buttons on that form. Inside this sub,
you have to look at the ID of the button (passed as IDControl) to see which
specific button called the event. The advantages of this approach is that
the parsing function can be generic, and that arrays of control can be
simulated easily.
WinParse Function
WinParse is the generic function used for parsing the windows
messages and is included in the WinParse.f90 file. This function relies
heavily on the use of metacommands. That is, the specific parts of the
parsing function that is included, depends on which metavariables are defined
for that form/dialog.
Thus, the command,
!MS$DEFINE Form_LButtonDown
will cause the following to be included from the WinParse function,
case (WM_LBUTTONDOWN)
call Form_LButtonDown(hWnd,
wParam, LWord(lParam), HWord(lParam))
Click for a list of the messages currently
parsed.
Examples and Templates
In addition to the functions mentioned above, KFWIN includes several
functions to convert numbers to text, text from text boxes to numbers,
sizeof
function (FPS4 does not have one), etc.
It also includes a text file called WinTemplates.txt. This file contains
examples of how to create various controls, statusbars, toolbars, tooltips,
subclassing controls, typical paint/close/etc function, file open/save
common controls, etc.
It also includes 3 examples for creating simple dialog, SDI or MDI applications.
The fourth example is a partial implementation of a simple text editor
application. A screen shot of this example is shown below.

Platform
KFWIN was developed using Microsoft Powerstation 4 on Windows 98. If
you do not use this compiler (and we guess many don't), there will be some
work involved to convert the functions/modules. At the minimum, your compiler
must support calls to the Win API as well as conditional compilation using
meta commands (stuff like !MS$DEFINE or equivalent).
Although the dialog boxes/menus can be created in code, it is much easier
to create it visually with a resource editor. We used the Microsoft Dialog
Editor.
Cost
To ensure you appreciate the effort put into it, these functions are
available at 10 pound (or 15 US dollars or approximate equivalent in other
currency).
|