Windle is a clone of the popular word game, built for Windows 3.1. Experience the joy of finding the right word in Windows 3.1's 3D bevelled style!
The program was developed in Delphi 1 on a Gateway 4DX2-66 running Windows 3.11 for Workgroups. It takes UI design cues from contemporary games such as Solitaire and the games that were part of the Microsoft Entertainment Pack (Chip's Challenge, Pipe Dream, etc).
If you want to read about my experience coding Windle in Delphi 1, read on. Otherwise, you can skip to the download section below.
It's been a while since I last developed in Delphi, and having coded in more modern programming environments in the decades since, there were several things that were fun to reminisce.
CPU speed - One thing that shouldn't have been a surprise, but something that I'd almost forgotten, was the fact that a 66MHz CPU is slow. I was initially relying on reading the entire dictionary into memory on startup, but had to quickly replace that with a binary search through the file on disk since it took multiple seconds to load Windle while the UI hung. You can't just throw everything in memory and call it a day.
UI design - One of Delphi's strengths is its form (UI) designer. It features a robust set of standard Windows components, which you can visually manipulate on the screen to form your application's UI. It's missing some things that you'd take for granted in a UI editor or design tool today, like being able to nudge things over by a pixel, or showing guides when aligning things. But overall, it's great!
Spaces rule, tabs drool - Forget code completion (that would come in '97 in Delphi 3)— things that seem basic today like an automatically indenting Tab key don't exist. Pressing Tab, which you might expect to indent you the right amount for the context you're in, instead takes you one character past the last character of the previous line. For instance, here you can see I've mistakenly indented the "var" declarations by 3 spaces, and the procedure body after "begin" by 5 spaces, because "var" is 3 characters and "begin" is 5. It turns out that the standard Delphi style is to indent everything manually by 2 spaces!
Confusing compiler errors - Delphi 1's compiler error messages aren't its strong suit. The compiler error in the screenshot, for instance, appears because variable C is of the wrong type. Instead, "Field identifier expected" sounds like there's a syntax error somewhere. I did notice that Delphi 2's error messages were greatly improved—but for 16-bit development, you're stuck with Delphi 1.
Usefulness of the help file - A distinctly pleasant part of the experience was the built-in Help (.hlp) file. Back in the day, when Stack Overflow didn't exist and the Internet barely did, the Help file (and the thick stack of manuals that accompanied Delphi) were your main ways to learn how the built-in libraries and the Windows API worked. I found the built-in search and documentation quite usable. I still found myself Googling for the cure to obscure compiler errors and Windows API intricacies, which was hampered by the fact that there have been more than a dozen Delphi versions and almost as many versions of Windows since Delphi 1 and Windows 3.1 were on store shelves.
Speaking of Stack Overflow... - One of the snippets of code I did end up borrowing from the Internet turned out to
have a subtle bug in it that cost me a couple hours of
exasperation debugging. You see, Delphi has two string types—a
native string, and a PChar, or a pointer to a null-terminated array of characters (like in C). UI components use the native
string type, but the Windows API functions, naturally, require a PChar for their string parameters.
Long story short, a snippet of code I'd lifted from the Internet to convert a native string to a PChar allocated one fewer byte than required (a PChar requires space for its trailing null), and caused my code to behave in odd ways, like corrupting the text in dialog boxes and crashing in completely unrelated areas of the code. Let's just say I spent a lot of time questioning my ability to do a binary search.
Did you say crashes? - During my debugging, because I was randomly overwriting memory (including, presumably, memory not belonging to Windle thanks to the lack of protected memory), Windle would crash often. Sometimes it would crash in a way that Windows could catch and recover from. But more often than I wanted, I'd cause Windows itself to crash and dump me on a blue screen of death, from which I'd have to pull the power on the computer and reboot.
Splendidness of the Delphi setup screen - Finally, one of my favorite memories of Delphi 1 from when I first used it back in the day was the Setup process. It's an InstallShield-style installer like much Windows software from back in the day, but with a twist—you're in a Borland car on the Delphi highway and your speedometer is the percent complete. It's a fun twist I definitely appreciated, since it takes an eternity and a half going through all 15 diskettes.
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License. No warranties are given for this software; please read the license before use.
While the 16-bit build of Windle for Windows 3.1 will not work on 64-bit versions of Windows, a 32-bit build is also available. That should work on newer Windows versions, but won't look as classic as it does on Windows 3.1.
The only differences between the two versions are that the 32-bit version has been compiled with Delphi 2 on Windows 98 SE, and a reference to the shell.dll function ShellAbout—to display the standard Windows About dialog—has been replaced with one to the shell32.dll function ShellAboutA.