Originally the KFWIN functions were developed for internal use to reduce the developement time creating true Windows programs in Fortran using the Win32 API. 

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)

   !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, 
      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.

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.

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). 


KFWIN © was developed and is maintained and distributed by KORF Software.
Click image (if scripting enabled) to email us any technical or commercial questions.

This product is protected by copyright law and international treaties.