Electronic Review of Computer Books

[ ERCB Home | New | Feature | Brief | DDJ | Letters | Links ]

[an error occurred while processing this directive]

Vital Statistics

Title

MFC Internals: Inside the Microsoft Foundation Class Architecture

Authors

George Shepherd and Scott Wingo
http://www.stingsoft.com/

Publisher

Addison-Wesley Publishing Company, Inc.
Reading, Massachusetts
http://www.awl.com/devpress/

Copyright

1996

ISBN

0-201-40721-3

Pages

709

Price

$39.95


Telling It Like It Is, Not How It Should Be

What we've lost now that "user-friendly" days are here and structured programming is passé is the concept of right and wrong in programming. Everyone strives to encapsulate reality, but, perhaps because everyone's reality differs, every developer's concept of the right way to implement an application differs as well. What was science has become art. But don't let Microsoft or any other tool vendor fool you -- software engineering still isn't easy to do. Developers may have fewer lines of code to write, but they have to think more about each line of code.

The tool a developer uses to create applications influences the reality that gets encapsulated. These days, Windows developers' reality is often constrained by Microsoft's Visual C++. That means Windows developers must know the SDK, C, and C++ and the peculiar assortment of building blocks and C++ extensions called the Microsoft Foundation Classes. (Did someone tell you that we didn't need to know the SDK anymore now that we have Visual C++? Sorry to disappoint you. I have, actually, written programs using Borland C++ where I never needed my SDK docs, but that was in an alternate universe, one where I didn't need to call Create() after every new.)

MFC is a work in progress. It's nigh on impossible for the ordinary person to determine all its features and pitfalls using the documentation that Microsoft provides, let alone to follow its evolution; it changes quarterly. In fact, because MFC's documentation is usually shipped on-line only, it's hard to find out about something unless you know its name and how to spell it. Knowing a good deal about the history of VC++ itself helps as well. (My favorites are the functions that begin with "Afx"... Try finding out about these if you forget the "Afx"!)

That's why many MFC developers learn MFC by trial and error. You write something, it compiles fine, you run it and it blows up, and, once you fix the problem, you've learned something. Or, you read about an interesting class, spend time designing an object that seems appropriate, but then it turns out, you really can't use that class to construct that object, at least not in the way you conceived of it.

In addition, much information of vital importance to developers is simply not documented in any of the materials that accompany this compiler. And, few books about Visual C++ convey much of this vital information either. In fact, most books about MFC do little more than restate the documentation provided by Microsoft. What we need is a book that tells it the way it is, not the way it is supposed to be.

That's why, if you program in MFC, you need MFC Internals. Shepherd and Wingo don't dazzle us with science. MFC Internals has few pretty pictures and it comes with a plain old floppy disk, not a CD. The text of the book is not on the disk, nor is there code for every chapter. But there are a number of un-assuming but interesting little programs, alluded to in the book, that relate to particular topics of interest. The authors don't tell us everything we might want to know about them, but they give us enough to get started.

MFC Internals has little flow, either, which is actually an advantage in a book of this type. It's advisable to read whole chapters in order, but you don't necessarily have to read the first five chapters to understand the sixth. The authors provide helpful suggestions about which chapters to read together early on in the book.

MFC Internals is not a book for those just learning Visual C++. It doesn't tell newbies how to use an App Wizard, or how to use the IDE. You need to use VC++ for a while, notice its good features, get frustrated by its idiosyncrasies, before you can appreciate a work like this one.

MFC Internals gets specific where other reference sources about Visual C++ stop. Take, for example, MFC's much-hyped Document-View architecture. Even in the bad old days of linear programming, we knew that separating data from the display of data was a good idea. Doc-View plays a prominent part in every MFC program, but, in my experience, is so poorly explained and implemented in MFC that the average MFC programmer doesn't take advantage of it.

MFC programmers talk the Document-View talk, but never venture past the document templates the App Wizards generate. The learning curve spirals abruptly upwards every time you try to do anything interesting with MFC's CDocument or CView classes, not to mention the CDocTemplate classes, which I haven't found documented usefully anywhere until MFC Internals.

