The About Box
When I was asked to deliver a half-hour “mini keynote” at November 2005 DevConnections, it was suggested that I could speak about either Visual Studio or the history of Windows. I was already preparing a talk about Visual Studio for the NYC .NET Developer’s Group, so I thought it would be best neither to elaborate nor contradict that particular presentation.
Although nobody else seemed to have notice, November 2005 marks the 20th anniversary of the official introduction of Windows 1.0 at Fall Comdex in Las Vegas. (The version number of that first release was actually 1.01; the files are dated November 15, 1985.) It seemed suitable to celebrate that anniversary. I could have done a straight narrative history, but I thought it might be more fun to pretend as if it were actually 1985, and that I was trying to “sell” Windows as an application platform to a group of programmers.
Of course I would want to actually run Windows 1.0 and demonstrate its features in front of the audience, and because I would be addressing programmers, I thought it necessary to compile and a Windows application as well. The talk instantly shifted into an exercise in retro-computing.
The last time I had tried to run Windows 1.01 was probably about 15 years ago. As I vaguely recall, Windows 1.01 generated an exception interrupt on whatever machine I was using, and I didn't really pursue the issue.
However, I knew it was possible to run Windows 1.01 under Virtual PC, the Microsoft product that creates virtual environments for applications and even entire operating systems. Virtual PC works mostly in conjunction with virtual hard disks, which are actually just files that can be created and manipulated with programs like WinImage
I knew that it was possible to run Windows 1.01 under Virtual PC because I had seen this blog entry by Virtual PC Guy. Using Virtual PC certainly wasn't an optimum solution, but seemed much saner than trying to recreate an actual vintage 1985-era PC-AT. I figured that I could also easily install the Windows 1.0 Software Development Kit along with Windows. With the SDK installed, I could actually show the audience source code for a small Windows application, compile it on the command line, and then run it under Windows 1.01.
Windows 1.01 shipped with several display drivers — for the IBM Color Graphics Adapter, for the Hercules monochrome board, and for the IBM Enhanced Graphics Adapter (EGA), which provided 640 by 350 pixels with 16 colors.
Under Virtual PC, Windows 1.01 thinks it’s running on an EGA, and Virtual PC does not compensate for the non-square EGA pixels. In Virtual PC full-screen mode, Windows is flattened out and occupies only about the middle ¾ of the display. In this aspect ratio, Windows looks rather like the wide-screen letterbox edition. I didn’t know whether the video projectors at the conference could compensate for that, but I preceded on the assumption that they could not. (I decided not to include the CLOCK program as part of my demonstration because it would display as an ellipse and just call attention to the problem.)
Windows 1.01 had several other peculiarities when running under Virtual PC. It wouldn’t recognize the mouse, for example. (At some point I’d like to try a serial mouse, but I’d need both a serial mouse and a machine with a serial port.) I realized I’d have to do the entire Windows demonstration from the keyboard. Since the mouse wasn’t common in 1985, Windows 1.01 had a comprehensive keyboard interface that continues to this day. You used Alt and a letter to invoke the application menu, and Alt-Spacebar to invoke the system menu. You could then use the cursor keys to navigate the menu.
But that revealed the second big problem with running Windows 1.01 under Virtual PC. It doesn’t recognize the separate cursor keys. On a regular desktop keyboard, the cursor keys in the number pad are available, but on a laptop — I would be running the presentation on a Toshiba Tablet PC — the number pad is embedded in the alphanumeric keyboard. I needed to use the Fn key in conjunction with the U, 8, O, and K keys for left, right, up, and down, respectively. I put little pieces of masking tape on these keys to make them stand out.
Although I needed to use Alt-Spacebar to invoke the system menu, Alt with letter keys to select menu items, and Fn with letter and number keys to control the cursor, it was very, very important that I not press Fn-Spacebar. That key combination changes the video resolution of the Toshiba Tablet PC. The best case was that the screen would go blank for two seconds. The worst case was that the screen would return in a “scrambled” state.
The other major problem running Windows 1.01 under Virtual PC was that it would crash under certain circumstances. One of these involved the File Open menu in Notepad. That was easily avoidable.
But Windows 1.01 running under Virtual PC would also crash when Windows was exited! I would have preferred a presentation where I showed some slides, then demoed Windows, exited Windows back to the command line, showed a bit of development stuff, compiled a program on the command line, and then ran Windows again with that program. But to keep the presentation seamless, I needed to run Windows 1.01 at the very end of the presentation and not exit it.
After some consideration, I came upon the idea of writing a Windows 1.01 program that displays a graphical birthday cake. (Of course, the presence of a birthday cake conflicted with the idea that the presentation would “occur” in 1985, but I figured I could talk myself out of that little anomaly.) When I realized I’d be demonstrating how to compile the program on the command line by typing MAKE and the program name, the program couldn’t be named anything other than CAKE.
Of course, I hadn’t done any Windows 1.0 programming since I first started working with beta versions of Windows 2.0 while writing the first edition of Programming Windows in 1987. It all came back in a rush, however, and I wrote most of the program on October 28, 2005, adding the animated candles the next day. Working entirely in Virtual PC, I’d compile the successive versions of the program on the DOS command line, and run WIN CAKE to test it. Because Windows wouldn’t exit without crashing, I’d then need to reboot the Virtual PC session by typing Right Alt-Delete.
My text editor back in early Windows days was WordStar. To write the CAKE program, I used the EDIT program included with DOS 5.0. Although DOS 5.0 wasn’t released until 1991, this happened to be the version of DOS installed on the Virtual PC hard drive I was using. After several hours of working under DOS, the command MODE 80,43 popped into my head. I tried it, and I got a 43-line display to make editing easier.
The CAKE program is mostly Rectangle and Ellipse calls. The text is displayed in the Script font, which was one of the scalable vector fonts included with early versions of Windows. (And I really mean vector rather than outline. To give it some body, I made it bold, and then displayed it twice with a little offset.) The flickering candles were little bitmaps. Because the ICONEDIT program included in the SDK required a mouse, I couldn’t use it. The bitmaps were created algorithmically in code, displayed with BitBlt, and animated with the Windows timer. To display the source code during the presentation, I found a slightly updated version of a program called BROWSE that I wrote for PC Magazine sometime in the mid-1980s. Links to the source code are provided below. Of course, the “November 1985” dates at the top of some of the files are bogus and were inserted for purposes of the presentation.
I knew that running Windows and the CAKE program would be delayed until the end of the talk. The beginning of the talk required some slides. To keep the whole talk consistent and seamless, the slides would have to be displayed from a DOS program, and the video resolution of the slides needed to agree with the video resolution that Windows would be running in — namely, 640 by 350 with 16 colors.
Color under the EGA was a little strange: Although the EGA was capable of displaying only 16 colors at once, these 16 colors could be chosen from a palette of 64 colors. In RGB terms, these 64 colors were all combinations where Red, Green, and Blue took on values of 0x00, 0x55, 0xAA, or 0xFF. The video signal from the EGA board to the EGA display was digital (like most computer displays of that era) but with 4 levels of each primary.
I created the slides in Microsoft Word using text, scanned images, and images I found on the Internet, and then took screen captures and saved them in PNG format. I wrote a little Windows Forms 2.0 program in C# to read in these PNG files and convert them. For each image, this program calculated an optimum 16-color palette based on the 64 possible EGA colors, and converted the image to 640 by 350 with 4 bits per pixel. The images were saved in BMP format.
To display these slides under DOS, I then wrote a C program that sequentially read in each BMP files, set the EGA palette from the BMP color table, and displayed the image by writing directly to the EGA screen buffer. (Writing code that directly manipulated video memory was something I hadn’t done since the 1980s, I believe.) Of course, figuring out how to do this required consulting the EGA Technical Reference manual I had been prescient enough to save all these years.
With all the technical stuff finished, the talk practically wrote itself. To refresh my memory about those days, I read my “Windows Wars!” cover story in the February 26, 1986 issue of PC Magazine, and I looked over Steve Ballmer’s slides from his introductory talk at the Microsoft Windows Development Seminar that I attended on June 5-6, 1986 in New York City, and I tried to remember how Steve (successfully) sold Windows to the programming community.
As I was getting ready to leave for Las Vegas, I packed the two manuals that came with the Windows 1.0 Software Development Kit so I could hold them up during the talk. But I was trying to pack light, and these manuals were too heavy and bulky for a brief sight gag that nobody would believe anyway. I left them behind.
The first ten images shown below are the slides I used as they were seen by the audience. They are 640 by 350 pixels with 16 optimized EGA colors, squashed down from larger images. I apologize to Sigmund Freud, Alan Turing, and Steve Ballmer for making their faces seem wider than they actually are.
I want to thank Arin Goldberg, Shirley Brothers, Ben Armstrong, and Amy Stevenson for their help and support in giving me the opportunity to pull off this crazy thing.
I also want to thank Steve Ballmer for inspiration, and Paul Somerson for once asking me to write him an UNFREEZE utility.
Welcome to DevConnections ’85!
Just a little over four years ago, in August of 1981, IBM introduced its first Personal Computer, and with it, the Microsoft operating system we’ve come to know as DOS.
Most users seem pretty much satisfied with DOS as it’s evolved over the past four years, but nobody knows better than the programmers sitting in this room that DOS is already in a state of crisis. I am skeptical that DOS can even survive the remainder of the 1980’s, let alone the 1990’s.
DOS is in a state of crisis all because of three little letters: T, S, and R.
Who could have guessed that the little innocuous DOS Interrupt 27 hex, “Terminate and Stay Resident” would wreck such chaos on our personal computers and push DOS to its breaking point?
If you’re like most users, you have several TSRs running on your computer, each one occupying memory, each one monitoring every keystroke that comes through, each one ready to pounce up on the screen and take command, and each one in danger of crashing DOS.
As a programmer, you’re probably either a writer of TSRs hoping to get your code to work with other TSRs, or you’re writing an application that’s incompatible with some TSR, or you’re just fed up with TSRs in general and tired of giving DOS the three-finger salute.
One of the executive editors at PC Magazine has a 20-line AutoExec.bat file. He runs so many TSRs that his machine freezes up several times a day. Just the other day he asked me if I could write him yet another TSR called UNFREEZE so he could just press a function key to snap the machine out of its coma.
People, this is insane. Let me be blunt: TSRs are bad for users, they are bad for programmers, and they are bad for this industry. We need a solution, and we have an opportunity here. We can look at this TSR situation and read between the lines to discover the next step.
Or, as Sigmund Freud once asked: What do users want?
Users want multitasking. You laugh. They don’t know it but they do. They want to run multiple programs at the same time. They want popups. They want calculators and notepads at their fingertips. That’s what TSRs are all about, and that’s what users want.
Users also want memory management. No user will actually say that, but it’s obvious. All those TSRs sitting in memory, and real applications get stuck with the leftovers. Once you introduce multitasking, memory management becomes a must. Multitasking without memory management is like having a party in a closet. It may be lots of fun for a little while, but pretty soon, somebody’s bound to get a little claustrophobic.
Users want inter-process communication. It’s a mouthful but it’s a simple concept. Programs talking to each other. And I don’t mean just file conversions. You should be able to transfer a number out of the SideKick calculator and insert it into your WordStar document without bringing the whole system down.
Over the past year, several software vendors have developed possible solutions to the predicament in which we find ourselves. These are sometimes known as operating environments or windowing environments. These are very ambitious and very sophisticated applications that run on top of DOS to provide a cooperative framework in which to run other applications.
Quarterdeck has released a program called DESQview that takes your existing DOS applications and runs them in little windows on the screen. Here’s an ugly screen shot of DESQview running two copies of Lotus 1-2-3.
The next three environments can also run DOS applications, but their real purpose is to host entirely new applications written specifically for the environment. IBM has weighed in with an environment called TopView. Here’s the TopView Alarm Clock program and Calculator program running on the same screen in overlapping windows.
Both DesqView and TopView obviously run in character mode. Now I know a lot of you will disagree with me, but I think it’s time we take a look at what moving to a graphical environment has to offer us. If we were all really honest, I think that we’d admit that when Apple introduced the Macintosh computer last year, we felt a bit envious, didn’t we?
Digital Research may have lost out to Microsoft in developing an operating system for IBM’s personal computer, but they’d like to host the next generation of applications in the Graphics Environment Manager or GEM.
Gosh, that looks familiar. I hope they have a license from Apple to make it look like that.
Last but not least, we have Microsoft Windows. Now I know Windows has become an industry laughing stock. It was first announced two years ago in 1983, and it’s been vaporware ever since. What the hell have they been doing in Redmond?
Well, Windows is now ready for prime time, and I’ll be showing you Windows in action in a few minutes.
I know everybody wants to know which, if any, of these environments is going to “take off” and become successful. Don’t look to me for a decision. As Alan Turing said, “The Entscheidungsproblem has no solution.”
But consider this: Environments such as TopView and Gem and Windows only really show their stuff when they’re running programs designed specifically for the environment. These programs have not yet been written, and until they’re written, users aren’t going to suddenly say “I want to start running the XYZ environment.” They will run XYZ when they want to use an application that requires XYZ.
And who know who’s going to write these applications?
That’s right: You are.
And so, if you’re considering writing applications for one of these platforms, you should really be asking yourself: Which company is totally committed to the future of their environment? And which company has put together a quality software development kit that lets us successfully write these applications of the future?
Or, as Saint Ballmer has so wisely said, “By their SDKs shall ye know them.”
IBM, Digital Research, and Microsoft have all released SDKs for their respective environments. They’re all about $500, they’re all pretty complex, but to tell you the truth, the one that really stands out is Windows. It’s not perfect, but you get the impression that Microsoft really wants Independent Software Vendors like yourselves to invest in writing applications for Windows.
The Windows SDK comes with 7 diskettes, with all the tools you need including a special version of the Microsoft C Compiler version 3.0, and it also includes two fat manuals totally about 1000 pages containing everything you need to know to write Windows apps.
I know that many of you swear by assembly language for PC programming and I’m very sympathetic. The PC wouldn’t be where it is today without assembly language. And many of you are hesitant about using high-level languages like C because of the performance issues.
Let me put it this way. Any performance problems you experience with your Windows applications are probably not the result of using C rather than assembly language. But if you want, you can use assembly language for writing Windows programs, and you can even use Microsoft Pascal, but most of the sample code and documentation is geared towards C.
Let’s drop down to the DOS command line and start exploring this baby. I have both Windows and the SDK installed on this machine, and I hacked out a little program this morning that we can look at.
You may be asking: Why do I even need a $500 SDK? Why can’t I just CC my apps like I’ve always done?
Well, one of the things you get with the SDK is this indispensable 80K header file named WINDOWS.H. Now, I don’t know what kind of programming you do, but I have never seen a header file that was 80K in size. This header file essentially defines the application programming interface available to your Windows programs. It defines a bunch of new data types, constants, and structures, and also declares every function call that Windows makes available to your application, and there are about 400 or those, all nicely documented in the reference manuals.
Using the typedefs and constants that WINDOWS.H provides for you is important. Microsoft has basically guaranteed that the programs you write for Windows today will run on that future version of DOS that will take advantage of the protected-mode of the 286 microprocessor.
Let’s look at a small sample Windows program. I was feeling in a particularly festive mood, so I decided to write a little program that displays a graphical birthday cake.
A Windows application is generally assembled from several different types of source code files. Of course, the major part is the actual C program, but let me show you something else first. This is called a resource script, and it has the filename CAKE.RC.
The two major parts of the user interface in Windows are menus and dialog boxes. The resource script provides a simple way for you to define these things. The menu generally has a bunch of items going horizontally across the top, and each item invokes a little popup submenu. The top-level items are indicated by the keyword POPUP and the items on the submenu by MENUITEM.
All the program’s dialog boxes are defined by text templates like this one. The dialog box contains a collection of user interface objects known as “controls.” The keyword LTEXT indicates a left-justified text string, EDITTEXT is a little box in which you can enter or edit text. CHECKBOX is a text string with a little box that you can check or uncheck. There are two PUSHBUTTON’s one a default labeled “OK” and the other labeled “Cancel”. These are all followed by device-independent coordinates and sizes.
You’ll notice some upper-case identifiers beginning with the letters IDM and ID. Those identifiers are defined in the header file for the program, which of course is called CAKE.H. Here’s CAKE.H. A tiny little thing.
Here’s CAKE.C. As you can see, it too references WINDOWS.H and CAKE.H, and it contains some global variables, and some forward declarations of some functions.
The entry point to every Windows program is a function named WinMain. A typical Windows program begins by defining a window class structure and registering it by calling the RegisterClass function. It then creates a main application window based on this class by calling CreateWindow, and if some of this terminology sounds a little like object-oriented programming, well, that’s not accidental.
The code in WinMain concludes with a little chunk of code called the “message loop.” There’s actually stuff coming through here, mostly keyboard and mouse input, but the program doesn’t really do anything with it right here. Instead, all the input events for a particular application are dispatched to another part of the program.
This is the second major function that every Windows program includes, and it’s called the window procedure or “window proc.” This procedure was specified when registering the window class. Everything the program needs to know comes through here in the form of messages. The window proc is message central. It’s like the switchboard of the entire application, and each of these messages is associated with an identifier that begins with the letters WM for “window message.”
There’s WM_KEYDOWN and WM_MOUSEMOVE and WM_COMMAND tells you when the user has selected an item from the menu, and you can tell which item by the identifier that you defined that you associated with the particular menu item.
One of the most important messages is called WM_PAINT, which tells your program when it’s time to redraw the contents of its window. This is a very strange concept, I know, but it’s essential to create proper Windows programs. This section of the program contains a lot of calls to Windows Graphics Device Interface or GDI functions.
A couple other small files round out the typical Windows application. One of them is the module definition file, CAKE.DEF. Among other things, this file defines your program’s EXPORTS, which are functions in your program that are called from Windows. These are the window procedure and a similar function for the dialog box.
Compiling this program requires a few steps. You need to compile the C source code to get an OBJ file, and you need to compile the resource script using the resource compiler — yep, another piece of the SDK — and then you have to run a special linker named LINK4, and then the resource compiler again to add the resources to the EXE file.
To save a little time and typing, Windows programmers generally put all these commands into a single make file, which generally has the same name as the program but no filename extension. And here is the CAKE file.
To compile and link the program, we run the MAKE program on this make file, which is simply the command MAKE CAKE. And there we go. We now have a file called CAKE.EXE which is less than 6K in size, and which we can run on the DOS command line.
Uh, oh: “This program requires Microsoft Windows.” Don’t worry: We’ll be entering Windows momentarily. Let’s go to the Windows directory.
If you’re a C programmer, you’re accustomed to linking into your program all the library functions you need. The code in all those functions like printf and fopen and strlen actually becomes part of your executable. You’re probably assuming it’s the exact same story for all these Windows functions. And you would be wrong.
All the 400 function calls that Windows provides for your application are located in three files — I’ll show them to you — three files named KERNEL.EXE, USER.EXE, and GDI.EXE, totalling about, ohh, looks like 250K. Those three files basically implement Windows. All the memory management and tasking stuff is in KERNEL, all the user interface stuff is in USER, and GDI contains the Graphics Device Interface — the functions used to draw graphics and formatted text.
Now, when you compile and link your Windows application, the actual calls in your code are just dummied out. Only when you run the program under Windows are these calls linked up to the entry points in the KERNEL, USER, and GDI modules.
Yeah, I know. Sounds like a real operating system, doesn’t it? This process is known as dynamic linking, and these three modules are known as dynamic link libraries or DLLs. You can even write you own DLLs.
To run Windows, just type WIN at the command line.
And there we are. The initial program that comes up is called the MS-DOS Executive. The program identifies itself at the top in a caption bar, and the program’s menu is under that.
Now, I know when some people see graphical environments they start whining and saying “But I don’t want to use a mouse. There’s no room on my desk for a mouse.” Well, with Windows, for the most part the mouse is optional. I won’t be using a mouse at all during this demonstration.
For example, you can invoke the menu by pressing the Alt key with the first letter of one of the menu items, and you can move around with the cursor keys.
Let’s run the Windows CALENDAR program. The MS-DOS EXECUTIVE appears as an icon at the bottom of the screen. I’ll load in a file that I use to keep track of my life, and you’ll see that it lists the stuff I need to do today. You can shift between the two programs using the Alt and Tab keys, and you can invoke something called the system menu with Alt and the Spacebar. Move lets you move the icon up to exchange the programs. Or, if you move the icon to an edge, you’ll get both windows on the screen at one, and you can switch between them using Alt Tab. This is called “tiling” and it’s central to how Windows arranges multiple applications on the screen.
Now let’s run the Windows Calculator. Ohh, very nice. It’s a regular four-function calculator. You can use the mouse or the keyboard.
Now let’s split the screen three ways, and let’s run Windows Write, which is a full-fledged WYSIWYG word processor.
What have we got? Multitasking? Sure. Windows implements a kind of cooperative non-pre-emptive multitasking that let’s you easily move between multiple programs.
Memory management? You bet. It’s too complex to go into now, but the memory management that Windows implements under the 8086 real-mode is simply jaw-dropping.
Interprocess communication? Watch this. I go to the calculator and select Copy from the Edit menu. Then I go to Write and select Paste from the Edit menu.
Now, let’s find the Cake program. Back to the Cake directory, and let’s run it.
We use the menu to display the dialog box,
Now who shall we wish Happy Birthday to? Let’s say Windows, and give it 10 candles. We’ll pretend that it’s 1995 and Windows is 10 years old.
Now let’s light the candles.
Let’s go back into the dialog box. Let’s give it 20 candles and we’ll make the bold prediction that Windows will still be around 20 years from now, the year Two Thousand and Five.
And that is Windows, and I don’t know about you, but after this event is over, I’m going home and writing me some Windows apps.
© 2005, Charles Petzold (www.charlespetzold.com)
First Posted: November 2005
Back to the Et cetera page.
Back to Home