No results
6
Getting Started
dxtr edited this page 2026-10-17 04:57:32 +02:00
Table of Contents
Getting Started
Requirements
- Windows 10 version 1607 or later, on x86-64. Per-monitor DPI awareness,
set-thread-dpi-awareness, needs 1607. - SBCL. See Platforms and Testing.
- cl-ffi, which is not in Quicklisp:
with stift, cl-win32's
stiftfilebrings it in; without, clone it where ASDF finds it.
user32.dll and kernel32.dll are part of Windows; there is nothing else to install.
Loading
cl-win32 is not in Quicklisp. Clone it where ASDF can find it, for example
under %USERPROFILE%\common-lisp\, and load it:
(asdf:load-system :cl-win32)
The package is cl-win32. Its symbols are short and general, such as
create-window and key-state, so use a local nickname rather than
:use:
(defpackage #:my-app
(:use #:cl)
(:local-nicknames (#:win32 #:cl-win32)))
All the examples in this wiki use the nickname win32.
A first window
(in-package #:my-app)
(win32:define-window-procedure my-procedure (window message wparam lparam)
(declare (ignore lparam))
(cond ((= message win32:+wm-size+)
(format t "~&Resized: ~:[restored~;minimised~]~%"
(= wparam win32:+size-minimized+))
0)
((= message win32:+wm-close+)
(win32:destroy-window window)
0)
((= message win32:+wm-destroy+)
(win32:post-quit-message 0)
0)
(t nil)))
(win32:set-thread-dpi-awareness :per-monitor-aware-v2)
(win32:register-window-class "my-app" 'my-procedure)
(unwind-protect
(let ((window (win32:create-window "my-app" :title "My app")))
(multiple-value-bind (width height)
(win32:window-size-for-client-size 640 400 :dpi (win32:window-dpi window))
(win32:set-window-bounds window :width width :height height))
(win32:show-window window)
(win32:run-message-loop))
(win32:unregister-window-class "my-app"))
Close the window and run-message-loop returns 0.
What each step does:
define-window-proceduredefines the window procedure: the function Windows calls with every message for a window, such as+wm-size+or+wm-close+. It returns the message's result, an integer, ornilto leave the message to Windows' default handling.set-thread-dpi-awarenesshas Windows report sizes in pixels for the windows this thread creates, rather than scaling them up blurred. See DPI.register-window-classregisters a window class: a name tied to the window procedure.create-windowmakes a window of the class. It is hidden untilshow-window. Its size is the whole window, title bar and borders included, sowindow-size-for-client-sizeworks out the size that gives the inside, the client area, 640 by 400 pixels.run-message-loophands the thread's messages to their window procedures untilpost-quit-message, and returns its code. Closing the window sends+wm-close+; the procedure destroys the window, which sends+wm-destroy+, which ends the loop.