8 Platforms and Testing
dxtr edited this page 2026-10-17 04:57:32 +02:00

Platforms and Testing

SBCL

cl-win32 runs on SBCL, and the suite passes on SBCL 2.6.9 for Windows. It has no implementation-specific code: everything goes through cl-ffi.

Windows versions

cl-win32 needs Windows 10 version 1607 or later, on x86-64. 1607 added SetThreadDpiAwarenessContext, GetDpiForWindow and AdjustWindowRectExForDpi, which the DPI functions use.

The system loads only on Windows: user32.dll, kernel32.dll and imm32.dll are its foreign libraries. Code that also runs elsewhere should depend on it behind a feature, as cl-windowing does:

(:feature (:or :win32 :windows) "cl-win32")

SBCL has :win32 on its features on Windows.

Running the tests

The tests use Parachute, and the dependencies are pinned in the stiftfile with stift. From the repository:

stift test

test-system signals an error if any test fails. From a REPL:

(asdf:load-system :cl-win32/test)
(parachute:test :cl-win32/test)

The tests create windows without showing them, so they need a desktop session but put nothing on the screen. Each registers its window class under a fresh name, so a run cut short leaves nothing behind that the next one trips over. Two kinds of test touch the session itself:

  • The clipboard tests need the session unlocked: while it is locked, Windows gives no program the clipboard.
  • The test of clip-cursor moves the real pointer into the rectangle it clips to, and puts it back with cursor-position and set-cursor-position afterwards. Leave the pointer alone while it runs.

CI does not run the suite yet: it needs a Windows runner.

Writing tests for code that uses cl-win32

A window procedure is also a plain Lisp function of the same name, so its logic can be tested by calling it with a message, without Windows:

(is = 0 (my-procedure 0 win32:+wm-char+ (char-code #\a) 0))

To test it as Windows calls it, make a hidden window of its class and send it messages. send-message returns once the procedure has handled the message, and an error in the procedure comes back from it:

(let ((window (win32:create-window "my-app")))
  (unwind-protect
       (progn
         (win32:send-message window win32:+wm-keydown+ (win32:virtual-key-code :escape)
                             (win32:make-lparam 1 1))   ; repeat count 1, scancode 1
         (true (closed-p)))
    (when (win32:window-p window)
      (win32:destroy-window window))))

Posted messages need a message loop: post them, then process-messages.