{"id":33236859,"url":"https://github.com/fjames86/ftw","last_synced_at":"2026-01-21T04:38:31.139Z","repository":{"id":68933971,"uuid":"73630462","full_name":"fjames86/ftw","owner":"fjames86","description":"Common Lisp Win32 GUI library ","archived":false,"fork":false,"pushed_at":"2024-08-02T22:33:38.000Z","size":312,"stargazers_count":62,"open_issues_count":2,"forks_count":10,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-12-06T19:44:38.301Z","etag":null,"topics":["common-lisp","gui","lisp","win32"],"latest_commit_sha":null,"homepage":null,"language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fjames86.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2016-11-13T17:10:58.000Z","updated_at":"2024-12-03T19:47:50.000Z","dependencies_parsed_at":"2024-01-27T08:41:47.310Z","dependency_job_id":"2f7c091c-bac0-441e-ac39-86b253d307b2","html_url":"https://github.com/fjames86/ftw","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fjames86/ftw","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fjames86%2Fftw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fjames86%2Fftw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fjames86%2Fftw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fjames86%2Fftw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fjames86","download_url":"https://codeload.github.com/fjames86/ftw/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fjames86%2Fftw/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28626552,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T02:47:06.670Z","status":"ssl_error","status_checked_at":"2026-01-21T02:45:44.886Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["common-lisp","gui","lisp","win32"],"created_at":"2025-11-16T19:00:28.309Z","updated_at":"2026-01-21T04:38:29.639Z","avatar_url":"https://github.com/fjames86.png","language":"Common Lisp","readme":"\r\n# FTW - Common Lisp For the Win(32) \r\n\r\n# 1. Introduction \r\nThis library provides a very thin interface to the underlying\r\nAPIs for writing native Windows GUIs in Common Lisp.\r\n\r\nThe intention is to be able to write the same sort of codes in Lisp as you\r\nwould if writing normal Win32 GUIs in C. This also opens the possibility\r\nfor writing other more general graphical applications like games.\r\n\r\n# 2. Functions\r\nAll underlying Win32 functions have Lisp equivalents, mostly with CamelCase replaced with the Lisp style kebab-case.\r\n\r\nBecause this is a very thin wrapper over the top of the underlying Win32 API,\r\nit is assumed the user is at least familiar with the equivalent C programming.\r\nDocumentation for each of the functions can be found on MSDN or any of\r\nthe other C language resource.\r\n\r\n## 2.1 Limitations\r\nSeveral functions accept IDs for so called \"resources\", which normally get linked\r\nin with the object code by the resource compiler (when writing in C). For\r\nobviously reasons this is not possible when using Lisp. \r\n\r\n## 2.2 Other platforms\r\nThis is a Windows only library and does not work on any other platform.\r\nIt is not a cross platform GUI library.\r\n\r\n\r\n# 3. Extra utilities\r\nSeveral extra functions and macros are provided which the author has found useful.\r\nThese are found in ftw.lisp.\r\n\r\n## 3.1 Constants \r\nTo use the Win32 API you need access to a vast number of predefined constants. \r\nThese are defined in constants.lisp. Rather than export each of these symbols from \r\nthe FTW package the programmer has two options: either access directly \r\nor use the macros `const` or `logior-consts`:\r\n```\r\n;; directly \r\nftw::+fred+\r\n(logior ftw::+fred+ ftw::+jim+)\r\n;; sugar coating macro \r\n(ftw:const +fred+)\r\n(ftw:logior-consts +fred+ +jim+)\r\n```\r\n\r\nThe macro `CONST` takes a string designator and converts to the symbol with that name in the `FTW` package. \r\nIn many places you need to pass a bitmask of logical-OR of several flags, use `LOGIOR-CONSTS` for this\r\nwhich performs the same transformation. \r\n\r\nNote that there are possibly many constants which have not been defined in constants.lisp. These should be added over time as they become useful.\r\n\r\n## 3.2 Resources \r\nWhen writing Win32 programs in the C programming language it is common to embed binary resources such \r\nas icons, cursors and bitmaps using the resource compiler. These can then be referenced by an integer \r\nID from various Win32 calls. This is not possible when calling these functions at from Lisp because \r\nwe have to do everthing at runtime. Where possible I have included the functions for generating \r\nthese at runtime either by loading from files or from raw binary data. \r\n\r\nTo make it easier I have also included several functions for pregenerating Lisp code for icons, cursors and \r\nbitmaps. This has the equivalent semantics as the normal Win32 resource compiler but we're still doing \r\nall the work at runtime. \r\n\r\nThe advantage of pregenerating code and putting that into your project is you don't need to ship \r\nexternal images which need to be loaded at runtime - you need only compile your code. \r\n\r\nTo e.g. embed an icon into your project do the following: \r\n 1. Get your icon file e.g. by drawing it in gimp. make sure it is 32x32 pixels and exported as 32-bit\r\nwith 8 bits each of alpha and rgb. \r\n 2. Run `(ftw:generate-icon-resource \"myicon.ico\")`\r\nThis will print out the code you need to paste into your project. \r\n\r\nSee the minesweeper example of how you can have a custom icon without shipping the file separately. \r\n\r\n## 3.3 Dialogs\r\nThe standard mechanism for drawing modal and modeless dialogs with Win32 is to use the \r\nresource compiler to generate the specification. This is not possible for us so we must do it at runtime.\r\n\r\nThe functions `DIALOG-BOX` and `CREATE-DIALOG` create modal and modeless dialogs respectively. Both accept \r\nthe same inputs. The difference is that modal dialogs do not return control to the caller until \r\nthe dialog has been closed whereas modeless dialogs return control immediately and run alongside the original\r\nwindow. \r\n\r\n## 3.4 Hwnd registry\r\nYou may associate a window handle (hwnd) with a symbol name and optionally integer ID using `REGISTER-HWND`.\r\nPerform lookups by name or ID using `HWND-BY-NAME` and `HWND-BY-ID`:\r\n```\r\n;; register an hwnd with the name FRED and ID 1\r\n(register-hwnd 'fred hwnd 1) \r\n;; lookup hwnd with name FRED \r\n(hwnd-by-name 'fred) \r\n;; lookup hwnd with ID 1\r\n(hwnd-by-id 1)\r\n;; Lookup the name of the hwnd with ID 1 \r\n(hwnd-name-by-id 1)\r\n```\r\n\r\nThis makes it very simple to keep references to window handles in a consistent\r\nway rather than implementing private lists or globals in each program.\r\n\r\n# 4. Examples\r\nVarious examples are provided which show various levels of abstractions and a\r\ngood showcase of how to use it.\r\n\r\n## 4.1 Zetcode samples\r\nThe rather comprehensive tutorial for the C programming language can be\r\nfound here [zetcode website](http://zetcode.com/gui/winapi/).\r\nThese have been translated to Lisp and show that the same GUIs can be written\r\nwhich correspond to largely the same structure.\r\n\r\n## 4.2 Climage\r\nThis example GUI displays a two list boxes which show the packages and\r\nexported symbols. Clicking on a symbol displays the documentation for it.\r\n\r\nIn addition, this GUI shows how to write and handle modal dialogs\r\nand accelerator keys -- these are the keyboard combinations which\r\nare used as shortcuts for menu items.\r\nCtrl+F brings up a Find dialog to search for a given symbol. Ctrl+Q quits.\r\n\r\n## 4.3 Dragdrop\r\nThis shows how to support drag and drop functionality by handling the `WM_DROPFILES` message.\r\n\r\n## 4.4 Pong\r\nThis is a small and not very well written example of how you might go about\r\nwriting games. It's just a silly little pong game but shows the basic idea.\r\n\r\n## 4.5 Icon\r\nShows how to add icons and other graphics.\r\n\r\n## 4.6 Minesweeper\r\nSimple minesweeper game.\r\n\r\n## 4.7 Tetris\r\nSimple tetris clone.\r\n\r\n## 4.8 Macroman\r\nSimple pacman clone. Shows how to reduce flicker by double buffering. \r\n\r\n## 4.9 Scrollbar \r\nHow to add scrollbars and response to scoll messages. \r\n\r\n## 4.10 Dragons: DNS client\r\nThis 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\r\nrecord type and entry name and click Query. The list box below is filled with\r\nthe results returned from the server, or a message box indicates an error status.\r\n\r\n## 4.11 RPC: MsgWaitForMultipleObjects example\r\nThis shows how to interleave networking and the message pump in the main thread,\r\nthereby making it possible to do asynchronous processing without blocking the\r\ngui. The example broadcasts to the rpcbind null procedure and fills in results\r\nas they are received. Requires [frpc2](http://github.com/fjames86/frpc2).\r\nThis means the gui never blocks, the same technique can be applied to do any networking,\r\ne.g. background refreshes of data. The examples uses RPC over UDP but there is no reason\r\nwhy you couldn't also do non-blocking TCP networking as well. \r\n\r\n# 5. Notes\r\nRequires CFFI. Developed on Windows 8.1 and Windows 7 using SBCL \r\nbut should work on basically any Windows version because all the APIs are \r\npretty stable and haven't changed for a long time. \r\nShould work with any Lisp implementation which provides FFI callbacks\r\n\r\n## 5.1 TODO\r\n - [ ] Try with CCL, Lispworks etc.\r\n - [ ] Better error handling.\r\n\r\n\r\nLicensed under the terms of the MIT license.\r\n\r\nFrank James\r\nOctober 2016.\r\n\r\n\r\n\r\n\r\n\r\n","funding_links":[],"categories":["Miscellaneous ##"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffjames86%2Fftw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffjames86%2Fftw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffjames86%2Fftw/lists"}