| Foreword |
|
xvii | |
| Acknowledgments |
|
xix | |
| Introduction |
|
xxi | |
| Why MFC Internals? |
|
xxi | |
| MFC Internals to the Rescue! |
|
xxii | |
| Who Will Benefit from This Book |
|
xxiii | |
| How to Use This Book |
|
xxiii | |
| A Word of Caution |
|
xxiv | |
| Contacting the Authors |
|
xxv | |
|
A Conceptual Overview of MFC |
|
|
1 | (28) |
|
Some Background on Object-Oriented Programming |
|
|
1 | (1) |
|
|
|
2 | (1) |
|
|
|
2 | (1) |
|
|
|
2 | (1) |
|
|
|
2 | (1) |
|
|
|
3 | (1) |
|
|
|
3 | (1) |
|
|
|
3 | (1) |
|
|
|
4 | (2) |
|
|
|
6 | (1) |
|
Application Frameworks and MFC |
|
|
7 | (5) |
|
|
|
7 | (1) |
|
|
|
8 | (2) |
|
|
|
10 | (1) |
|
But That Wasn't Enough ... |
|
|
10 | (1) |
|
|
|
11 | (1) |
|
|
|
12 | (16) |
|
|
|
12 | (4) |
|
|
|
16 | (5) |
|
Application Framework Classes |
|
|
21 | (1) |
|
|
|
22 | (2) |
|
Operating System Extensions |
|
|
24 | (4) |
|
|
|
28 | (1) |
|
|
|
29 | (36) |
|
|
|
30 | (9) |
|
All That (Boilerplate) Code |
|
|
31 | (1) |
|
|
|
32 | (4) |
|
|
|
36 | (1) |
|
Initializing a Particular Instance of the Application |
|
|
37 | (1) |
|
|
|
37 | (1) |
|
|
|
38 | (1) |
|
Basic MFC Application Components |
|
|
39 | (7) |
|
CWinApp: The Application Object |
|
|
39 | (3) |
|
CWnd: The Base Window Class |
|
|
42 | (2) |
|
Turning Window Handles into Window Objects |
|
|
44 | (2) |
|
Attaching and Detaching Window Handles |
|
|
46 | (1) |
|
|
|
46 | (8) |
|
|
|
48 | (3) |
|
|
|
51 | (1) |
|
Initializing the Framework: AfxWinInit() |
|
|
52 | (2) |
|
Some Other Hidden Cool Stuff |
|
|
54 | (4) |
|
Registering Window Classes |
|
|
54 | (3) |
|
|
|
57 | (1) |
|
MFC's Message Pump: CWinApp::Run() |
|
|
58 | (1) |
|
|
|
58 | (5) |
|
|
|
59 | (2) |
|
|
|
61 | (2) |
|
|
|
63 | (2) |
|
|
|
65 | (28) |
|
CCmdTarget and Message Maps |
|
|
65 | (1) |
|
|
|
66 | (4) |
|
Message Handling Using C and the SDK |
|
|
67 | (2) |
|
|
|
69 | (1) |
|
MFC Message-Mapping Internals |
|
|
70 | (5) |
|
|
|
70 | (1) |
|
Message Map Data Structures |
|
|
70 | (1) |
|
|
|
71 | (4) |
|
How MFC Uses Message Maps |
|
|
75 | (16) |
|
How MFC Windows Become Wired to a WndProc |
|
|
76 | (1) |
|
|
|
77 | (4) |
|
|
|
81 | (6) |
|
Handling Regular Window Messages |
|
|
87 | (2) |
|
|
|
89 | (2) |
|
Hooking into the Message Loop: PreTranslateMessage() |
|
|
91 | (1) |
|
|
|
92 | (1) |
|
|
|
93 | (58) |
|
|
|
93 | (14) |
|
Class CString: A char * on Steroids |
|
|
94 | (12) |
|
|
|
106 | (1) |
|
|
|
107 | (22) |
|
|
|
108 | (1) |
|
|
|
108 | (6) |
|
|
|
114 | (8) |
|
|
|
122 | (7) |
|
The CFile Family: MFC Access to Files |
|
|
129 | (14) |
|
|
|
130 | (1) |
|
|
|
131 | (2) |
|
|
|
133 | (3) |
|
|
|
136 | (5) |
|
|
|
141 | (1) |
|
|
|
142 | (1) |
|
CException: Providing Better Error Handling |
|
|
143 | (5) |
|
|
|
145 | (3) |
|
|
|
148 | (3) |
|
All Roads Lead to CObject |
|
|
151 | (50) |
|
|
|
151 | (1) |
|
|
|
151 | (2) |
|
An Introduction to Macros |
|
|
153 | (1) |
|
Run-Time Class Information |
|
|
153 | (9) |
|
|
|
155 | (4) |
|
|
|
159 | (2) |
|
What's Left to Learn about CRuntimeClass? |
|
|
161 | (1) |
|
|
|
162 | (12) |
|
Adding Serialization to Your Classes |
|
|
162 | (1) |
|
Serialization: How It Works |
|
|
163 | (6) |
|
CObject and Serialization |
|
|
169 | (1) |
|
Tracing a Write and a Read of a CObject Derived Object |
|
|
170 | (3) |
|
Serialization Performance |
|
|
173 | (1) |
|
A CRuntimeClass Status Update |
|
|
174 | (1) |
|
CObject Diagnostic Support |
|
|
174 | (6) |
|
|
|
174 | (1) |
|
|
|
175 | (2) |
|
|
|
177 | (3) |
|
Inside CObject Diagnostic Support |
|
|
180 | (16) |
|
|
|
180 | (7) |
|
Advanced Memory Diagnostics |
|
|
187 | (5) |
|
|
|
192 | (3) |
|
Cool AFX Helper Functions |
|
|
195 | (1) |
|
|
|
196 | (1) |
|
|
|
197 | (1) |
|
|
|
198 | (1) |
|
|
|
199 | (2) |
|
MFC Dialog and Control Classes |
|
|
201 | (58) |
|
CDialog: Modal and Modeless MFC Dialogs |
|
|
201 | (24) |
|
|
|
201 | (3) |
|
|
|
204 | (8) |
|
CDialog Control Initialization |
|
|
212 | (3) |
|
DDX/DDV: CDialog Exchange and Validation |
|
|
215 | (10) |
|
|
|
225 | (11) |
|
Using the MFC Common Dialog Classes |
|
|
226 | (1) |
|
|
|
227 | (8) |
|
|
|
235 | (1) |
|
|
|
236 | (3) |
|
|
|
237 | (1) |
|
MFC OLE Dialog Class Internals |
|
|
237 | (2) |
|
|
|
239 | (1) |
|
Property Sheets (a.k.a. Tabbed Dialogs) |
|
|
239 | (11) |
|
|
|
240 | (1) |
|
Property Sheet and Page Internals |
|
|
241 | (8) |
|
|
|
249 | (1) |
|
|
|
250 | (7) |
|
The ``Old-Fashioned'' Windows Control Classes |
|
|
250 | (6) |
|
The ``New-Fangled'' MFC Windows Common Control Classes |
|
|
256 | (1) |
|
|
|
257 | (2) |
|
MFC's Document/View Architecture |
|
|
259 | (36) |
|
Why You Want Document/View |
|
|
259 | (1) |
|
|
|
260 | (1) |
|
|
|
260 | (1) |
|
|
|
261 | (6) |
|
|
|
261 | (1) |
|
|
|
262 | (4) |
|
|
|
266 | (1) |
|
Inside the Document/View Architecture |
|
|
267 | (22) |
|
The CWinApp/CDocTemplate Interface: CDocManager |
|
|
267 | (6) |
|
CDocTemplate: CDocument, CView, and CFrameWnd Manager |
|
|
273 | (6) |
|
|
|
279 | (3) |
|
|
|
282 | (6) |
|
|
|
288 | (1) |
|
Document/View Internals Recap |
|
|
289 | (4) |
|
Document/View Interdependencies |
|
|
289 | (1) |
|
|
|
290 | (1) |
|
|
|
290 | (3) |
|
|
|
293 | (2) |
|
Advanced Document/View Internals |
|
|
295 | (38) |
|
Mirror, Mirror, on the Wall ... |
|
|
295 | (4) |
|
|
|
296 | (3) |
|
|
|
299 | (8) |
|
|
|
300 | (2) |
|
|
|
302 | (5) |
|
Inside CView Print Preview Support |
|
|
307 | (10) |
|
CView::OnFilePrintPreview() |
|
|
308 | (1) |
|
|
|
309 | (1) |
|
|
|
309 | (2) |
|
CPreviewView: An Undocumented Print Preview CView Derivative |
|
|
311 | (3) |
|
Inside CPreviewView::SetPrintView() |
|
|
314 | (2) |
|
|
|
316 | (1) |
|
CView Derivatives: CScrollView |
|
|
317 | (10) |
|
|
|
317 | (6) |
|
|
|
323 | (1) |
|
CForm View: Forms in a View |
|
|
324 | (3) |
|
|
|
327 | (1) |
|
Another CView Derivative: CCtrlView |
|
|
327 | (4) |
|
|
|
327 | (2) |
|
CTreeView: An Example Control View/CCtrlView Derivative |
|
|
329 | (1) |
|
|
|
330 | (1) |
|
|
|
331 | (2) |
|
MFC's Enhanced User-Interface Classes |
|
|
333 | (66) |
|
CSplitterWnd: MFC Splitter Windows |
|
|
333 | (32) |
|
The Anatomy of a Splitter Window |
|
|
334 | (1) |
|
Refresher: How to Use CSplitterWnd |
|
|
335 | (1) |
|
|
|
336 | (27) |
|
|
|
363 | (2) |
|
The MFC CControlBar Architecture |
|
|
365 | (27) |
|
Step Right Up to the CControlBar |
|
|
365 | (17) |
|
|
|
382 | (8) |
|
CControlBar Layout Management |
|
|
390 | (1) |
|
|
|
391 | (1) |
|
|
|
392 | (2) |
|
MFC MRU File List Implementation |
|
|
394 | (2) |
|
How MFC Implements MRU File Lists |
|
|
394 | (2) |
|
|
|
396 | (3) |
|
|
|
399 | (34) |
|
|
|
399 | (8) |
|
|
|
400 | (5) |
|
How the MFC States Are Related |
|
|
405 | (2) |
|
|
|
407 | (10) |
|
|
|
408 | (6) |
|
Extension DLL Initialization and Cleanup |
|
|
414 | (1) |
|
|
|
414 | (3) |
|
|
|
417 | (12) |
|
|
|
417 | (7) |
|
MFC User-Interface Threads |
|
|
424 | (5) |
|
A Tale of Threads, Handles, and Objects |
|
|
429 | (1) |
|
|
|
429 | (4) |
|
|
|
430 | (1) |
|
|
|
431 | (2) |
|
|
|
433 | (68) |
|
|
|
434 | (1) |
|
The Component Object Model |
|
|
434 | (1) |
|
|
|
435 | (2) |
|
|
|
437 | (2) |
|
Globally Unique Identifiers |
|
|
439 | (1) |
|
Exploring the Great IUnknown |
|
|
439 | (5) |
|
Object Lifetime Management |
|
|
440 | (2) |
|
|
|
442 | (1) |
|
A Peek at the Client Side: Call/Use/Release |
|
|
443 | (1) |
|
|
|
444 | (10) |
|
|
|
445 | (1) |
|
Out-of-Proc Servers (EXEs) |
|
|
445 | (1) |
|
|
|
446 | (3) |
|
Exposing the Class Factory in an In-Proc Server |
|
|
449 | (1) |
|
Exposing the Class Factory in an Out-of-Proc Server |
|
|
449 | (1) |
|
Unloading In-Proc Servers |
|
|
450 | (1) |
|
Unloading Out-of-Proc Servers |
|
|
451 | (1) |
|
Class Registration in the Registry |
|
|
452 | (1) |
|
Creating Instances of COM Classes |
|
|
453 | (1) |
|
COM Classes with Multiple Interfaces |
|
|
454 | (10) |
|
Implementing CoMath Using Multiple Inheritance |
|
|
455 | (3) |
|
Implementing CoMath Using Nested Classes |
|
|
458 | (4) |
|
A Class Factory for CoMath |
|
|
462 | (2) |
|
|
|
464 | (3) |
|
Using MFC to Create CoMath |
|
|
467 | (8) |
|
|
|
467 | (1) |
|
|
|
468 | (5) |
|
The Internal IUnknown Functions |
|
|
473 | (1) |
|
The External IUnknown Functions |
|
|
474 | (1) |
|
Multiple Interfaces through Nested Classes |
|
|
474 | (1) |
|
The MFC COM and Interface Map Macros |
|
|
475 | (4) |
|
Declaring the Nested Classes |
|
|
475 | (2) |
|
Building the Interface Map |
|
|
477 | (2) |
|
The CoMath Class Using MFC |
|
|
479 | (6) |
|
MFC COM Classes and Inheritance |
|
|
482 | (2) |
|
InternalQueryInterface() Revisited |
|
|
484 | (1) |
|
|
|
485 | (2) |
|
Implementing the Interfaces |
|
|
485 | (2) |
|
MFC Support for Class Factories |
|
|
487 | (11) |
|
|
|
487 | (4) |
|
Developer Tip: Registering Other Information |
|
|
491 | (2) |
|
The Heart of COleObjectFactory: OnCreateObject() |
|
|
493 | (1) |
|
COleObjectFactory and IClassFactory::LockServer() |
|
|
493 | (1) |
|
Creating Class Factories within Your App |
|
|
494 | (1) |
|
COleObjectFactory and Interface Maps |
|
|
495 | (2) |
|
Exporting the Class Factory from a DLL |
|
|
497 | (1) |
|
|
|
498 | (3) |
|
Uniform Data Transfer and MFC |
|
|
501 | (38) |
|
|
|
501 | (3) |
|
|
|
502 | (1) |
|
Limitations of the Windows Clipboard and DDE |
|
|
503 | (1) |
|
OLE and Uniform Data Transfer |
|
|
504 | (1) |
|
|
|
504 | (3) |
|
|
|
504 | (2) |
|
|
|
506 | (1) |
|
The IDataObject Interface |
|
|
507 | (2) |
|
|
|
508 | (1) |
|
IDataObject::GetDataHere() |
|
|
508 | (1) |
|
IDataObject::QueryGetData() |
|
|
508 | (1) |
|
IDataObject::GetCanonicalFormatEtc() |
|
|
508 | (1) |
|
|
|
508 | (1) |
|
IDataObject::EnumFormatEtc() |
|
|
509 | (1) |
|
|
|
509 | (1) |
|
|
|
509 | (1) |
|
IDataObject::EnumDAvise() |
|
|
509 | (1) |
|
|
|
509 | (2) |
|
MFC's IDataObject Classes |
|
|
511 | (4) |
|
Transferring Data via the Clipboard |
|
|
511 | (4) |
|
|
|
515 | (1) |
|
MFC's IDataObject Classes in Detail |
|
|
516 | (10) |
|
|
|
517 | (6) |
|
|
|
523 | (3) |
|
|
|
526 | (12) |
|
|
|
526 | (1) |
|
|
|
526 | (2) |
|
Implementing Drag-and-Drop Data Transfer Using MFC |
|
|
528 | (1) |
|
Originating a Drag-and-Drop Transfer |
|
|
528 | (1) |
|
Implementing a Drop Target |
|
|
529 | (2) |
|
Inside MFC's Drag-and-Drop Classes |
|
|
531 | (3) |
|
How MFC Drag-and-Drop Works |
|
|
534 | (4) |
|
|
|
538 | (1) |
|
OLE Documents the MFC Way |
|
|
539 | (42) |
|
|
|
540 | (10) |
|
|
|
540 | (2) |
|
Structured Storage, Compound Files, and Persistent Objects |
|
|
542 | (5) |
|
In-Place Activation and Visual Editing |
|
|
547 | (1) |
|
|
|
548 | (1) |
|
|
|
549 | (1) |
|
The OLE Document Protocol |
|
|
550 | (1) |
|
MFC's Support for OLE Documents |
|
|
550 | (7) |
|
The Base Classes: CDocItem and COleDocument |
|
|
550 | (2) |
|
OLE Document Containers the MFC Way |
|
|
552 | (2) |
|
|
|
554 | (3) |
|
OLE Document Servers the MFC Way |
|
|
557 | (4) |
|
|
|
557 | (4) |
|
|
|
561 | (1) |
|
The Container/Server Dance (Embedding) |
|
|
561 | (14) |
|
The Container: Creating a New File |
|
|
561 | (1) |
|
|
|
562 | (13) |
|
|
|
575 | (2) |
|
Inside COleClientItem::Close() |
|
|
575 | (2) |
|
Saving the Container's Document |
|
|
577 | (1) |
|
|
|
578 | (2) |
|
|
|
580 | (1) |
|
|
|
581 | (38) |
|
The History of Automation |
|
|
581 | (1) |
|
What Automation Can Do for You |
|
|
582 | (2) |
|
Writing an MFC Automation Application |
|
|
584 | (1) |
|
But How Does It All Work? |
|
|
584 | (1) |
|
COM Interfaces versus Automation |
|
|
585 | (12) |
|
|
|
585 | (2) |
|
IDispatch: The Key to Automation |
|
|
587 | (4) |
|
Implementing IDispatch by Hand |
|
|
591 | (6) |
|
Another Way: Using Type Information |
|
|
597 | (5) |
|
|
|
597 | (1) |
|
Object Description Language |
|
|
597 | (2) |
|
Implementing IDispatch Using Type Information |
|
|
599 | (2) |
|
Recap: Automation in the Raw |
|
|
601 | (1) |
|
|
|
602 | (15) |
|
|
|
602 | (2) |
|
|
|
604 | (7) |
|
CCmdTarget and GetlDsOfNames() |
|
|
611 | (2) |
|
|
|
613 | (1) |
|
|
|
614 | (3) |
|
Conclusion: The Consequences of ``The MFC Way'' |
|
|
617 | (2) |
|
|
|
619 | (36) |
|
VBXs and Their Shortcomings |
|
|
620 | (1) |
|
|
|
620 | (1) |
|
|
|
621 | (1) |
|
Using OLE Controls in a Project |
|
|
622 | (2) |
|
OLE Controls in a Dialog Box |
|
|
622 | (1) |
|
Using an OLE Control in a View |
|
|
623 | (1) |
|
|
|
624 | (4) |
|
MFC's OLE Control Classes |
|
|
624 | (4) |
|
MFC and OLE Control Containers |
|
|
628 | (1) |
|
|
|
628 | (1) |
|
|
|
628 | (1) |
|
|
|
629 | (1) |
|
A Day in the Life of an OLE Control |
|
|
629 | (5) |
|
|
|
630 | (2) |
|
|
|
632 | (1) |
|
Finishing Creating the Control |
|
|
633 | (1) |
|
|
|
634 | (5) |
|
OLE Connection Interfaces |
|
|
635 | (1) |
|
Establishing a Connection |
|
|
636 | (3) |
|
Establishing a Connection (Continued) |
|
|
639 | (1) |
|
|
|
639 | (3) |
|
|
|
641 | (1) |
|
|
|
641 | (1) |
|
|
|
642 | (1) |
|
Developer Tip: Adding an Event Sink to a View |
|
|
643 | (3) |
|
Adding a Function to Handle the Event |
|
|
644 | (1) |
|
Setting Up the Event Sink Map |
|
|
645 | (1) |
|
Inside OLE Control Property Pages |
|
|
646 | (8) |
|
Property Pages in a Nutshell |
|
|
647 | (1) |
|
Programming the Property Page |
|
|
648 | (1) |
|
Inside the Properties Verb |
|
|
649 | (2) |
|
|
|
651 | (1) |
|
|
|
652 | (1) |
|
|
|
653 | (1) |
|
|
|
653 | (1) |
|
|
|
654 | (1) |
| Appendix A A Field Guide to the MFC Source Code |
|
655 | (34) |
|
|
|
656 | (5) |
|
Class Declaration Subsections |
|
|
656 | (1) |
|
Variable Naming---Think Hungarian! |
|
|
657 | (1) |
|
Symbol-Naming Conventions |
|
|
658 | (1) |
|
The Proof Is in the Pudding! |
|
|
658 | (1) |
|
|
|
659 | (1) |
|
Granularity and Swap Tuning?! |
|
|
660 | (1) |
|
|
|
661 | (1) |
|
|
|
661 | (1) |
|
|
|
662 | (1) |
|
A Visual C++ Syntax-Coloring Tip |
|
|
662 | (1) |
|
|
|
662 | (1) |
|
A Guide to the MFC Source Code |
|
|
662 | (25) |
|
|
|
662 | (2) |
|
|
|
664 | (8) |
|
|
|
672 | (1) |
|
|
|
673 | (1) |
|
|
|
674 | (13) |
|
|
|
687 | (2) |
| Appendix B The MFC Internals Floppy |
|
689 | (2) |
| Index |
|
691 | |