From: Stephen Adams Date: Mon, 29 Nov 1993 02:56:15 +0000 (+0000) Subject: Mended Windows installation section. X-Git-Tag: 20090517-FFI~7422 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=be82fbfe829d1022bc74d5470e97290f45a057c9;p=mit-scheme.git Mended Windows installation section. Incorporated Win32 Package documentation. --- diff --git a/v7/doc/user-manual/user.texinfo b/v7/doc/user-manual/user.texinfo index 57977a78a..2ff1da9ce 100644 --- a/v7/doc/user-manual/user.texinfo +++ b/v7/doc/user-manual/user.texinfo @@ -97,9 +97,10 @@ literature without prior written consent from MIT in each case. @end enumerate @end titlepage -@node Top, Running Scheme, (dir), (dir) +@node Top, Installation, (dir), (dir) @menu +* Installation:: * Running Scheme:: Running Scheme * REPL:: The Read-Eval-Print Loop * Debugging:: Debugging @@ -108,19 +109,47 @@ literature without prior written consent from MIT in each case. * Compiling Files:: Compiling Files * GNU Emacs Interface:: GNU Emacs Interface * Edwin:: Edwin +* Win32 Package Reference:: * Variable Index:: Variable, Declaration, and Option Index * Key Index:: Key Index * Concept Index:: Concept Index +--- The Detailed Node Listing --- + +Running Scheme + --- The Detailed Node Listing --- +Installation + +* Generic Unix:: +* C-backend:: +* Microsoft Windows and Windows NT installation:: +* DOS:: + +Microsoft Windows and Windows NT installation + +* System requirements:: +* Manifest:: +* Installation-win32:: Installation +* Known Problems:: + Running Scheme * Basics of Starting Scheme:: Basics of Starting Scheme +* Customizing Scheme:: * Command-Line Options:: Command-Line Options * Environment Variables:: Environment Variables +* Starting Scheme from Microsoft Windows 3.1/NT:: * Leaving Scheme:: Leaving Scheme +Environment Variables + +* General Environment Variables:: +* Environment variables for Bchscheme:: +* Environment variables for PC versions:: +* Environment variables that affect Edwin:: + The Read-Eval-Print Loop * The Prompt and Level Number:: The Prompt and Level Number @@ -143,38 +172,129 @@ Declarations * Standard Names:: Standard Names * In-line Coding:: In-line Coding * Operator Reduction:: Operator Reduction -@end menu +Win32 Package Reference + +* Overview:: +* Foreign function interface:: +* Device Independent Bitmap Utilities:: + +Foreign Function Interface +* Windows Types:: +* Windows Foreign Procedures:: +* Win32 API names and procedures:: -@node +Device Independent Bitmap Utilities + +* DIB procedures:: +* Other parts of the DIB Utilities implementation:: +@end menu + +@node Installation, Running Scheme, Top, Top @chapter Installation -@node +@menu +* Generic Unix:: +* C-backend:: +* Microsoft Windows and Windows NT installation:: +* DOS:: +@end menu + +@node Generic Unix, C-backend, , Installation @section Generic Unix Installation information for Unix versions goes here. (perhaps several a multitude of unixes? -@node +@node C-backend, Microsoft Windows and Windows NT installation, Generic Unix, Installation @section C-backend Installation information for C back-end versions goes here? @c NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -@node +@node Microsoft Windows and Windows NT installation, DOS, C-backend, Installation @section Microsoft Windows and Windows NT installation +This section describes how to install MIT Scheme on Microsoft Windows +3.1 and Microsoft Windows NT. For the most part installing under these +platforms is the same. + +@menu +* System requirements:: +* Manifest:: +* Installation-win32:: Installation +* Known Problems:: +@end menu + +@node System requirements, Manifest, , Microsoft Windows and Windows NT installation +@subsection System requirements + +MIT Scheme requires at least a 386DX with 8Mb RAM. +The bare minimum disk space required is 5.5Mb, which gives you a command +line interface for Scheme. We strongly recommend a more advanced +environment. To build the Edwin editor band requires an additional +4.3Mb. The whole installation without source code occupies 36Mb. + +@node Manifest, Installation-win32, System requirements, Microsoft Windows and Windows NT installation +@subsection Manifest + +The installation comprises the following files: + +@example +bin.zip @r{Scheme binaries} +lib.zip @r{Smaller files from Scheme library} +runtime.zip @r{@file{runtime.com} band} +eddel.zip @r{@file{eddel.com}: a kit to build @file{edwin.com} band} +compedl.zip @r{@file{compdel.com}: a kit to build @file{compiler.com} band} + +bcirun1.zip @r{Debugging information for runtime system} +bcirun2.zip @r{ " " " " "} +bcirun3.zip @r{ " " " " "} +bcied1.zip @r{Debugging information for Edwin} +bcied2.zip @r{ " " " "} +bcied3.zip @r{ " " " "} +bcicomp1.zip @r{Debugging information for compiler} +bcicomp2.zip @r{ " " " "} +bcicomp3.zip @r{ " " " "} +win32s.zip @r{Win32s installation floppy from Microsoft} +@end example + + +@node Installation-win32, Known Problems, Manifest, Microsoft Windows and Windows NT installation +@subsection Installation + +In each of the following steps the amount of disk space consumed is +indicated in square brackets. +These sizes do not include the @file{.zip} files which are required +only during installation. @enumerate +@item +MIT Scheme under Windows 3.1 requires the Win32s system to be installed. +If you have not previously installed the Win32s system then you should +create a floppy disk containing the contents of the @file{win32s.zip} +file, e.g: + +@example +a: +unzip @var{wherever}\win32s.zip +@end example + +Run the @file{setup} command on the floppy disk. + +@example +a:setup +@end example + @item Decide on where to install MIT Scheme. We suggest the default: @file{C:\SCHEME}. -Create the root directory which we from now on refer to as @var{root}. +Create the root directory which we from now on refer to as @var{scheme}. If for example, you choose the default: @example @@ -183,47 +303,59 @@ cd \scheme @end example @noindent -@var{root} is the string @code{C:\scheme} +@var{scheme} is the string `@code{C:\scheme}'. @item -In the @var{root} directory unzip the following essential files: -@file{BIN.ZIP}, @file{LIB.ZIP}, @file{RUNTIME.ZIP}. +In the @var{scheme} directory unzip the following essential files: +@file{bin.zip}, @file{lib.zip} and @file{runtime.zip} [5.5Mb]. @example -unzip bin.zip -unzip lib.zip -unzip runtime.zip +unzip @var{wherever}\bin.zip +unzip @var{wherever}\lib.zip +unzip @var{wherever}\runtime.zip @end example +(@var{Wherever} stands for the place that you have put the @file{.zip} +files, which might be another directory or a floppy disk.) + +@item +If you are installing for Windows 3.1 only, do @emph{one} of the following: +@itemize @bullet @item -If you are installing for Windows 3.1 only, either (a) put the following -line in the @file{AUTOEXEC.BAT} file to ensure that the -@file{@var{root}\bin\win31} directory is on the path: +Put the following line in the @file{autoexec.bat} file to ensure that +the @file{@var{scheme}\bin\win31} directory is on the path: @example -path %PATH%;@var{root}\bin\win31 +path %PATH%;@var{scheme}\bin\win31 @end example -@noindent -or (b) copy the files from @file{@var{root}\bin\win31} into -@file{@var{root}\bin}. - - @item -If you are installing for Windows NT only, either (a) as system -administrator add @file{@var{root}\bin\nt} to the @code{PATH in the -environment (Registry ...) or (b) as an individual place -@code{PATH=}@var{root}@code{\bin\nt} in your enviroment (use the control -panel's system option}, or (c) copy the files from -@file{@var{root}\bin\nt} into @file{@var{root}\bin}. +Copy the files from @file{@var{scheme}\bin\win31} into +@file{@var{scheme}\bin}. +@end itemize +@item +If you are installing for Windows NT only, do @emph{one} of teh +following: +@itemize @bullet +@item +As system +administrator add @file{@var{scheme}\bin\nt} to the @code{PATH} in the +system environment (using the Registry Editor, @code{regedt32}) +@item +As an individual place @code{PATH=}@var{scheme}@code{\bin\nt} in your +environment (use the control panel's system option) +@item +Copy the files from @file{@var{scheme}\bin\nt} into +@file{@var{scheme}\bin}. +@end itemize @item If you are installing for both Windows 3.1 and Windows NT then you must -use an option from the above that does not involve copying files, i.e. -you must arrange for Windows 3.1 to be run with -@file{@var{root}\bin\win31} on the path and for Windows NT to be run -with @file{@var{root}\bin\nt} on the path. +use use environment variables and the @code{PATH} rather than copying +files, i.e. you must arrange for Windows 3.1 to be run with +@file{@var{scheme}\bin\win31} on the path and for Windows NT to be run +with @file{@var{scheme}\bin\nt} on the path. @item @@ -231,7 +363,7 @@ If you did not choose the default installation directory, make sure that the environment variable @code{MITSCHEME_LIBRARY_PATH} is defined: @example -set MITSCHEME_LIBRARY_PATH=@var{root}\lib +set MITSCHEME_LIBRARY_PATH=@var{scheme}\lib @end example @@ -242,12 +374,13 @@ window by running the following from the Program Manager or the File Manager @example -@var{root}\bin\scheme +@var{scheme}\bin\scheme @end example @noindent If there are any problems at this stage review the installation so far. - +Remember that you might have to restart your machine to get the effect +of any changes that you made in @file{autoexec.bat}. @item Now you should create a Program Manager group for MIT Scheme. @@ -255,7 +388,7 @@ This can be done by running a Scheme program from the Program Manager using the @code{File|Run} option: @example -@var{root}\bin\scheme -load @var{root}\etc\pmgrp +@var{scheme}\bin\scheme -load @var{scheme}\etc\pmgrp @end example @noindent @@ -278,132 +411,125 @@ shield) should report that they cannot find their bands. @item To install the Edwin editor you need to build the @file{edwin.com} band. -First unpack the delta file: +First unpack the delta file @file{eddel.com} [1.6Mb]: @example -cd @var{root} -unzip eddel.com +cd @var{scheme} +unzip @var{wherever}\eddel.zip @end example To build @file{edwin.com} start the `build EDWIN.COM band' icon, or run the following command: @example -@var{root}\bin\scheme -large -load @var{root}\etc\build -eval (edwin.com) +@var{scheme}\bin\scheme -large -load @var{scheme}\etc\build -eval (edwin.com) @end example @noindent -This will load in @file{eddel.com} and create the new band. +This will load in @file{eddel.com} and create the new band [4.3Mb]. After a successful build the program will exit. @item To install the compiler you need to build the @file{compiler.com} band. -First unpack the delta file: +First unpack the @file{compdel.com} delta file [2.5Mb]: @example -cd @var{root} -unzip compdel.com +cd @var{scheme} +unzip @var{wherever}\compdel.zip @end example To build @file{compiler.com} start the `build COMPILER.COM band' icon, or run the following command: @example -@var{root}\bin\scheme -large -load @var{root}\etc\build -eval (compiler.com) +@var{scheme}\bin\scheme -large -load @var{scheme}\etc\build -eval (compiler.com) @end example @noindent -This will load in @file{compdel.com} and create the new band. -After a successful build the program will exit. +This will load in @file{compdel.com} and create the new +@file{compiler.com} band [4.8Mb]. After a successful build the program +will exit. @item If you want both Edwin and the compiler in one band you should build the -@file{all.com} band. -First unpack the delta files: +@file{all.com} band. First unpack the delta files [4.1Mb unless already +unpacked in previous steps]: @example -cd @var{root} -unzip eddel.com -unzip compdel.com +cd @var{scheme} +unzip @var{wherever}\eddel.zip +unzip @var{wherever}\compdel.zip @end example To build @file{all.com} start the `build ALL.COM band' icon, or run the following command: @example -@var{root}\bin\scheme -large -load @var{root}\etc\build -eval (all.com) +@var{scheme}\bin\scheme -large -load @var{scheme}\etc\build -eval (all.com) @end example @noindent -This will load in both @file{eddel.com} and @file{compdel.com} and -create the new band. After a successful build the program will exit. +This will load in both @file{eddel.com} and @file{compdel.com} into the +runtime band and create the new band [6.7Mb]. After a successful build +the program will exit. @item Any combination of @file{edwin.com}, @file{compiler.com} and -@file{all.com} may be used. It is not necessary to build either of -@file{edwin.com} and @file{compiler.com} before building and using -@file{all.com}. After building the bands you may tidy the MIT Scheme -group by removing the mincer icons and recover disk space -by deleting the delta files. +@file{all.com} may be used. They may be built in any order: it is not +necessary to build either of @file{edwin.com} and @file{compiler.com} +before building and using @file{all.com}. After building the bands you +may tidy the MIT Scheme group by removing the mincer icons and recover +disk space by deleting the delta files [4.1Mb] and the +@file{runtime.com} band [2.3Mb] if you do not need it. To create icons that use @code{bchscheme} instead of @code{scheme} copy the icons and edit the command lines to change `scheme' to `bchschem' (that is right: no tailing `e'). @item -Debugging information can be installed by uncompressing the files in the -Scheme root directory @var{root}. The most useful is the runtime -debugging info which is in @file{RUNBCI.ZIP}. These files can be -installed in another directory. If this is done then set the -@var{MITSCHEME_INF_DIRECTORY} environment variable to this directory. -@file{EDWINBCI.ZIP} and @file{COMPBCI.ZIP} hold the debugging info files -for Edwin and the compiler respectively. +Debugging information can be installed by uncompressing the +@file{bci*.zip} files in the Scheme root directory @var{scheme}. The +total space required for all of the debugging information is 11.3Mb. +The most useful is the runtime debugging info which is in +@file{bcirun1.zip} through @file{bcirun3.zip} [3.6Mb installed]. + +Debugging information files can be installed in the Scheme root +directory or in another directory. If another directory is chosen then +set the @code{MITSCHEME_INF_DIRECTORY} environment variable to this +directory. @file{bcied1.zip} through @file{bcied3.zip} [3.8Mb +installed] and @file{bcicomp1.zip} through @file{bcicomp3.zip} [4Mb +installed] hold the debugging information files for Edwin and the +compiler respectively. @end enumerate -@node -@subsection random junk - -@table @asis -@item Win32s DLLs - -@item * - -@item Binaries -Choice 1: 3.1 xor NT: put DLLs with scheme.exe -Choice 2: 3.1 and NT: (a) two bin directories -(b) One bin, DLLs in separate directories, these directories on the -path. - - -@end table - -@node -@subsection Manifest - - -BIN.ZIP +@node Known Problems, , Installation-win32, Microsoft Windows and Windows NT installation @subsection Known Problems -@itemize @asis +@itemize @bullet -@item * -MIT Scheme is a lot more robust under NT than Windows 3.1 +@item +MIT Scheme is more robust under NT than Windows 3.1 -@item Exclusive file access [NT] +@item +Exclusive file access [NT]. Can't write a file that is still open for reading. (e.g. mismatched paren in @code{(load "foo.scm")}. Work-around: Quit to top level. Do a @code{(gc-flip)} to force file to be closed. Now you will be able to save the file. +@item +@code{MITSCHEME_INF_DIRECTORY} sometimes does not work. +The runtime system cannot find the debugging information unless it is on +the @file{C:} drive. - -@item Edwin autoloads +@item +Edwin autoloads. A few files that are automatically part of Edwin under unix are not part of Edwin in the PC. These can be loaded manually from the auto-load directory, for example, by putting @@ -420,56 +546,58 @@ in your @file{edwin.ini} file. -@node -@subsection NT build - -The windows/NT version can only be built under Windows NT. - -@table @asis -@item no TOUCH command -Create the following 1 line script in @file{TOUCH.BAT}: - -@example -echo on > %1 -@end example - -@item can't find @file{w32sut.h} -These files are a part of Win32S: @file{w32sut.h}, @file{?.dll}, @file{?.dll} -You need to copy @file{w32sut.h} from -@end table - - -TTD - -w32sut.h & dlls to ntutl/config +@c @node +@c @subsection NT build +@c +@c +@c @table @asis +@c @item Build +@c The Windows/NT version can be built only under Windows NT. +@c +@c @item no TOUCH command +@c Create the following 1 line script in @file{TOUCH.BAT}: +@c +@c @example +@c echo on > %1 +@c @end example +@c +@c @item can't find @file{w32sut.h} +@c These files are a part of Win32S: @file{w32sut.h}, @file{?.dll}, @file{?.dll} +@c You need to copy @file{w32sut.h} from +@c @end table +@c +@c +@c w32sut.h & dlls to ntutl/config? @c NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN -@node +@node DOS, , Microsoft Windows and Windows NT installation, Installation @section DOS Installation information for DOS version goes here -@node Running Scheme, REPL, Top, Top +@node Running Scheme, REPL, Installation, Top @chapter Running Scheme This chapter describes how to run MIT Scheme on a unix system or a PC running DOS, Microsoft Windows or Windows NT. -It also describes how you can customize the behaviour of MIT Scheme +It also describes how you can customize the behavior of MIT Scheme using command-line options and environment variables. @menu * Basics of Starting Scheme:: Basics of Starting Scheme +* Customizing Scheme:: * Command-Line Options:: Command-Line Options * Environment Variables:: Environment Variables +* Starting Scheme from Microsoft Windows 3.1/NT:: * Leaving Scheme:: Leaving Scheme @end menu -@node Basics of Starting Scheme, Command-Line Options, Running Scheme, Running Scheme +@node Basics of Starting Scheme, Customizing Scheme, , Running Scheme @section Basics of Starting Scheme Usually, MIT Scheme is invoked by typing @@ -514,15 +642,14 @@ the part of the system that is written in Scheme. @cindex subsystem versions @cindex SF, version -@cindex CREF, version @cindex compiler, version @cindex Edwin, version @cindex student package, version @cindex compatibility package, version Following this there may be additional version numbers for specific subsystems. @samp{SF} refers to the scode optimization program -@code{sf}, @samp{Liar} is the native-code compiler, @samp{CREF} is the -cross-reference generator, @samp{Edwin} is the Emacs-like text editor, +@code{sf}, @samp{Liar} is the native-code compiler, +@samp{Edwin} is the Emacs-like text editor, and @samp{Student} is the S&ICP compatibility package. @cindex compiler, starting @@ -538,7 +665,7 @@ This option causes Scheme to use a larger constant space and heap, and to load the world image containing the compiler. -@node +@node Customizing Scheme, Command-Line Options, Basics of Starting Scheme, Running Scheme @section Customizing Scheme You can customize your setup by using a variety of tools: @@ -658,7 +785,7 @@ The Scheme procedure @code{(print-gc-statistics)} shows how much heap and constant space is available. -@node Command-Line Options, Environment Variables, Basics of Starting Scheme, Running Scheme +@node Command-Line Options, Environment Variables, Customizing Scheme, Running Scheme @section Command-Line Options Scheme accepts the command-line options detailed in the following @@ -966,7 +1093,7 @@ environment variable @code{MITSCHEME_GC_WRITE_OVERLAP} is used instead, and if that is not defined, 0 is used, disabling overlapped writes. @end table -@node Environment Variables, Leaving Scheme, Command-Line Options, Running Scheme +@node Environment Variables, Starting Scheme from Microsoft Windows 3.1/NT, Command-Line Options, Running Scheme @section Environment Variables @@ -983,7 +1110,14 @@ The rest of this section is a summary of the environment variables that are specific to MIT Scheme. The environment variables are organised according to the parts of MIT Scheme that they affect. -@node +@menu +* General Environment Variables:: +* Environment variables for Bchscheme:: +* Environment variables for PC versions:: +* Environment variables that affect Edwin:: +@end menu + +@node General Environment Variables, Environment variables for Bchscheme, , Environment Variables @subsection General Environment Variables @table @asis @@ -1065,7 +1199,7 @@ and @code{-utab}. It is only necessary when re-building @end table -@node +@node Environment variables for Bchscheme, Environment variables for PC versions, General Environment Variables, Environment Variables @subsection Environment variables for Bchscheme @table @asis @@ -1118,7 +1252,7 @@ The maximum number of simultaneous write operations. Overriden by @code{-gc-write-overlap}. @end table -@node +@node Environment variables for PC versions, Environment variables that affect Edwin, Environment variables for Bchscheme, Environment Variables @subsection Environment variables for PC versions These environment variables only make sense to the Microsoft Windows, @@ -1186,7 +1320,7 @@ to @code{TMP}. @end table -@node +@node Environment variables that affect Edwin, , Environment variables for PC versions, Environment Variables @subsection Environment variables that affect Edwin @table @asis @@ -1247,7 +1381,7 @@ adapter and support software. E.g. 132. @end table -@node +@node Starting Scheme from Microsoft Windows 3.1/NT, Leaving Scheme, Environment Variables, Running Scheme @section Starting Scheme from Microsoft Windows 3.1/NT There are two distinct versions of MIT Scheme that run on IBM @@ -1303,7 +1437,7 @@ at the end of the command line. -@node Leaving Scheme, , Environment Variables, Running Scheme +@node Leaving Scheme, , Starting Scheme from Microsoft Windows 3.1/NT, Running Scheme @section Leaving Scheme There are two ways you can leave Scheme. The first is to evaluate @@ -1359,7 +1493,7 @@ another prompt. * The Current REPL Environment:: The Current REPL Environment @end menu -@node The Prompt and Level Number, Interrupting, REPL, REPL +@node The Prompt and Level Number, Interrupting, , REPL @section The Prompt and Level Number @cindex prompt, REPL @@ -1695,7 +1829,7 @@ appear, be prepared to attack them with all the tools available. * Debugger:: The Debugger @end menu -@node Subproblems and Reductions, Debugger, Debugging, Debugging +@node Subproblems and Reductions, Debugger, , Debugging @section Subproblems and Reductions @cindex subproblem @@ -1941,7 +2075,7 @@ available on machines that support native-code compilation. * Declarations:: Declarations @end menu -@node Compilation Procedures, Declarations, Compiling Files, Compiling Files +@node Compilation Procedures, Declarations, , Compiling Files @section Compilation Procedures @deffn {procedure+} cf filename [destination] @@ -2048,7 +2182,7 @@ Several declarations can be added to your programs to help @code{cf} and * Operator Reduction:: Operator Reduction @end menu -@node Standard Names, In-line Coding, Declarations, Declarations +@node Standard Names, In-line Coding, , Declarations @subsection Standard Names Normally, all files have a line @@ -2510,7 +2644,7 @@ Like typing @kbd{C-c C-b} when running Scheme without Emacs Like evaluating @code{(proceed)} (@code{xscheme-send-proceed}). @end table -@node Edwin, Variable Index, GNU Emacs Interface, Top +@node Edwin, Win32 Package Reference, GNU Emacs Interface, Top @chapter Edwin This chapter describes how to start Edwin, the MIT Scheme text editor. @@ -2658,7 +2792,924 @@ Edwin's internal display data structures to get into an inconsistent state that prevents Edwin from running. @end deffn -@node Variable Index, Key Index, Edwin, Top +@c WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +@node Win32 Package Reference, Variable Index, Edwin, Top +@chapter Win32 Package Reference + +@ifinfo +The Win32 implementation is still in a state of development. It is +expected that changes will be necessary when MIT Scheme is ported to +Microsoft Windows NT on the DEC Alpha architecture. In particular, the +current system is not arranged in a way that adequately distinguishes +between issues that are a consequence of the NT operating system and +those which are a consequence of the Intel architecture. +@end ifinfo + +@menu +* Overview:: +* Foreign function interface:: +* Device Independent Bitmap Utilities:: +@end menu + +@c @node Acknowledgements, Overview, Top, Top +@c @unnumbered Acknowledgements +@c +@c Somebody must have helped! +@c GJR, Alan Bawden. + +@node Overview, Foreign function interface, , Win32 Package Reference +@section Overview + + +The Win32 implementation is still in a state of development. It is +expected that changes will be necessary when MIT Scheme is ported to +Microsoft Windows NT on the DEC Alpha architecture. In particular, the +current system is not arranged in a way that adequately distinguishes +between issues that are a consequence of the NT operating system and +those which are a consequence of the Intel architecture. +@cindex limitations + +Thus this documentation is not definitive, it merely outlines how the +current system works. Parts of the system will change and any project +implemented using the win32 system must plan for a re-implementation +stage. + + +The Win32 implementation has several compononents: + +@itemize @bullet + +@item +Special microcode primitives. + +@item +A foreign function interface (FFI) for calling procedures in dynamically +linked libraries (DLLs). + +@item +An interface for Edwin. + +@item +The Win32 package provides support for using the features of the +Microsoft Windows 3.1 and Microsoft Windows NT 3.1 environments. + +@item +Device Independent Bitmap utilities. These are used by the win32 Scheme +Graphics implementation. (The Scheme Graphics implementation is +described in the Reference Manual). + +@end itemize + +Note that all the names in the Win32 support are part of the +@code{win32} package. The names are bound in the @code{(win32)} +environment, and do not appear as bindings in the user or root +environments. +An effect of this is that it is far easier to develop Win32 software in +the @code{(win32)} package environment or a child environment. + +@node Foreign function interface, Device Independent Bitmap Utilities, Overview, Win32 Package Reference +@section Foreign Function Interface + +The Win32 foreign function interface (FFI) is a primitive and fairly +simple system for calling procedures written in C in a +dynamically linked library (DLL). Both user's procedures from a custom +DLL and system procedures (e.g. MessageBox) are called using the same +mechanism. + +@cindex limitations +@strong{Warning:} The FFI as it stands has several flaws which make it +difficult to use reliably. It is expected that both the interface to +and the mechanisms used by the FFI will be changed in the future. We +provide it, and this documentation, only to give people an early start +in accessing some of the features of Win32 from Scheme. Should you use +it in an experiment we welcome any feedback. + +The FFI is designed for calling C procedures that use C data types +rather than Scheme data objects. Thus it is not possible to write and +call a C procedure that returns, for example, a Scheme list. The object +returned will always be an integer (which may represent the address of a +C data structure). + +@cindex warning +@strong{Warning:} It is extremely dangerous to try to pass Scheme +callback procedures to C procedures. It is only possible by passing +integer `handles' rather than the actual procedures, and even so, if a +garbage collection occurs during the execution of the callback procedure +objects in Scheme's heap will have moved. Thus in a foreign procedure +that has a callback and a string, after calling the callback the string +value may no longer be valid. Playing this game requires a profound +knowledge of the implementation. + + +The interface to the FFI has two main components: a language for +declaring the types of values passed to and returned from the foreign +procedures and a form for declaring foreign procedures. + +@menu +* Windows Types:: +* Windows Foreign Procedures:: +* Win32 API names and procedures:: +@end menu + +@node Windows Types, Windows Foreign Procedures, , Foreign function interface +@subsection Windows Types + +@cindex Windows types +@cindex foreign type declarations +@cindex types, Windows +@cindex defining foreign types +Foreign types are designed to represent a correspondence between a +Scheme data type that is used to represent an object within the Scheme +world and a C data type that represents the data object in the C world. +Thus we cannot manipulate true C objects in Scheme, nor can we +manipulate Scheme objects in C. + +Each foreign type has four aspects that together ensure that the +correspondence between the Scheme and C objects is maintained. These +aspects are all encoded as procedures that either check for validity or +convert between representations. Thus a foreign type is not a +declarative type so much as a procedural description of how to pass the +type. The underlying foreign procedure call mechanism can pass integers +and vector-like Scheme objects, and returns integer values. All other +objects must be translated into integers or some other basic type, and +must be recovered from integers. + +The aspects are: + +@table @var + +@item check +A predicate that returns @code{#t} if the argument is of an acceptable +Scheme type, otherwise returns @code{#f}. +The @var{check} procedure is used for type-checking. + +@item convert +A procedure of one argument which returns a Scheme object of one of the +basic types. +It is used to convert an object into a `simpler' object that will +eventually be converted into a C object. +The legal simpler objects are integers and strings. + +@item return-convert +A procedure of one argument that, given an integer, returns a Scheme +object of a type satisfying @var{check}. +Its purpose is to convert the result returned by the foreign procedure +into a Scheme value. + +@item revert +Some C procedures modify one or more of their arguments. These +arguments are passed by reference, i.e. as a pointer to their address. +Since a Scheme object might have a different memory layout and storage +conventions, it must be passed by copy-in and copy-out rather than by +reference. +@var{Revert} is a procedure of two parameters, the original object +passed and the result of @var{convert} on that object. +@var{Revert} may then inspect the converted object and copy back the +changes to the original. + +@end table + +@deffn {special form+} define-windows-type name check convert return revert +@deffnx {special form+} define-similar-windows-type name model [check [convert [return [revert]]]] +@cindex defining foreign types +Both forms define a windows type. +The first form defines a type in terms of its aspects as described +above. +The second defines the type as being like another type, except for +certain aspects, which are redefined. +@var{Name} is the name of the type. +@var{Model} is the name of a type. +@var{Check}, @var{convert}, @var{return} and @var{revert} are +procedures or the value @code{#f}. +A @code{#f} means use the default value, which in the second form means +use the definition provided for @var{model}. +The defaults are + +@table @var +@item check +@code{(lambda (x) #t)}, i.e. unchecked. +@item convert +@code{(lambda (x) x)}, i.e. no translation performed. +@item return +@code{(lambda (x) x)}, i.e. no translation performed. +@item revert +@code{(lambda (x y) unspecific)}, i.e. no update performed +@end table + +The @code{unchecked} windows type (see below) is defined as: + +@example +(define-windows-type unchecked #f #f #f #f) +@end example + +Windows types are @emph{not} first class values, so they cannot be +stored in variables or defined using @code{define}: + +@example +(define my-type unchecked) @error{} Unbound variable +(define-similar-windows-type umy-type unchecked) @r{;; the correct way} +@end example + +Scheme characters must be converted to integers. This is accomplished +as follows: + +@example +(define-windows-type char + char? @r{; check} + char->integer @r{; convert} + integer->char @r{; convert return value} + #f @r{; cannot be passed by reference} +) +@end example +@end deffn + +@deffn {windows type} unchecked +The type which is not checked and undergoes only the basic conversion +from a Scheme integer to a C integer or from a Scheme string to a C +pointer to the first byte of the string. +Returned @code{unchecked} values are returned as integers. +@end deffn + +@deffn {windows type} bool +Scheme booleans are analogous to C integers @code{0} and @code{1}. +Windows type @code{bool} have been defined as: + +@example +(define-windows-type bool + boolean? + (lambda (x) (if x 1 0)) + (lambda (x) (if (eq? x 0) #f #t)) + #f) +@end example +@end deffn + +@deffn {windows type} char +Scheme characters are converted into C objects of type @code{char}, +which are indistinguishable from small integers. +@end deffn + +@deffn {windows type} int +@deffnx {windows type} uint +@deffnx {windows type} long +@deffnx {windows type} ulong +@deffnx {windows type} short +@deffnx {windows type} ushort +@deffnx {windows type} word +@deffnx {windows type} byte +Various integer types that are passed without conversion. +@end deffn + +@deffn {windows type} string +A string that is passed as a C pointer of type @code{char*} to the first +character in the string. +@end deffn + +@deffn {windows type} char* +A string or @code{#f}. The string is passed as a pointer to characters. +The string is correctly nul-terminated. @code{#f} is passed as the null +pointer. This is an example where there is a more complex mapping +between C objects and Scheme objects. C's @code{char*} type is +represented as one of two Scheme types depending on its value. This +allows us us to distinguish between the C string (pointer) that points +to the empty sequence of characters and the null pointer (which doesnt +point anywhere). +@end deffn + +@deffn {windows type} handle +@deffnx {windows type} hbitmap +@deffnx {windows type} hbrush +@deffnx {windows type} hcursor +@deffnx {windows type} hdc +@deffnx {windows type} hicon +@deffnx {windows type} hinstance +@deffnx {windows type} hmenu +@deffnx {windows type} hpalette +@deffnx {windows type} hpen +@deffnx {windows type} hrgn +@deffnx {windows type} hwnd +Various kinds of Win32 handle. These names correspond to the same, but +all uppercase, names in the Windows C language header files. Win32 API +calls are the source of values of this type and the values are +meaningless except as arguments to other Win32 API calls. Currently +these values are represented as integers but we expect that Win32 +handles will in future be represented by allocated Scheme objects (e.g. records) +that will allow predicates (e.g. @code{hmenu?}) and sensible +interlocking with the garbage collector to free the programmer of the +current tedious allocation and deallocation of handles. +@end deffn + +@deffn {windows type} resource-id +A Windows resource identifier is either a small integer or a string. +In C, this distinction is possible because pointers look like +larger integers, so a machine word representing a small integer can be +distinguished from a machine word that is a pointer to the text of the +name of the resource. +@end deffn + + +@node Windows Foreign Procedures, Win32 API names and procedures, Windows Types, Foreign function interface +@subsection Windows Foreign Procedures + +Foreign procedures are declared as callable entry-points in a module, +usually a dynamically linked library (DLL). + + +@deffn {procedure+} find-module name +@cindex loading DLLs +@cindex DLL, loading +Returns a module suitable for use in creating procedures with +@code{windows-procedure}. @var{Name} is a string which is the name of a +DLL file. Internally, @code{find-module} uses the @code{LoadLibrary} +Win32 API, so @var{name} should conform to the specifications for this +call. @var{Name} should be either a full path name of a DLL, or the +name of a DLL that resides in the same directory as the Scheme binary +@file{SCHEME.EXE} or in the system directory. + +The module returned is a description for the DLL, and the DLL need not +necessarily be linked at or immediately after this call. DLL modules +are linked on need and unlinked before Scheme exits and when there +are no remaining references to entry points after a garbage-collection. +This behaviour ensures that the Scheme system can run when a DLL is +absent, provided the DLL is not actually used (i.e. no attempt is made +to call a procedure in the DLL). +@end deffn + + +@defvr {variable+} gdi32.dll +@cindex DLL, GDI32.DLL +This variable is bound to the module describing the @file{GDI32.DLL} +library, which contains the Win32 API graphics calls, e.g. +@code{LineTo}. +@end defvr + +@defvr {variable+} kernel32.dll +@cindex DLL, KERNEL32.DLL +This variable is bound to the module describing the @file{KERNEL32.DLL} +library. +@end defvr + +@defvr {variable+} user32.dll +@cindex DLL, USER32.DLL +This variable is bound to the module describing the @file{USER32.DLL} +library. This module contains many useful Win32 API procedures, like +@code{MessageBox} and @code{SetWindowText}. +@end defvr + + +@deffn {special form+} windows-procedure (name (parameter type) ...) return-type module entry-name [options] +@cindex defining foreign procedures +This form creates a procedure, and could be thought of as +``foreign-named-lambda''. The form creates a Scheme procedure that +calls the C procedure identified by the exported entry point +@var{entry-name} in the module identified by the value of @var{module}. +Both @var{entry-name} and @var{module} are evaluated at procedure +creation time, so either may be expression. @var{Entry-name} must +evaluate to a string and @var{module} must evaluate to a module as +returned by @code{find-module}. +These are the only parts of the form that are evaluated at procedure +creation time. + +@var{Name} is the name of the procedure and is for documentation +purposes only. This form @emph{does not} define a procedure called +@var{name}. It is more like @code{lambda}. The name might be used for +debugging and pretty-printing. + +A windows procedure has a fixed number of parameters (i.e. no `rest' +parameters or `varargs'), each of which is named and associated with a +windows type @var{type}. Both the name @var{parameter} and the windows +type @var{type} must be symbols and are not evaluated. The procedure +returns a value of the windows type @var{return-type}. + +The following example creates a procedure that takes a window handle +(@code{hwnd}) and a string and returns a boolean (@code{bool}) result. +The procedure does this by calling the @code{SetWindowText} entry in the +module that is the value of the variable @code{user32.dll}. The +variable @code{set-window-title} is defined to have this procedure as +it's value. + +@example +(define set-window-title + (windows-procedure (set-window-text (window hwnd) (text string)) + bool user32.dll "SetWindowText")) + +(set-window-title my-window "Hi") @result{} #t + @r{;; Changes window's title/text} + +set-window-title @result{} #[compiled-procedure 56 ...] +set-window-text @error{} Unbound variable +@end example + + +When there are no @var{options} the created procedure will (a) check its +arguments against the types, (b) convert the arguments, (c) call the C +procedure and (d) convert the returned value. No reversion is +performed, even if one of the @var{types} has a reversion defined. +(Reverted types are rare [I have never used one], so paying a cost for +this unless it is used seems silly). + +The following options are allowed: + +@table @asis +@item @code{with-reversions} +The reversions are included in the type conversions. + +@item @code{expand} +A synonym for @code{with-reversions}. + +@item @var{Scheme code} +The @var{Scheme code} is placed between steps (a) and (b) in the default +process. The Scheme code can enforce constraints on the arguments, +including constraints between arguments such as checking that an index +refers to a valid position in a string. +@end table + +If both options (i.e. @code{with-reversions} and Scheme code) are used, +@code{with-reversions} must appear first. There can be arbitrarily many +Scheme expression. +@end deffn + +@node Win32 API names and procedures, , Windows Foreign Procedures, Foreign function interface +@subsection Win32 API names and procedures + +This section is a moving target. +@cindex Win32 API names +@cindex naming conventions + +The @code{#define} values from @file{wingdi.h} and @file{winuser.h} are +available as bindings in the @code{(win32)} package environment. The +@code{#define} symbols are all uppercase; these have been translated to +all lowercase Scheme identifiers, thus @code{WM_LBUTTONUP} is the scheme +variable @code{wm_lbuttonup}. As Scheme is case insensitive, the +upper-case version may be used and probably should to make the code look +more like conventional Windows code. The Scheme bindings have been +produced automagically. Most of the @code{#define}-symbols contain an +underscore so there are not many name clashes. There is one very +notable name clash, however: @code{ERROR} is @code{#define}d to 0, which +shadows the scheme procedure @code{error} in the root package +environment. To signal an error, use @code{access}: + +@example +((access error ()) "Whine moan" ...) +@end example + + +The set of procedures is incomplete because procedures have been added +on a by-need basis for the implementation of other parts of the system, +e.g. Scheme Graphics. Look in the implementation for further details. + +Win32 API procedure names have been uniformly converted into Scheme +identifiers as follows: + +@itemize @bullet +@item +A leading uppercase letter is translated into a lowercase letter. +@item +Subsequent sequences of uppercase letters are translated into lowercase +letters preceeded by a hyphen (minus symbol), i.e. hyphens are inserted +at a lowercase to uppercase transition. +@item +Predicates beginning with @code{Is} finally have a +question-mark appended. +@end itemize +Example: applying these rules to @code{IsWindow} yields +@code{is-window?}, and @code{GetDC} is translated into @code{get-dc}. + + +[It might be worthwhile just keeping the same names. As the +Win32 API procedure names are uniformly `WordWordWordACRONYMWord', case +insensitivity is unlikely to be a problem. The only problem is the +protential for a clash between a procedure name and a type +name.] + + +@node Device Independent Bitmap Utilities, , Foreign function interface, Win32 Package Reference +@section Device Independent Bitmap Utilities + + +The Device Independent Bitmap (DIB) utilities DLL @file{DIBUTILS.DLL} +and the associated procedures in @file{dib.scm} in the Win32 system +source is an example of how to use the foreign function interface to +access and manipulate non-Scheme objects. +@cindex DLL, DIBUTILS.DLL + +@deffn {windows type} dib +In the C world a DIB is a handle to a piece of memory containing the +bits that represent information about the image and the pixels of the +image. The handle is a machine-word sized piece of data which may be +thought of as a 32 bit integer. The handle may be null, indicating that +there is no block of memory describing the DIB. The null value is +usually returned by C functions that are supposed to create a DIB but +failed, for some reason like the memory could not be allocated or a file +could not be opened. + +In the Scheme world a DIB is a structure containing information +about the bitmap (specifically the integer that represents the handle). +We also include @code{#f} in the @code{dib} windows type to mirror the +null handle error value. +@example +(define dib-result + (lambda (handle) + (if (= handle 0) + #f + (make-dib handle)))) + +(define dib-arg + (lambda (dib) + (if dib + (cell-contents (dib-handle dib)) + 0))) + +(define-windows-type dib + (lambda (thing) (or (dib? thing) (eq? thing #f))) + dib-arg + dib-result) +@end example +@end deffn + + +@menu +* DIB procedures:: +* Other parts of the DIB Utilities implementation:: +@end menu + +@node DIB procedures, Other parts of the DIB Utilities implementation, , Device Independent Bitmap Utilities +@subsection DIB procedures + +The following procedures have typed parameters, using the same +convention as @code{windows-procedure}. + +@deffn {procedure+} open-dib (filename string) +Return type: @var{dib}. Calls the "OpenDIB" entry of +@file{DIBUTILS.DLL}. If the return value is not @code{#f} then the file +@var{filename} was found, successfully opened, and the contents were +suitable for loading into memory as a device independent bitmap. +@end deffn + +@deffn {procedure+} write-dib (filename string) (dib dib) +Return type: @var{bool}. Calls the "WriteDIB" entry of +@file{DIBUTILS.DLL}. Returns @code{#t} if the file @var{filename} could +be opened and written to. After this operation the file contains the +bitmap data in a standard format that is understood by @code{open-dib} +and various system utilities like the bitmap editor. Any problems +resulting in failure are signalled by a @code{#f} return value. +@end deffn + +@deffn {procedure+} bitmap-from-dib (dib dib) (palette hpalette) +Return type: @var{hbitmap}. +Calls the "BitmapFromDib" entry of @file{DIBUTILS.DLL}. The returned +value is a device dependent bitmap. The colours from the DIB are +matched against colors in @var{palette}. +@end deffn + +@deffn {procedure+} dib-from-bitmap (bitmap hbitmap) (style dword) (bits word) (palette hpalette) +Return type: @var{dib}. +Returns a DIB containing the same image as the device dependent bitmap +@var{bitmap}. +@var{Style} determines the kind of DIB, e.g. compression style. +Calls the "DibFromBitmap" entry of @file{DIBUTILS.DLL}. +@end deffn + +@deffn {procedure+} dib-blt (dest hdc) (x int) (y int) (w int) (h int) (src dib) (src-x int) (src-y int) (raster-op long) +Return type: @var{bool}. Calls the "DibBlt" entry of +@file{DIBUTILS.DLL}. Similar to the Win32 API @code{BitBlt} call, but +draws a DIB rather than a piece of another device context. Draws the +@var{dib} on device context @var{hdc} at position (@var{x},@var{y}). A +rectange of width @var{w} and height @var{h} is copied from position +(@var{src-x},@var{src-y}) of @var{dib}. +@var{Raster-op} is supposed to allow the source and destination to be +combined but I don't think I got this right so stick to @code{SRCCOPY}. +@end deffn + +@deffn {procedure+} %delete-dib (dib-handle handle) +Return type: @var{bool}. +Calls the "DeleteDIB" entry of @file{DIBUTILS.DLL}. +Note that the parameter is a @var{handle}, and not a @var{dib}. +This allows us to destroy a DIB and reclaim its memory by knowing only +the handle value, and not needing the @code{dib} record. +The importance of this is that if the @code{dib} record is GC-ed then a +GC hook can reclaim the storage knowing only the handle. +@end deffn + +@deffn {procedure+} delete-dib (dib dib) +Return type: @var{bool}. +This procedure calls @code{%delete-dib} to reclaim the storage occupied +by a DIB. +After being deleted, the DIB should not be used. +This procedure allows the programmer to reclaim external heap storage +rather than risking it running out before the next garbage collection. +@end deffn + +@deffn {procedure+} dib-height (dib dib) +Return type: @var{int}. +Calls the "DibHeight" expand entry of @file{DIBUTILS.DLL}, which returns +the height of the bitmap in pixels. +@end deffn + +@deffn {procedure+} dib-width (dib dib) +Return type: @var{int}. +Calls the "DibWidth" entry of @file{DIBUTILS.DLL}, which returns +the width of the bitmap in pixels. +@end deffn + +@deffn {procedure+} copy-bitmap (bm hbitmap) +Return type: @var{hbitmap}. +Calls the "CopyBitmap" of @file{DIBUTILS.DLL}, which creates a new +bitmap with the same size and contents as the original. +@end deffn + +@deffn {procedure+} create-dib (width int) (height int) (style int) (depth int) (palette hpalette) +Return type: @var{dib}. +Calls the "CreateDIB" entry of @file{DIBUTILS.DLL}. +Creates a DIB of @var{width} by @var{height} pixels and @var{depth} bits +of colour information. +The @var{style} parameter determines how the bitmap is stored. +I have only ever used @code{BI_RGB}. +If @var{depth}<=8 then the @var{palette} determines the DIB's colour table. +@end deffn + +@deffn {procedure+} crop-bitmap (bm hbitmap) (left int) (top int) (right int) (bottom int) +Return type: @var{hbitmap}. +Calls the "CropBitmap" entry of @file{DIBUTILS.DLL}. +Returns a new bitmap containing the image from a region of the original. +@end deffn + +@deffn {procedure+} dib-set-pixels-unaligned dib (pixels string) +Return type: @var{bool}. +Calls the "DIBSetPixelsUnaligned" entry of @file{DIBUTILS.DLL}. Stuffs +bytes from @var{pixels} into the bitmap. There are no alignment +constraints on @var{pixels} (the usual way of doing this is to use the +@code{SetDIBits} function which requires that every scan line of the +bitmap is 32-bit word aligned, even if the scan lines are not a multiple +of 4 bytes long). doing this +@end deffn + +@node Other parts of the DIB Utilities implementation, , DIB procedures, Device Independent Bitmap Utilities +@subsection Other parts of the DIB Utilities implementation + + +The @file{DIBUTILS.DLL} library is an ordinary DLL. See the standard +Microsoft documentation on how to create DLLs. Look at the code in the +@file{WIN32/DIBUTILS} directory of the Scheme source. + +Please note: +@itemize +@item +@cindex DLL, exports +For the foreign function interface to find the procedures they must be +declared as exports in the @file{.DEF} definition file. + +@item +To load the @file{.DLL} file use the @code{find-module} Scheme function. +Look at @file{WIN32/DIB.SCM} to see how this is done. + +@item +The current system works with C procedures with the @code{__stdcall} and +@code{__cdecl} calling conventions but @emph{not} the @code{__fastcall} +calling convention. +@end itemize + + +@c @node Writing windows procedures, Procedure Index, Device Independent Bitmap Utilities, Top +@c @section Writing windows procedures +@c +@c @cindex warning +@c @strong{Warning:} Do not try to do this. It is very hard to get it even +@c partly right and probably impossible to make the program 100% reliable. +@c +@c It is possible to write Scheme procedures that determine the behaviour +@c of windows and controls on the screen. To succeed at this you need a +@c good understanding of how you would do the same thing in C using the +@c Windows SDK, the limitations of mixed language working when C calls +@c Scheme, and lots of patience because debugging this kind of code is very +@c painful. +@c The only major example of this kind of code is the Scheme Graphics +@c implementation (source in @file{WIN32/GRAPHICS.SCM}, but you will need +@c to read @file{RUNTIME/GRAPHICS.SCM} and the DIB utilities too). +@c +@c Currently, Scheme `wndprocs' are run during interrupt processing. They +@c are run in the dynamic context of whatever was running when the +@c interrupt was signalled. Any procedure that relies upon a fluid +@c variable cannot be used reliably. Thus doing, say, a @code{display} +@c might result in the output unintentionally being inserted in a file +@c rather than appearing on the screen. Errors are not handled, thus a +@c call to @code{(+ #f 5)} can result in the interrupt processing mechanism +@c becoming confused, and subsequently causing the system to lock up, as +@c all user input ultimately is processed using this same mechanism. +@c Obviously this state of affairs is not satisfactory and I intend to +@c improve things by running the wndprocs in a known dynamic context and +@c trapping errors, but not until Edwin's I/O handling is changed to +@c separate it more from this mechanism, and definitely not until after the +@c release. +@c +@c @menu +@c * Procedures:: +@c * Scheme WndProcs:: +@c @end menu +@c +@c @node Procedures, , , Writing windows procedures +@c @subsection Procedures +@c +@c @deffn {procedure+} get-handle index +@c Return a magic number that cannot be found any other way. +@c Subject to change, the current behaviour is: +@c +@c @table @code +@c @item 0 +@c The handle of the instance, @code{hInstance}, of the Scheme application +@c @item 1 +@c The handle of the master tty window +@c @item 3 +@c The address of the C function that invokes a Scheme wndproc. +@c @end table +@c @end deffn +@c +@c @deffn {procedure+} create-scheme-window ex-style class name style x y w h parent menu inst param proc +@c Creates a window by calling @code{CreateWindowEx} with all the +@c parameters except @var{proc}. +@c +@c @table @var +@c @item ex-style +@c Integer. +@c @item class +@c String. Must name a window class created with a @code{lpfnWndProc} +@c entry that has the value of @code{(get-handle 3)}. +@c @item name +@c String. Title of window. +@c @item style +@c Integer. +@c @item x y +@c Integer. Window position. +@c @item w h +@c Integer. Window size. +@c @item parent +@c Integer. Handle of parent window. +@c @item menu +@c Integer or string. Number or name of menu resource for this window's +@c menu. +@c 0 means no menu. +@c @item inst +@c Integer, should be the result of @code{(get-handle 0)}. +@c @item param +@c Integer. +@c @item proc +@c @var{Proc} is a Scheme procedure with four parameters, i.e. of the form +@c +@c @example +@c (lambda (@var{hwnd} @var{msg} @var{wparam} @var{lparam}) +@c ...) +@c @end example +@c This procedure is the Scheme analogue of the C function that would +@c normally have been installed as the @code{lpfnWndProc} of the window +@c class. +@c @end table +@c @end deffn +@c +@c @deffn {procedure+} subclass-window! hwnd subclass-behaviour +@c Replace @var{hwnd}'s wndproc with a wndproc formed by calling +@c @var{subclass-behaviour} on the original wndproc. +@c @end deffn +@c +@c @deffn {procedure+} register-class style wndproc clsExtra wndExtra hInstance hIcon hCursor hBackground menu-name class-name +@c A way to call @code{RegisterClass} without first constructing a C +@c @code{WNDCLASS} object. +@c @end deffn +@c +@c @deffn {procedure+} default-scheme-wndproc +@c The Scheme equivalent of the C @code{DefWindowProc}. +@c @end deffn +@c +@c @node Scheme WndProcs, , Procedures, Writing windows procedures +@c @subsection Scheme WndProcs +@c +@c +@c A Scheme wndproc is of the form +@c +@c @cindex wndproc +@c @example +@c (lambda (hwnd msg wparam lparam) +@c (cond ((= msg WM_CREATE) +@c ...) +@c (... +@c ...) +@c (else +@c (default-scheme-wndproc hwnd msg wparam lparam)))) +@c @end example +@c +@c @cindex wndproc, higher-order +@c Scheme has the advantage over C that first class procedures can be used +@c to organize the data used by the window. +@c A useful idiom idiom is to parameterize the code with the default +@c behaviour. +@c This example behaves like @var{default-wndproc}, except that it +@c beeps every time the left mouse button is pressed. +@c +@c @example +@c (define ((my-wndproc default-wndproc) hwnd msg wparam lparam) +@c (define (default) (default-wndproc hwnd msg wparam lparam)) +@c (cond ((= msg WM_LBUTTONDOWN) +@c (message-beep MB_OK) +@c (default)) +@c (else +@c (default)))) +@c @end example +@c +@c @noindent +@c @code{my-wndproc} is suitable for use with @code{subclass-window!} +@c For example, +@c +@c @example +@c (subclass-window! (get-handle 1) my-wndproc) +@c @end example +@c Will cause the main Scheme window to beep every time the left mouse +@c button is pressed, but otherwise work normally. +@c +@c In a similar fashion, Scheme wndprocs can be closed over state +@c describing the object that the window displays or edits. +@c An idiom for a complex kind of window is to have a record (structure) +@c representing the object, and to create the window procedure with that +@c object in scope. +@c The following extended example is a framework for an editor. +@c The @code{whizz-editor} record's @code{hwnd} field is set at window +@c creation time so that we can get the window handle from the record. The +@c utility of this is demonstrated in @code{whizz-editor/set-title}. +@c +@c @example +@c (define-structure whizz-editor +@c hwnd +@c magic-flag? +@c @var{other stuff}) +@c +@c +@c (define (make-whizz-editor-wndproc data) +@c ;; @r{The following string is created once before the window comes} +@c ;; @r{into existence} +@c (define window-local-string (make-string 100)) +@c +@c ;; @r{The normal wndproc} +@c (define ((wndproc default-wndproc) hwnd msg wparam lparam) +@c (define (default) (default-wndproc hwnd msg wparam lparam)) +@c (cond ((= msg WM_CREATE) +@c (set-whizz-editor-hwnd! data hwnd) +@c ... +@c (default)) +@c (... +@c ... (if (whizz-editor-magic-flag? data) ... ...) +@c ...) +@c (else +@c (default)))) +@c +@c wndproc) +@c +@c +@c (define (create-whizz-editor) +@c (let* ((data (make-whizz-editor 0 ...)) +@c (wndproc (make-whizz-editor-wndproc data)) +@c +@c (create-scheme-window +@c 0 "WHIZZ_EDITOR_CLASS" "Whizz Editor" +@c (+ WS_VISIBLE WS_OVERLAPPED) +@c CW_USEDEFAULT CW_USEDEFAULT CW_USEDEFAULT CW_USEDEFAULT +@c 0 0 (get-handle 0) 0 +@c (wndproc default-scheme-wndproc))) +@c data)) +@c +@c (define (whizz-editor/set-title wh title) +@c (set-window-text (whizz-editor-hwnd wh) title)) +@c @end example +@c +@c @noindent +@c Now we are ready to create a Whizz Editor and set its title: +@c +@c @example +@c (define my-editor (create-whizz-editor)) +@c (whizz-editor/set-title my-editor "A new title") +@c @end example +@c +@c @node Procedure Index, Concept Index, , Top +@c @unnumbered Index of Procedures, Special Forms, and Variables +@c @printindex fn +@c +@c @node Concept Index, , Procedure Index, Top +@c @unnumbered Index of Concepts +@c @printindex cp +@c +@c @node Procedure Index, , Writing windows procedures, Top +@c @unnumbered Index +@c @printindex fn +@c +@c @c @summarycontents +@c +@c @contents +@c +@c @c Local Variables: +@c @c eval: (auto-save-mode -1) +@c @c End: +@c +@c @bye + +@c WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + +@node Variable Index, Key Index, Win32 Package Reference, Top @unnumbered Variable, Declaration, and Option Index @printindex fn