An open API service indexing awesome lists of open source software.

https://github.com/fjames86/ftw

Common Lisp Win32 GUI library
https://github.com/fjames86/ftw

common-lisp gui lisp win32

Last synced: 3 months ago
JSON representation

Common Lisp Win32 GUI library

Awesome Lists containing this project

README

          

# FTW - Common Lisp For the Win(32)

# 1. Introduction
This library provides a very thin interface to the underlying
APIs for writing native Windows GUIs in Common Lisp.

The intention is to be able to write the same sort of codes in Lisp as you
would if writing normal Win32 GUIs in C. This also opens the possibility
for writing other more general graphical applications like games.

# 2. Functions
All underlying Win32 functions have Lisp equivalents, mostly with CamelCase replaced with the Lisp style kebab-case.

Because this is a very thin wrapper over the top of the underlying Win32 API,
it is assumed the user is at least familiar with the equivalent C programming.
Documentation for each of the functions can be found on MSDN or any of
the other C language resource.

## 2.1 Limitations
Several functions accept IDs for so called "resources", which normally get linked
in with the object code by the resource compiler (when writing in C). For
obviously reasons this is not possible when using Lisp.

## 2.2 Other platforms
This is a Windows only library and does not work on any other platform.
It is not a cross platform GUI library.

# 3. Extra utilities
Several extra functions and macros are provided which the author has found useful.
These are found in ftw.lisp.

## 3.1 Constants
To use the Win32 API you need access to a vast number of predefined constants.
These are defined in constants.lisp. Rather than export each of these symbols from
the FTW package the programmer has two options: either access directly
or use the macros `const` or `logior-consts`:
```
;; directly
ftw::+fred+
(logior ftw::+fred+ ftw::+jim+)
;; sugar coating macro
(ftw:const +fred+)
(ftw:logior-consts +fred+ +jim+)
```

The macro `CONST` takes a string designator and converts to the symbol with that name in the `FTW` package.
In many places you need to pass a bitmask of logical-OR of several flags, use `LOGIOR-CONSTS` for this
which performs the same transformation.

Note that there are possibly many constants which have not been defined in constants.lisp. These should be added over time as they become useful.

## 3.2 Resources
When writing Win32 programs in the C programming language it is common to embed binary resources such
as icons, cursors and bitmaps using the resource compiler. These can then be referenced by an integer
ID from various Win32 calls. This is not possible when calling these functions at from Lisp because
we have to do everthing at runtime. Where possible I have included the functions for generating
these at runtime either by loading from files or from raw binary data.

To make it easier I have also included several functions for pregenerating Lisp code for icons, cursors and
bitmaps. This has the equivalent semantics as the normal Win32 resource compiler but we're still doing
all the work at runtime.

The advantage of pregenerating code and putting that into your project is you don't need to ship
external images which need to be loaded at runtime - you need only compile your code.

To e.g. embed an icon into your project do the following:
1. Get your icon file e.g. by drawing it in gimp. make sure it is 32x32 pixels and exported as 32-bit
with 8 bits each of alpha and rgb.
2. Run `(ftw:generate-icon-resource "myicon.ico")`
This will print out the code you need to paste into your project.

See the minesweeper example of how you can have a custom icon without shipping the file separately.

## 3.3 Dialogs
The standard mechanism for drawing modal and modeless dialogs with Win32 is to use the
resource compiler to generate the specification. This is not possible for us so we must do it at runtime.

The functions `DIALOG-BOX` and `CREATE-DIALOG` create modal and modeless dialogs respectively. Both accept
the same inputs. The difference is that modal dialogs do not return control to the caller until
the dialog has been closed whereas modeless dialogs return control immediately and run alongside the original
window.

## 3.4 Hwnd registry
You may associate a window handle (hwnd) with a symbol name and optionally integer ID using `REGISTER-HWND`.
Perform lookups by name or ID using `HWND-BY-NAME` and `HWND-BY-ID`:
```
;; register an hwnd with the name FRED and ID 1
(register-hwnd 'fred hwnd 1)
;; lookup hwnd with name FRED
(hwnd-by-name 'fred)
;; lookup hwnd with ID 1
(hwnd-by-id 1)
;; Lookup the name of the hwnd with ID 1
(hwnd-name-by-id 1)
```

This makes it very simple to keep references to window handles in a consistent
way rather than implementing private lists or globals in each program.

# 4. Examples
Various examples are provided which show various levels of abstractions and a
good showcase of how to use it.

## 4.1 Zetcode samples
The rather comprehensive tutorial for the C programming language can be
found here [zetcode website](http://zetcode.com/gui/winapi/).
These have been translated to Lisp and show that the same GUIs can be written
which correspond to largely the same structure.

## 4.2 Climage
This example GUI displays a two list boxes which show the packages and
exported symbols. Clicking on a symbol displays the documentation for it.

In addition, this GUI shows how to write and handle modal dialogs
and accelerator keys -- these are the keyboard combinations which
are used as shortcuts for menu items.
Ctrl+F brings up a Find dialog to search for a given symbol. Ctrl+Q quits.

## 4.3 Dragdrop
This shows how to support drag and drop functionality by handling the `WM_DROPFILES` message.

## 4.4 Pong
This is a small and not very well written example of how you might go about
writing games. It's just a silly little pong game but shows the basic idea.

## 4.5 Icon
Shows how to add icons and other graphics.

## 4.6 Minesweeper
Simple minesweeper game.

## 4.7 Tetris
Simple tetris clone.

## 4.8 Macroman
Simple pacman clone. Shows how to reduce flicker by double buffering.

## 4.9 Scrollbar
How to add scrollbars and response to scoll messages.

## 4.10 Dragons: DNS client
This implements a simple DNS client using the DNS client [dragons](http://github.com/fjames86/dragons). Enter the DNS address in the IP address field, select the
record type and entry name and click Query. The list box below is filled with
the results returned from the server, or a message box indicates an error status.

## 4.11 RPC: MsgWaitForMultipleObjects example
This shows how to interleave networking and the message pump in the main thread,
thereby making it possible to do asynchronous processing without blocking the
gui. The example broadcasts to the rpcbind null procedure and fills in results
as they are received. Requires [frpc2](http://github.com/fjames86/frpc2).
This means the gui never blocks, the same technique can be applied to do any networking,
e.g. background refreshes of data. The examples uses RPC over UDP but there is no reason
why you couldn't also do non-blocking TCP networking as well.

# 5. Notes
Requires CFFI. Developed on Windows 8.1 and Windows 7 using SBCL
but should work on basically any Windows version because all the APIs are
pretty stable and haven't changed for a long time.
Should work with any Lisp implementation which provides FFI callbacks

## 5.1 TODO
- [ ] Try with CCL, Lispworks etc.
- [ ] Better error handling.

Licensed under the terms of the MIT license.

Frank James
October 2016.