This book is an in-depth guide to the core features of OWL, namely, the OWL classes TApplication and TModule ; TControl and the rest of the OWL control classes; TWindow , TFrameWindow , and TDialog and their children; and the gadget subsystem within OWL.
This book is being released concurrently with Advanced OWL 5.0, which examines the lesser-documented and less-well-known aspects of OWL, such as multiple threads, mixin classes, and OWL debugging tips, leaving this book to focus on the hard-core (hence the name) classes of OWL. There will be some overlap between the two books, and each makes reference to the other from time to time.
Chapter 1 is a simple reintroduction to OWL, and what benefits we gain from OWL over doing things the old, hard, C/SDK way. This is really more of a warm-up than anything else, and helps to set the tone for the rest of the book.
Chapters 2 through 4 cover TModule and TApplication . We discuss how you use TModule for your DLLs just as you use TApplication for your EXEs, the kinds of support TModule can give you, how to avoid writing your own DllEntryPoint function, runtime and loadtime dynamic linking, the various application types, some application helper classes you may not know about, and some TApplication -derivatives for quick and dirty applications.
Chapters 5 and 6 traces message-handling. From the moment the WM_ message is dispatched from the Windows messaging system to the moment the message arrives in your carefully crafted event-handling method, we trace the flow of messages and point out the places where messages get sidetracked, detoured, and rerouted for greater flexibility. We discuss why OWL chose to use the message map architecture instead of some other approaches, and just for good measure, we put enablers under the microscope.
Chapters 7 and 8 jump into controls, both standard and custom. Standard Windows controls, Windows95/NT4.0 controls, custom OWL controls, custom C/SDK controls, standard controls with customized behavior, generic controls, owner-drawn controls, subclassed controls--they're all here.
Chapter 9 investigates the OWL gadget system, both TGadget and its children and TGadgetWindow and its children. We look at customizing gadgets and gadget windows, and provide some sample code of both.
Chapters 10 through 12 plumb the depths of TWindow , TFrameWindow , and TDialog . We look at all the TDialog -derived types, including the Win16/Win32 common dialogs and the new OWL 5.0 dialog types, TRollDialog , TInputDialog , and TPickListDialog . We peek inside TFrameWindow and its children, as well as some customized TWindows .
Chapter 13, a collection of questions and answers, is followed by a glossary and an annotated bibliography.
This book, like its companion volume, Advanced OWL 5.0, can be read in one of two different methods.
First, you can read this book sequentially, from cover to cover, and become an OWL guru. We will cover the core OWL classes in great detail, delving deeply into the OWL source code to pick apart each of the major OWL classes and their derivatives, and see what we can find. This is certainly the more comprehensive, and time-consuming, method.
Or, you can pick out the sections that interest you, read a chapter, and put the book down until something else catches your eye. None of the chapters depends on any other so you are free to move around from subject to subject.
For this book, the first is probably the preferred method, since the core aspects of OWL tend to interact with each other more often than the other, more peripheral (but not necessarily less important) aspects. Moreover, this book was written in a kind of order of appearance. For example, the discussion about TModule and TApplication , comes before coverage of TWindow or the various controls because, conceptually, your application or DLL code is being executed long before any code in a window or control is.
Many times, it is as important to know what isn't covered in a book as to know what is. In this case, due to size limitations, several key technologies from OWL are not covered: none of the graphic display interface (GDI) classes ( TBrush , TPen , etc.) are covered, nor is printing nor print preview. While there may be some who immediately set this book back on the shelf for my decision to skip those two subjects, this was a conscious decision on my part. I couldn't cover everything. OWL is a huge system, and there's only so much this 2-volume book can cover. I tend not to use GDI or printing in my professional work (the last three projects I've done have all been client/server with a graphical user interface (GUI) frontend and a database backend), and while this may not be the world's most scientific study, empirical and anecdotal evidence seems to tell me that GDI isn't something that all OWL developers use; controls and windows and dialogs and menus and applications are.
This is not the place to find discussions of the undocumented (or rather, less-than-documented) classes and features of OWL. The place for that is in Advanced OWL 5.0. On the other hand, if we find something undocumented about a subject we are covering here, we'll explore it to great depths.
It always helps to know where you've been before you can know where you're going.
Time: Fall 1985 Windows 1.0 is released to the public, to a tremendous yawn, or belly-flop, if you prefer. In a time when 80286/12MhZ machines with a full 1MB RAM are top of the line, Windows is an incredible memory hog, not to mention slower than a snail in low gear headed uphill in an avalanche. Nobody's really interested, except maybe Petzold, and it takes him two years to produce the first Programming Windows edition.
Meanwhile, a language expert at AT&T has just made the first external release of a new language, C++. It is greeted with some speculation, some excitement, some trepidation. By his own estimation, Bjarne Stroustrup estimated that about 500 people were using C++ at this point. Not exactly what you'd call a tidal wave of users, but still 499 more than when he began work in October 1979.
Time: Spring 1990 Windows 3.0 is released to a tremendous explosion of interest. Over the next several years, sales of Windows 3.0 will break every software sales record the industry recognizes. Microsoft begins its domination of the software industry. Petzold releases a new version of Programming Windows, and becomes a programmer's household name. Entire generations of programmers are ingrained in the ways of WndProc and WNDCLASS , and Windows programming is hard. Very hard, to be exact. Remember to lock your blocks. Don't use large model. Oh, and don't forget your MakeProcInstance() calls.
At the same time, Borland makes its first commercial release of Turbo C++. Good timing, too, because Stroustrup estimates about 150,000 people are using his new language. The Annotated Reference Manual, or the Brown Book, the C++ bible, releases in the same month, describing C++ 2.0, which was released the previous June.
Some visionaries have already started thinking about how best to mix C++ and Windows, but it's still on the drawing board. A few forays are made, but nothing really takes steam.
Time: Spring 1992 Windows 3.1 is released to the public, and the sales records keep breaking. Petzold makes his new edition available, and his position as the father of all Windows programmers is reinforced. Stroustrup estimates 400,000 people were using C++ in 1991; he stops counting at that point. Windows programmers, ingrained by repetition, are still locking their memory blocks and minding their ProcInstance() calls and hand-crafted files. But by this point, Microsoft has also made a C++ compiler release, Microsoft C/C++ 7.0, and with it ships the MFC1.0, consisting of sixty-three classes that closely map to the Windows API. Borland, not to be outdone, has already released OWL 1.0 which offers the same promise that MFC 1.0 offers: "Use us. We'll help you forget all about those nasty Windows programming details that you shouldn't have to worry about." Only a few programmers pay attention, and so most of the Windows world continues along the C-driven course, unaware of the power and promise given by C++.
Time: Summer 1993 Windows NT 3.1 is released to the public, to a tremendous yawn. Petzold doesn't even bother writing Programming Windows NT: Joe User is not interested in upgrading his 386/33 with 4MB RAM to a 486/50 with 16MB RAM. Windows 3.1 is still growing, and the C++/Windows wars are taking on a new bent. Borland releases OWL 2.0 with Borland C++ 4.0, and OWL 2.0 corrects what some (including this narrator) see to have been the fatal flaw in OWL 1.0: the Borland extension of Dynamic Dispatch Virtual Tables, a nonportable extension to the C++ syntax that may have made some OWL coding easier, but definitely confused and muddied the waters. MFC also exists in a 2.x version, both on the 16-bit and the 32-bit side. Visual C++ 1.0 was broken into two distinct products, one for 16-bit development and the other for 32-bit development. Microsoft, backed by powerful voices in the C/C++ development media, appears to be winning over Borland and OWL. But the nature of C++ is still transitory, and new extensions are being adopted into the language even as Borland and Microsoft struggle for Windows C++ class library supremacy.
Time: Late 1994, Early 1995 Windows95 is still called "Chicago," and just about everybody and their grandmother has a beta copy. Microsoft shifts its research and development efforts in MFC from the 16-bit side to the 32-bit side, shipping MFC 3.1 with Visual C++ 2.1, the first 32-bit C++ release that didn't simply parallel what was being developed on the 16-bit side. Borland, meanwhile, releases Borland C++ 4.5 and OWL 2.5, but it simply introduces the OCF, which is designed to ease object linking and embedding (OLE) development. Now, somewhat behind Microsoft, Borland struggles to extend and improve OWL to catch up to the perceived gap between the two frameworks. But those who see the potential in OWL, the power in OWL over MFC, quietly work on. They can see OWL's inherent object-oriented design: it has been ported to OS/2, and could easily be ported to other platforms if the demand were there. Microsoft tries the same thing with MFC to the Macintosh and, in this narrator's view, fails horribly, mostly due to the API-wrapping that is the foundation of MFC that fails to allow for a different underlying mechanism to be successfully encapsulated. It doesn't end the hooting of the MFC-proponents, but those who have discovered OWL stick to their guns and wait.
Time: Summer 1996 Windows95 ships, in an almost anticlimactic fervor. Newsweek and Time start carrying Windows95 polls and statistics. One can walk into a fast-food joint just about anywhere in the nation and hear people talking about files and storage and realize they're talking about computers and not those metal things that hold paper. C++ nears standardization, but a new trend starts to emerge, one that is independent of C++, but could have tremendous impact on the language and its uses. In early 1995, Design Patterns is published, bringing to the average C++ programmer the power of the emerging idea of patterns. Microsoft shipped Visual C++ 4.0 and MFC 4.0 (so named because the new release was so good as to warrant a jump in the version numbers), and Borland's answer only now comes forth. Borland C++ 5.0, codenamed Vulcan, ships, and OWL 5.0 answers every challenge laid down by MFC 4.0, as well as issues a few of its own. Unlike Microsoft, which introduces nonstandard C++ syntax within Visual C++ to cover its own problems within MFC, 1 Borland relies only on standard C++, and even breaks itself into separate layers to make OWL more portable to other compilers and other architectures.
Suddenly, Windows programming isn't so hard anymore. Matter of fact, it is downright ... fun.
Time: Now The heresy begun in 1993 with OWL 1.0 gains strength. OWL 5.0 stands as a classic example of encapsulation and architecture-hiding, being inherently portable between both Windows 3.1 and Win32 (Windows95 and WindowsNT), something not even MFC can claim. (16-bit MFC development ceased in July 1995.) OWL 5.0 finds a loyal flock eagerly awaiting the chance to plumb its depths and explore its capabilities and to push it to the edge of the envelope.
As Jeffrey Richter said in Advanced Windows and Windows95: A Developer's Guide, although only his name appears on the front cover of his book, there are many others' who should appear there. No truer words were ever penned by an author. In fact, if everybody's name that should be on the cover of this book were put there, there'd be no room left for the title, much less any cover art! And although an author's acknowledgments can often run longer than an Oscar speech, please bear with me and give me the moment I need to sufficiently thank all of them.
To begin with, I must thank my places of employment during the development of this book, Access Health Incorporated (Rancho Cordova, Calif.) and Ibex Technologies (El Dorado Hills, Calif.). The folks at both places were gracious and kind during difficult moments, and their support was greatly appreciated. Fabio, Ed, Keith, Bruce, is it time for basketball yet? Thanks also to the folks at Borland; without them, there'd be nothing to write about. Moreover, thanks specifically to Nan Borreson and Brian Meyers, who were kind enough to hear all my questions and struggle to find answers for them.
Thanks must also go to the folks at Manning: Marjan Bace, Ted Kennedy, Mary Piergies, all of whom struggled to work with this first-time author. Thanks, guys, for your patience and guidance. Your help and faith were invaluable.
Thanks, too, to the folks on the OWL mailing list; never once did they ever doubt that this would be a great book, and their confidence in me lifted my spirits right when it was needed. Not only that, but many were kind and gracious enough to allow code ideas of their's to be included in the CD at the back. If you're looking for a place to bring your OWL questions, the list is a great place to start. Rich, Gianni, Jack, Michael, Brian, Bruce, and many others, you are all great people, and I hope I've managed to live up to your expectations.
When I first began this project, I sent email to several book authors to see what sort of life book-writing was all about. One in particular responded to my queries in an eloquent and concise fashion, and now not only do I owe Bjarne Stroustrup a favor for inventing the C++ language, but for his comments and (repeated) answers to my questions. You'll be happy to know, Bjarne, that my marriage survived the book(s) and is doing well.
Thanks must also go to the men and women working the front lines at Lyon's Restaurants of Davis, Calif. (restaurant 469). Without them, you would be staring at the palm of your hand right now. When the time came to do writing, writing, and more writing, they kept me well-stocked with Diet Coke as I sat in the booth, laptop plugged into the ceiling, banging away at the keyboard, for hours on end. Thanks to Harry, Leonard, Damien, Janelle, Ben, Della, Barbara, Amy, Chad, Jennifer, Carolyn, and more. I couldn't have done it without you. Literally.
It seems that every author has to thank his parents, and I'm no different. What an author thanks them for, however, can be many things. I thank them for being who they are, so that they could rear me with the kind of love and affection and support they've shown me over all these years, not to mention their good consumer sense--sixteen years ago, it was a decision between an Apple Plus with 48K RAM, or a new Volvo. They came home with the Apple, and the rest is history. To my sister, JJ, also, I owe a great debt of gratitude--without the loan of her laptop computer, I really doubt I could have gotten the book written in time. To all of you out there looking for (or knowing somebody looking for) a wonderful actress and theater lead, I know just the woman.
Thanks must also go to Ron "The Younger" Reynolds, for many things, not the least of which is his ability to put up with me while I write a book. Without Ron's criticism and (mostly) constructive comments, this book would have been a much poorer work, and the code a lot buggier.
But most importantly, I must thank my wife, Charlotte, and my three-year-old son, Michael, for their unending support and love. With Michael, it was a little difficult at first adjusting to Daddy's constant "here-but-not-here" presence on the computer as I wrote the code, but once he discovered that computers can be fun too, he was a constant companion in the study. Sounds of Living Books' "Green Eggs and Ham" and "Dr. Seuss's A-B-C" wafted through the air to mingle with the sounds of tortured C++ code being hacked away. Thanks, Michael, and yes, Daddy can come read a story to you now. You've earned it. My wife, on the other hand, was forced to run the house by herself during the four months I was down at Lyon's pounding out page after page of text, and through it all her love and her support for the project was boundless. It has been said that behind every great man stands a great woman; in this case, behind this book stands a wonderful wife. I cannot express in words the gratitude and love I feel for this woman; I love you, honey, and thanks.
And now, on to the good stuff.
1. Microsoft allows the explicit call of a class constructor to initialize a particular object in a particular memory block: void* ptr = CObject::CObject(arg1, arg2, arg3, ...);
What is even more distressing is that this very case is already covered by C++'s current existing syntax, using the placement new operator: CObject* ptr = new (ptr) CObject (arg1, arg2, arg3, ...);