«previous next»

Windows Interface (continued)

System callbacks

Windows system callbacks are fully implemented. The user may specify a callback with any number of parameters. The parameters are passed to a SwiftForth function on the Windows original stack frame and may be accessed via a set of predefined (and user extensible) names in any routine responding to the callback, similar in principle to local variables. There is no requirement for the parameters to be carried around on the stack to each routine in the response code. For example, to enumerate all fonts in the system:

    : SHOWFONT ( -- res )
	    HWND MSG WPARAM LPARAM FontFunc 1 ;
   ' SHOWFONT 4 WP: &SHOWFONTS
   : .FONTS ( -- )
	    HCON GetDC 0 &SHOWFONTS 0 EnumFonts ;

This code snippet defines a four-parameter Windows callback named &SHOWFONTS, which calls the Forth routine SHOWFONT. When SHOWFONT executes, it has free access to the four parameters passed to it via the built-in names HWND MSG WPARAM and LPARAM. The function .FONTS passes the address of &SHOWFONTS to the Windows API function EnumFonts as the address for the callback.

SwiftForth's console debugging tool can be used to trace the execution of Windows callbacks, as the console is completely independent of Windows' GUI interface.

System messages

System messages are handled via a compiled switch mechanism, which is extensible by the user to include any new messages that need to be handled. For example, this is the code to extend the standard existing Windows message handler SFMESSAGES to include keystroke events:

    [+SWITCH SFMESSAGES
	    WM_SYSKEYDOWN	RUNS KDOWN1
	    WM_KEYDOWN	RUNS KDOWN0
	    WM_CHAR	RUNS CDOWN0
	    WM_SYSCHAR	RUNS CDOWN1
    SWITCH]

Windows dialogs

Dialog boxes are supported via a simple dialog compiler, which parallels the Microsoft resource compiler. SwiftForth's console debugging tool can be used to trace the execution of Windows dialog box code.

A simple example of a dialog box is:

OPTIONAL SIMPLE A modal dialog template which uses catch/throw.

{ ====================================================================
(C) Copyright 1999 FORTH, Inc.   www.forth.com

SIMPLE Dialog box example
==================================================================== }

DIALOG (SIMPLE)  [MODAL  " Press counter"      10   10  160   40
   (FONT 8, MS Sans Serif) ]

\  [control        " default text"     id    xpos ypos xsiz ysiz ]
   [DEFPUSHBUTTON  " OK"               IDOK   105   20   45   15 ]
   [PUSHBUTTON     " Clear"            103     05   20   45   15 ]
   [PUSHBUTTON     " Throw"            104     55   20   45   15 ]
   [RTEXT                              101     05   05   18   10 ]
   [LTEXT          " Total errors"     102     25   05   50   10 ]

END-DIALOG

: SIMPLE-CLOSE ( -- res )   HWND 0 EndDialog ;

VARIABLE PRESSES

: .PRESSES ( -- )   HWND 101 PRESSES @ 0 SetDlgItemInt DROP ;

: THROWING ( -- )   -1 THROW ;

: STUPID ( -- )   ['] THROWING CATCH IF PRESSES ++ .PRESSES THEN ;

[SWITCH SIMPLE-COMMANDS ZERO  ( -- res )
   IDOK     RUN: SIMPLE-CLOSE ;
   IDCANCEL RUN: SIMPLE-CLOSE ;
   103      RUN: PRESSES OFF  .PRESSES 0 ;
   104      RUN: STUPID 0 ;
SWITCH]

[SWITCH SIMPLE-MESSAGES ZERO
   WM_CLOSE      RUNS SIMPLE-CLOSE
   WM_INITDIALOG RUN: ( -- res )   0 PRESSES !  .PRESSES  -1 ;
   WM_COMMAND    RUN: ( -- res )   WPARAM LOWORD SIMPLE-COMMANDS ;
SWITCH]

:NONAME ( -- res )   MSG LOWORD SIMPLE-MESSAGES ;  4 CB: RUNSIMPLE

: SIMPLE
   HINST  (SIMPLE)  HWND  RUNSIMPLE  0  DialogBoxIndirectParam DROP ;

CR CR .( Type SIMPLE to run the dialog sample.) CR CR

«previous next»