Discussion of the Document-View architecture and, especially, the distinctions between the Multiple Document Interface (MDI) and Single Document Interface (SDI) proves treacherous for most authors. Document-View should mean that I can display a single document (or, data source) in a variety of formats. But, actually, MFC's SDI precludes displaying multiple views of a single document, except in its brain-dead splitter windows. Most authors are, perhaps understandably, reluctant to come out and say that Microsoft has made it almost impossible to create a useful SDI application using the tools MFC makes public.

Which is probably why most authors cave. They define terms exactly as they are defined in the MFC docs. They throw in one brain-dead SDI example with a splitter window. Then, they spend pages and pages explaining how MDI is the way Microsoft implements important applications like Word and Excel. So, all these books imply, isn't MDI the way we all really want to go, because we want all our applications to look like just Microsoft's Word and Excel don't we?

Contrast this with the exposition of Document-View in MFC Internals. Politically skirting the issue of why SDI allows only a splitter window, Shepherd and Wingo thoroughly define all the terms and tell us what Microsoft's rules for them are. Fairly often, they throw in something like: "You don't need to use a CView here, but you lose some of the functionality of the CView." I believe that this is where they are recommending that we go around Doc-View, and then they tell us how. Later, in discussing document templates, they say "You can use frames/views/documents without relying on CDocTemplate or any of its derivatives. CDocTemplate really doesn't do anything special other than encapsulate a few common uses of the document/view framework." In other words, CDocTemplates have straight-jacketed us for years, but there is a way around them too.

In the chapters having to do with Doc-View, as in other chapters, MFC Internals shows us the ways around the MFC ties that bind most uncomfortably. In addition, it describes many undocumented classes. Although the authors are careful to say these are subject to change in the future, they also point out which ones are used extensively within MFC itself, which makes it unlikely they will change.

Shepherd and Wingo use quite a few adjectives, admiring ones, natch, in the first chapter or two, but they soon run out of them, which is good. They are quite careful about how they state things that might, in other hands, seem to be accusing Microsoft of not having a clear plan for MFC. Often a historical context is used to show how something evolved to be the perverse mess it is today. In other cases, they'll reproduce a conversation with a Microsoft insider who isn't exactly sure why suddenly something changed. And yet, the authors don't waste time bashing Microsoft or Visual C++. Usually, if they use an adjective like "wacky" to describe something, it's hyperbole. They then proceed to baldly state the pros and cons of Microsoft's decisions.

The choice of topics is good as well. Particularly interesting to me was "Chapter 5: All Roads Lead to CObject", which really does prove that we should be deriving almost everything in our realities from CObject if we want to take advantage of what MFC gives us. The chapters on COM and OLE were obviously written before ActiveX and its associated buzzwords invaded our reality. The concepts may be the same, but the jargon is, unfortunately, not in the index. By the time you've digested the rest of the book, an update to the book will, hopefully, remedy this shortcoming.

Not convinced that this book is for you? Go to your local bookstore and read page 100 of MFC Internals. Observe how Wingo and Shepherd walk that fine line between admiration, skepticism and, is that -- wonder -- when they note how much is not documented. Their wry observations make otherwise dry topics memorable; I learned something new about pretty much every topic covered. But don't read this book until you've developed your first real application in MFC. You need to learn how much you need to learn before you can appreciate MFC Internals.

If only MFC Internals explained why Microsoft forces us to do a Create() after every new, I'd stand on street corners asking developers if they'd been saved and giving away copies of this book ....

-- Emily Berk (armadill@ix.netcom.com)


Excerpts from "MFC Internals"

"Well, well, well. It looks like we have yet another undocumented helper class here! ..."

-- MFC Internals, pg. 382.

* * *

"Understanding the difference between native window handles (HWNDs) and the MFC objects representing windows is very important. At the highest level, MFC is set up to work with CWnd objects. However, native Windows code deals with window handles. For example, when Windows calls a window procedure, Windows passes a window handle as a first parameter. However, MFC's message dispatch mechanism works with CWnd-derived objects.. In order for the message dispatching to work, MFC has to figure out which CWnd-derived object is associated with a particular handle. MFC uses a class called CHandleMap to relate CWnd-derived objects to window handles."

-- MFC Internals, pg. 45

* * *

