Table of Contents
Lifetimes and Threads
Releasing
Windows does not free what a program made when the garbage collector drops the handle. Release each thing explicitly:
| Thing | Make | Release | Scoped |
|---|---|---|---|
| window class | register-window-class |
unregister-window-class |
|
| window | create-window |
destroy-window, on its thread |
|
| event object | make-event |
close-event |
with-event |
System cursors, from system-cursor, are shared by every program: never
release one.
Destroy a class's windows before unregistering it: unregistering a class
that still has windows signals a win32-error (1412). Destroying a
window destroys the windows it is the parent of. When a thread ends, its
windows are destroyed with it.
Handles are plain integers. A handle released is not marked in any way,
and Windows may reuse the number. window-p tells whether a window handle
names a window now.
Threads
| What | Rule |
|---|---|
| a window | belongs to the thread that created it: only that thread takes its messages and may destroy it; any thread may move, size, title, show, post to and send to it |
| a window class | belongs to the program: windows of it may be created on any thread |
| an event object | may be used from any thread |
| DPI awareness | belongs to a thread, for the windows it creates afterwards |
| a message loop | runs on one thread, for that thread's windows |
| key state | belongs to a thread: key-state answers for the message the calling thread is handling |
| a window's input method | used from the window's thread only |
| the cursor | set-cursor from the thread of the window the pointer is over |
| the pointer's position and clip | the desktop's: any thread, but a program holds the pointer only while it has the focus |
| raw mouse input | one window of the program receives it, the last registered |
| the clipboard | the desktop's: one program at a time has it open, which clipboard-text waits for |
When another thread moves, sizes or titles a window, Windows sends the
messages that causes to the window's thread and waits for it. So the
window's thread must be taking messages, and must not be waiting for the
calling thread, or neither goes on. The same holds for send-message.
See Recipes for a thread that runs windows on behalf of the
others.
Allocation
These allocate nothing, so they can run every frame:
run-message-loopandprocess-messages, per message, and the call of a procedure defined withdefine-window-procedure, up to its body;post-message,set-event,wait-for-event;virtual-key-name,virtual-key-code,key-state,map-virtual-keyand the word functions;system-cursor, which a window procedure may call for each+wm-setcursor+;raw-mouse-motion.
peek-message and send-message allocate a little per call, 32 bytes,
to catch errors in window procedures. Functions that take strings, such as
create-window and (setf window-text), copy them to UTF-16 for Windows,
and those that return strings, such as window-text, return fresh ones.