"Version note: Versions of MFC before release 4.0 maintained the document template list right in CWinApp. Microsoft appears to be abstracting it out into CDocManager, though it's not crystal clear why. Perhaps they are making way for new MDI alternatives. Who knows -- maybe managing this list in CWinApp got cumbersome and Microsoft just wanted to dust off CWinApp in 4.0.

"Here's what our MFC insider had to say:

" 'The main reason we separated out this implementation into a separate class is so that applications which don't use doc/view (simple utilities, for example) don't take on the overhead. In the early days, it was OK to put all this functionality into CWinApp, because it was relatively small, such that it didn't impact the size of applications that didn't use it too much. Over time the implementation has grown as we added new features. In MFC 4.0 we separate out this functionality into a separate class with all virtual functions. If a CDocManager object is never created, its virtual table is never referenced, and as a result, its functions are not linked in. You'll see this technique used in several cases (for example, COccManager and CRecent FileList) where we want a feature and its associated code to be optional. Of course, if you use the DLL then all the code is there and this trick doesn't really do a lot of good. If you statically link, this can make a difference in size of the resulting application (we keep an eye on the size of the "HelloApp" sample for doing these kind of optimizations.) Also, as a side effect, someone could replace the CDocManager implementation with one of their own. In the future, we do want to reduce the amount of stuff in CWinApp--it is getting out of hand--and this is one example of moving toward that goal as well.' "

Note from Emily: Sounds good, right. Except how many people using MFC compile statically?

* * *

"If you stuck to your MFC documentation, you would think that this was the end of the CFile discussion. But there is another CFile class that is completely undocumented: CSharedFile. ... This class is so clandestine that its declaration has been hidden away in the most sacred of MFC header files, AFXPRIV.H....

"OK, What Is It Used For?

"... If you ever find yourself with a global handle that's coming into your MFC application from legacy C code or somewhere like the Clipboard, you now know that you can attach a CSharedFile to the memory and access it through a CFile interface. In fact, if you browse through some of the MFC samples (such as drawcli), you will see that Microsoft even uses this undocumented class in the samples."

-- MFC Internals, pg. 141

* * *

"Aha! Class CString is hiding the information that it needs for reference counting before the data pointed to by m_pchData. Now, the million-dollar question is Why on earth would the MFC team do something wacky like this? Why not add some new members to CString and not risk playing with un-type-safe pointers like this?

"We asked Dean McCrory, our MFC insider, about the motivation for what seems like a really nasty 'hack'.

" ... [Dean McCrory's comments]

" ' Microsoft could have also changed m_pchData to be a CStringData pointer and accessed the data that way in a more type-safe manner, but legacy MFC applications could potentially have code that derives a CString and accesses the m_pchData buffer pointer through the protected member, as in the example shown in Listing 4-6.' "

-- MFC Internals, pg. 99


Table of Contents

Foreword

Acknowledgments

Introduction

Why MFC Internals?

Chapter 1 A Conceptual Overview of MFC

Chapter 2 Basic Windows Support

Chapter 3 Message Handling in MFC

Chapter 4 The MFC Utility Classes

Chapter 5 All Roads Lead to CObject

Chapter 6 MFC Dialog and Control Classes

Chapter 7 MFC's Document/View Architecture

Chapter 8 Advanced Document/View Internals

Chapter 9 MFC's Enhanced User-lnterface Classes

Chapter 10 MFC DLLs and Threads

Chapter 11 How MFC Implements COM

Chapter 12 Uniform Data Transfer and MFC

Chapter 13 OLE Documents the MFC Way

Chapter 14 MFC and Automation

Chapter 15 OLE Controls

Appendix A A Field Guide to the OK Source Code

Appendix B The MFC Internals Floppy

Index


Quick Rating

Readability

StarStarStar

Originality

StarStarStarStar

Organization

StarStar

Accuracy

StarStarStar

Consistency

StarStar

Depth

StarStarStarStar

Timeliness

StarStar

Editing

StarStarStar

Design

StarStar

Overall Value

StarStarStar

Explanation of ERCB rating scale: No stars = unacceptable, 1 Star = marginal, 2 Stars = average, 3 Stars = above average, 4 Stars = exceptional.


Copyright ©1996 Electronic Review of Computer Books
Created 12-23-96 / Last modified 12-23-96 / webmaster@ercb.com