![]() |
MVP Tips, Techniques, and Goodies |
|
Microsoft has been rewarding me for the last
few years for my contributions on the microsoft.public forums by
designating me as one of the Microsoft
MVPs. This page is the root of my "MVP Tips" sub-Web. You
can see my whole site by going to my home page.
This page is inspired by the very useful page of Bob Moore's MVP Site. I will attempt to not duplicate anything already on his page.
What I'm putting in here, besides code examples, are little essays that I've often posted to the microsoft.public.vc.mfc newsgroup and other places. Rather than keep posting them, I'm collecting my essays in one place.
Click to see the list of the LATEST STUFF
Some of these essays are intended for beginners, pointing out useful techniques. Some are for experienced programmers poking into previously unknown areas of MFC. Some are advanced techniques, highly specialized. Some are simply my take on "best practice", style issues I feel strongly about, and which are not addressed adequately by the Microsoft documentation, and in some cases which have a folklore of incorrect methodology which is promulgated on the newsgroups. Be prepared for a variety of discussions.
Note that these essays represent, in many cases, my opinion of the right way to do things. Other people have other opinions. Microsoft may have yet a different opinion. The views expressed in these essays are those of the author, and in no way represent, nor are they endorsed by, Microsoft. Or anyone else, as far as I know.
I've sometimes been asked how I dare to differ from Microsoft's opinion. Well, the answer is simple: their opinion may not be right. In some cases, Microsoft's views represent one programmer's view of how to do something, and I find nothing wrong with disagreeing with another programmer. Just because Microsoft has enshrined that opinion as company policy (for example, "Hungarian notation"), doesn't mean that it is "right" or "sensible". Just that one opinion has become pervasive in one culture. (After all, if using "m_" was the only correct and sensible way to designate member variables, don't you think Bjarne Stroustrup would have designed the language that way and no other? He didn't, and I'd offer that he's as competent as Simonyi. Just a matter of opinion).
Disagree with me? Have a better idea? Fine. Send me a pointer to an essay on your Web site. If I think you have written something reasonably coherent on the subject, I'll even put a pointer to your site in my essay, even if I disagree with it. And if you find a bug or something demonstrably incorrect in one of my essays, or code examples, let me know and I'll fix it and even give you a wave of the Flounder Fin. (Or even, as it turns out, put your remarks on my Web site, with your permission. Already I've got feedback that revised my essays on Attaching and Detaching Objects and Avoiding UpdateData).
The code here is delivered "as is" with no warranty, express or implied, about its utility, correctness, merchantability, or suitability for any particular purpose. I will not be responsible for consequences of the incorporation of this code, in its original or modified form, in any product. The usual verbiage applies here: I will not be responsible for any form of financial, business, or other loss, including but not limited to lost time, lost revenue, and the like, caused by the use of this code in any context. You are free to copy, modify, and reuse it in any context: personal, academic, or commercial, as you see fit. The only restrictions on its use is that (a) you may not publish it as if it is your own, or claim authorship of it in a public or private declaration; (b) you may not attempt to sell it for any amount of money (although you are free to incorporate it into products you are selling; you may not sell it standalone); (c) you may not redistribute the source without retaining my authorship.
Otherwise, there is a grant for the use of this code as an non-exclusive, royalty-free, perpetual license, subject to the above restrictions and limitations.
I do not believe in the GNU Public License (GPL, the "copyleft"); I do not think that code re-use should require that you make your code public, and I impose no such limitations on the users of my code.
This code and the essays are primarily provided as a form of teaching materials, to be studied for techniques and methodologies, philosophies of software design and construction, and as discussions to provoke thought.
Anyone who wishes to translate my pages to some language other than English is free to do so providing the following restrictions are observed:
If you wish to have me display a link on my site, please provide the text in your translated language naming the language (in your native language script if relevant, as Unicode text), and I will add a link to your translation to each of my pages for which you have sent me a link..
Have a cool function? Want it available? Well, you should really post it to www.codeproject.com, but if for some reason you don't want to go through that effort, I'll host some pages of interesting code as well.
http://home.earthlink.net/~railro
http://www.wotsit.org/search.asp?s=windows (file format descriptions)
(If you know a site that should be listed here, send it to me; I'll add it)
I have divided these into two major categories: Essays, that discuss issues, and Sample Code, where the essay presentation is somewhat thinner but there is a program you can download and use. I have further added categories that group some of these essays or code examples together, and I've designated them
Alternative Spin Lock Implementations (20-Nov-03)
Avoid CMutex, CSemaphore, CEvent, and
CCriticalSection (24-Jun-08)
![]()
Avoiding EN_CHANGE notifications (17-Aug-06)
Avoiding multiple instances (updated 4-Mar-00)
Attaching and Detaching Objects
The Best Synchronization is No Synchronization (5-Jun-07)
The Bridge-Color Problem (18-Jun-03)
A Bug in _CrtMemCheckpoint (14-Feb-07)
Building under both VS.NET 2003 and VS.NET 2005 (2-Sep-06)
C# Color Table (17-Mar-03)
C# Equivalences (17-Mar-03)
CAsyncSocket handling in UI threads (3-Jan-03, 4-Jul-03)
Character Functions (28-Jun-08)
![]()
A Checksum algorithm (3-Feb-01)
A Class for saving DC contexts (19-Feb-01)
ComboBox values in the Dialog Editor
Compensating for a Serious Bug in RICHED20.DLL (10-Sep-06)
Creating GUIDs (10-Jul-01)
CString
techniques (8-Feb-01, 24-Feb-01, 29-Dec-06) ![]()
A Degree in Brick Science (19-Jun-03)
Dialog box and control design (1-Jun-03)
Dialog Boxes in Console Apps (23-May-00, 8-Jan-03)
Dialog-based
Applications (15-Oct-01, 8-Jan-03, 5-Mar-06)
![]()
EBCDIC-to-ASCII conversion (8-May-01)
The Graphical Developer Interface
A Handy Guide to Handling Handles (21-Jun-00, 22-Jun-01, 8-Jan-03, 14-Jun-03)
Hooks and DLLs (13-Mar-01)
How Big is My Program? (12-Jul-00)
If Theordore Seuss Geissel had been an MFC Programmer (2-Sep-06)
Inside Memory Allocation (21-Aug-06)
An Introduction to Messages (21-Oct-01)
I/O Completion Ports and
Cross-Thread Messaging (21-Nov-03, Revised 1-Apr-06)
![]()
KB103788:
Creating Modeless Dialogs with MFC Libraries done right (18-Feb-08)
![]()
Memory Damage Primer (18-Aug-06)
MSDN Documentation Errors and
Omissions (15-Dec-07)
![]()
The n Habits of Highly Defective Windows Programs (10-Jan-03)
Optimization: Your worst enemy
A Self-Registering Window Class (15-Oct-01)
Sorting Techniques (4-Jul-03)
Subclassing Dialogs and Property Pages (13-Sep-00)
Surviving
the Release Version (18-Jun-01, updated 25-Oct-03)
Time is the Simplest Thing... (3-Jun-00)
Using PreSubclassWindow (15-Oct-01)
Using Semaphores (14-Jun-01)
Using Worker Threads (updated 28-Jan-00, 10-Apr-00, 20-Jan-01)
Asynchronous Socket Programming: KB192570 Done Right (4-Apr-07)
A BitmapFile Analyzer (6-Jan-03)
A Class for saving DC contexts (19-Feb-01)
A Class for Dynamically Loading DLLs (25-Nov-01)
A Clock project (21-Mar-06)
Copying ListBox Contents to the Clipboard (1-Sep-06)
Asynchronous File I/O (7-Mar-06)
Asynchronous Process Notification
An automatic build-number incrementer (13-Mar-00)
An Auto-Repeat Button (22-Oct-01)
A Better Bitmap Button Class (21-Dec-99, revised 28-Dec-99)
A Better Zoomin utility (13-Jun-05)
A Button with an Arrow (18-Jun-07)
Changing Dialog Box/CFormView Color
(20-Sep-07)
![]()
A Checksum Algorithm (3-Feb-01)
Converting a CInternetException to a printable string (14-Mar-02)
The CPUID Explorer (10-Mar-07)
The CTime Explorer (5-May-00)
A CWnd class mapper (19-Mar-07)
A Cylinder Drawing Class (26-Mar-08)
![]()
A Dialog Shortcut Consistency Checker (23-Dec-99, updated 4-Feb-00)
A Dynamically-Resized Combo Box
A Fast log2(n) function (18-May-07)
A Fiber Example (1-May-06)
The Floating Point Explorer (4-Jun-07)
Getting Timer Events in a CDocument class (18-Oct-01)
The GradientFill Explorer
(22-Jan-08, revised 10-Feb-08)
![]()
Hooks and DLLs (13-Mar-01)
A Horizontal-Scrolling ListBox Class (11-Mar-01)
An HTML validator (20-Oct-04)
An
Image Comparator Program
(8-Jan-08)
![]()
Limiting Dialog Box Resizing (1-Sep-06)
The LoadLibrary Explorer (7-May-06)
The Locale Explorer (28-Mar-06)
A Logarithmic Slider Control (22-Nov-03)
The MessageBox Explorer (9-Apr-07)
The Metafile Explorer (10-Feb-08)
![]()
An MFC Interface to ::FormatMessage (17-Aug-06)
An MFC Process Class (1-Sep-01)
The
OpenMP Explorer (23-Jun-08)
![]()
Owner-Draw
Controls: A Color Table Generator (12-Jan-02, revised 4-Jan-08)
A
PowerPoint Indexer (31-Aug-07, revised
6-Jan-08)
![]()
The PolyDraw Explorer (10-Feb-08)
![]()
Polygon Transformations (15-Sep-01)
Printing Bitmaps (8-Jan-03)
Rearranging Controls on a Dynamically Resizable Window (1-Sep-06)
A Registry Class and Library (7-Feb-01, Revised 3-Jul-05)
A Self-Registering Window Class (15-Oct-01)
Serial Port
Programming (14-Jun-06, revised 17-Aug-06, 25-Jan-08)
![]()
The SHGetFolderPath Explorer (29-Dec-06)
A subroutine for Screen Capture to the Clipboard
The Thread Affinity Explorer (9-Apr-07)
Threads and Pipes in Console Apps
(18-Nov-07)
![]()
A Toggle Button Class (28-Dec-99)
The ToString function (10-Jul-07)
![]()
A Tree
Printing Algorithm (30-May-07)
![]()
The Ultimate (DLL) Header File (19-Oct-00)
Using FormatMessage (13-Jan-02)
Using Semaphores (14-Jun-01, revised 19-Mar-06)
Using SetWindowRgn (16-May-04)
Using WM_COPYDATA (20-Oct-01)
UTF-8 encodings
for data exchange (16-Dec-07)
![]()
A Validating Edit Control (30-Oct-00)
A Vector Editor (16-Oct-01)
The Viewport Explorer (8-Jul-05)
Virtual Screen Coordinates (31-May-06,
22-Jul-07)
![]()
A whereis utility (7-Mar-06)
An HP16C Simulator (31-Jul-00, Palm Pilot version 20-Jan-01, C# version 18-Mar-03)
The complete CD contents for the Win32 book (17MB)
Avoiding UpdateData (3-Feb-01)
A BitmapFile Analyzer [lots of cool dialog box techniques included!] (6-Jan-03)
Changing Dialog Box/CFormView Color (20-Sep-07)
![]()
A Checksum Algorithm (3-Feb-01)
ComboBox values in the Dialog Editor
Compensating for a Serious Bug in RICHED20.DLL (10-Sep-06)
Copying ListBox Contents to the Clipboard (1-Sep-06)
A Dialog Shortcut Consistency Checker (23-Dec-99, updated 4-Feb-00)
Dialog box and control design (1-Jun-03)
Dialog-based
Applications (15-Oct-01, 8-Jan-03, 5-Mar-06)
![]()
I/O Completion Ports and
Cross-Thread Messaging (21-Nov-03, Revised 1-Apr-06 to include dialog-based
apps) ![]()
KB103788:
Creating Modeless Dialogs with MFC Libraries done right (18-Feb-08)
![]()
Limiting Dialog Box Resizing (1-Sep-06)
The MessageBox Explorer (9-Apr-07)
Rearranging Controls on a Dynamically Resizable Window (1-Sep-06)
A Self-Registering Window Class (15-Oct-01)
Subclassing Dialogs and Property Pages (13-Sep-00)
Using PreSubclassWindow (15-Oct-01)
A Class for Dynamically Loading DLLs (25-Nov-01)
A Self-Registering Window Class (15-Oct-01)
Hooks and DLLs (13-Mar-01)
The Ultimate (DLL) Header File (19-Oct-00)
A BitmapFile Analyzer [lots of cool dialog box techniques included!] (6-Jan-03)
A subroutine for Screen Capture to the Clipboard
Printing Bitmaps (8-Jan-03)
A Better Bitmap Button Class (21-Dec-99, revised 28-Dec-99)
The GradientFill Explorer
(22-Jan-08)
![]()
An
Image Comparator Program
(8-Jan-08)
![]()
Avoiding EN_CHANGE notifications (17-Aug-06)
A Better Bitmap Button Class (21-Dec-99, revised 28-Dec-99)
An Auto-Repeat Button (22-Oct-01)
Changing Dialog Box/CFormView Color (20-Sep-07)
[This essay mostly deals with the
controls in the dialog box]
Copying ListBox Contents to the Clipboard (1-Sep-06)
ComboBox values in the Dialog Editor
Compensating for a Serious Bug in RICHED20.DLL (10-Sep-06)
Dialog box and control design (1-Jun-03)
A Dynamically-Resized Combo Box
A Horizontal-Scrolling ListBox Class (11-Mar-01)
Limiting Dialog Box Resizing (1-Sep-06)
A Logarithmic Slider Control (22-Nov-03)
Owner-Draw Controls: A Color Table Generator (12-Jan-02)
Polygon Transformations (15-Sep-01)
Rearranging Controls on a Dynamically Resizable Window (1-Sep-06)
A Self-Registering Window Class (15-Oct-01)
Subclassing Dialogs and Property Pages (13-Sep-00)
A Toggle Button Class (28-Dec-99)
Using PreSubclassWindow (15-Oct-01)
A Validating Edit Control (30-Oct-00)
A BitmapFile Analyzer (6-Jan-03)
A Class for saving DC contexts (19-Feb-01)
A Better Bitmap Button Class (21-Dec-99, revised 28-Dec-99)
A Better Zoomin utility (13-Jun-05)
A Button with an Arrow (18-Jun-07)
A Cylinder Drawing Class (26-Mar-08)
![]()
The GradientFill Explorer
(22-Jan-08, revised 10-Feb-08)
![]()
An
Image Comparator Program
(8-Jan-08)
![]()
The Metafile Explorer (10-Feb-08)
![]()
Owner-Draw
Controls: A Color Table Generator (12-Jan-02, revised 4-Jan-08)
The PolyDraw Explorer (10-Feb-08)
![]()
Polygon Transformations (15-Sep-01)
Printing Bitmaps (8-Jan-03)
A subroutine for Screen Capture to the Clipboard
Using SetWindowRgn (16-May-04)
A Vector Editor (16-Oct-01)
The Viewport Explorer (8-Jul-05)
Virtual Screen Coordinates (31-May-06,
22-Jul-07)
![]()
Alternative Spin Lock Implementations (20-Nov-03)
Asynchronous File I/O (7-Mar-06)
Asynchronous Process Notification
Asynchronous Socket Programming: KB192570 Done Right (4-Apr-07)
Attaching and Detaching Objects
Avoid CMutex, CSemaphore, CEvent, and
CCriticalSection (24-Jun-08)
![]()
Avoiding multiple instances (updated 4-Mar-00)
CAsyncSocket handling in UI threads (3-Jan-03, 4-Jul-03)
I/O Completion Ports and
Cross-Thread Messaging (21-Nov-03, Revised 1-Apr-06)
![]()
An MFC Process Class (1-Sep-01)
The
OpenMP Explorer (23-Jun-08)
![]()
Serial Port
Programming (14-Jun-06, revised 25-Jan-08)
![]()
The Thread Affinity Explorer (9-Apr-07)
Threads and Pipes in Console Apps
(18-Nov-07)
![]()
Using
Semaphores (14-Jun-01, revised 19-Mar-06)
Using Worker Threads (updated 28-Jan-00, 10-Apr-00, 20-Jan-01)
Using WM_COPYDATA (20-Oct-01)
|
A spin lock is a kernel synchronization primitive. In the 2003 Driver Development Conference held in Redmond, Washington, Microsoft introduced a new implementation of the traditional Spin Lock. This one is able to sustain a greater pressure than an ordinary spin lock. |
|
The _CrtMemCheckpoint function has either a bug in its documentation or its implementation. This essay discusses the bug and gives the code for a workaround. |
![]()
Building Under VS.NET
2003 and VS.NET 2005 During the transition period, you might find, as I did, that I needed to support configurations under both VS.NET 2003 and VS.NET 2005. Unlike in the past, where Microsoft actually changed the names of the files, the VS.NET 2003 and VS.NET 2005 environments use files by the same names, but which are mutually incompatible. This article suggests one way that both configurations can be maintained. |
Character
Functions The C library ctype.h defines a number of predicates and transformations on characters, such as isalpha, islower, toupper, tolower, and so on. The Windows API provides some functions such as IsCharAlpha, IsCharLower, CharUpper, CharLower, and so on. Do the C Library functions and the Windows API functions return the same values? Absolutely not. Check out this table (beware: this is a massive file! It is almost 800K bytes of HTML, a table of nearly 10,000 cells). |
A
Checksum Algorithm Historically, checksums have been used to increase data transmission reliability, whether from a serial line or network, tape drive, or disk drive, among the many data sources that require reliability checking. However, checksums have other uses, such as in dialog box change-state maintenance, document change-state maintenance, and similar applications. This essay tells you a bit about how I use a checksum algorithm for this purpose, and includes a sample checksum class you can copy-and-paste into your application. |
Having trouble keeping your DC intact? Having too many complex variables around to hold old fonts, the next-oldest old font, the saved region, the saved bitmap, the saved ROP, the saved transform matrix, the saved pen, the saved brush, the previously-saved brush; the brush that was the brush before the previously-saved brush was saved...you get the idea. Here's an essay on how to do this much more easily using ::SaveDC/::RestoreDC, or CDC::SaveDC/CDC::RestoreDC. In addition I give you a really trivial C++ class, CSaveDC, that lets you do this even more easily than with the CDC primitives. |
Attaching
and Detaching Objects When you create an Windows-related object in MFC, you are actually creating a "wrapper" around the underlying object. There are interactions between MFC and Windows which can get you into serious trouble if you are not careful. Read this to learn more. |
Avoid
CMutex, CSemaphore, CEvent, and CCriticalSectionThe rules for the use of the CMutex, CSemaphore, CEvent and CCriticalSection classes boil down to one simple rule: NEVER, EVER USES THESE CLASSES! This article explains why these classes are so poorly implemented that they cannot ever work correctly. |
Avoiding
EN_CHANGE notificationsHandling complex control interactions when edit controls are involved can lead to problems when EN_CHANGE notifications are generated by the application actually changing the control values. To avoid having to handle EN_CHANGE notifications from CEdit and CRichEdit, this essay shows how to derive subclasses that allow these notifications to be selectively avoided. |
Avoiding
GetDlgItem in MFC My view: If you're writing more than one GetDlgItem per year, you're probably not using MFC correctly. Find out why, and what to do about it. |
Avoiding
Multiple Application Instances In Win16 it was easy: you looked at the hPrevInstance parameter to WinMain and if it was nonzero, you were the second instance. Done. In Win32 it isn't as easy. And there are several wrong ways, and some that don't work at all. This essay explores the techniques and tells you what the pitfalls are, and how to do it right. |
Avoiding
UpdateData Why you should never call UpdateData yourself. (This is actually related to the topic of avoiding GetDlgItem...if this discussion leaves you confused, go read the essay about GetDlgItem, and things will become clearer). |
The
Best Synchronization is No Synchronization In multithreaded systems, synchronization is required if two or more threads can touch a single object. This essay discusses some alternatives to the use of low-level operations such as mutexes and CRITICAL_SECTIONs. In particular, two paradigms called Positive Handoff and Central Manager are discussed as better alternatives to traditional synchronization primitives. |
The
Bridge-Color Problem What color does an engineer specify for a bridge? The decisions involved in determining what color to paint a bridge are not dissimilar from the problems we face in building software. And present many of the same hazards when we do reverse-engineering. How do you know when you have a bridge-color problem to solve, or when you've discovered a solution which may or may not be a bridge-color problem? |
Callbacks,
Threads, and MFC Proper use of MFC will allow you to access members of your MFC class from a callback or from within a thread. This essay describes how to accomplish this easily. |
|
A common problem many programmers have is trying to run sockets from a separate thread. You cannot use a worker thread; you must use a UI thread. And you cannot pass a CAsyncSocket reference across a thread boundary; it won't work. This is actually a subsection of an existing essay on the use of Attach and Detach, but I felt it deserved a top-level billing from this page. |
ComboBox
values in the dialog editor Do you think that the ability to preload values in a CComboBox by adding them using the dialog editor is useful? Think again. This is a way to certain trouble! Then download a code sample that simplifies initializing a ComboBox. |
Compensating
for a Serious Bug in RICHED20.DLL
There is a very serious and apparently undocumented bug in RICHED20.DLL, the implementation of one of the many chaotic attempts to build a usable Rich Edit Control. This particular version has a serious error which results in erroneous selection of text when the text is selected programmatically via SelSel. This essay shows an example of the consequences of the error and shows how to do a workaround. |
Creating
GUIDs GUIDs are a useful entity to guarantee that you have a unique name for a kernel object, Registered Window Message, clipboard format, or other object that must be guaranteed to be unique. However, there are times when a program needs to create a GUID; for example, a program that writes .h files. This essay tells how I created my own unique IDs. |
CString
techniques The CString data type of MFC is a powerful string mechanism. But it doesn't appear, at first glance, to support simple transformations from and to the conventional C/C++ char * data types. If you are confused about how to use CString effectively, read this essay. |
A
Degree in Brick Science A number of questions I see and answer in the newsgroups tend to be from people who seem to not understand modularity, interfaces, and so on. I address some solutions to this problem in a companion essay on dialog and control design, but the real problem seems to be an educational one. Given the quality of students I see in my courses, I'm convinced that by far the most incompetent are those with fresh B.S. degrees in Computer Science. In this essay, I conjecture about why this is so. |
Dialog-based
Applications Everyone asks the same questions: How do I keep the Enter key from closing my application? How do I keep the Escape key from closing my application? How can I get an Enter key in my control? How can I get an edit control which has no effect until the Enter key is hit? This essay and code sample illustrate how I accomplish this. |
Dialog
box control management Why you should never call EnableWindow or other such calls except in one central place. Think of control enabling as a set of constraint equations. Much easier to maintain if the computations are centralized. Find out how I do it, and why I think this is a good way to do it. |
Dialog
box and control design Far too many attempts at programs have involved the violation of every known principle of clean design. Controls that call methods in their parent dialog. Documents that call methods in the views. Dialogs that call methods in their parent window, such as a view. These horrors represent deep and fundamental failures in design, in such fundamental concepts as "modularity", "interface specifications", "abstraction", and other key design principles. This essay attempts to explain why these horrors are horrors, and what clean interface specifications look like and how to implement them. |
|
While Console Apps have their uses, they sometimes represent throwing out the baby with the bathwater, or something equivalent. Nominally, you can't interact with a Console App via a dialog box, even something that simply pops up a message. There is no reason these two worlds need to be completely disjoint, and this essay explains how to make them work together. Special thanks to fellow MVP David Lowndes for the key insight that made this work! |
Drawing
Techniques I've seen a lot of needlessly complex code, and far too much incorrect code, in doing drawing in OnPaint and OnDraw handlers. This essay points out some common failure modes and suggests simpler ways to accomplish the same tasks. |
EBCDIC-to-ASCII
Conversion (00-7F) (80-FF) It finally happened; I had to interface to a traditional Big Iron mainframe. After investigating the various Web sites, I was able to produce a set of tables that I used to construct an EBCDIC-to-ASCII conversion. One revelation was that some of the previously unused EBCDIC character positions have been reallocated to support most of the same glyphs as ISO-Latin-1 (the Windows character set, for example, maps well to this international standard). I think I've got these tables right, but if you see anomalies, let me know. |
|
While we talk a lot about the Graphical User Interface, many developers do not pay enough attention to the Graphical Developer Interface. This essay talks about the philosophy of the developer interface. It then references the essay on a Logging List Box, which is a very powerful control I use in nearly every application. |
A
Handy Guide to Handling Handles What, exactly, is a handle? In particular, what is a "file handle"? There are at least three ways of representing files, such as a small integer, a FILE *, and a Win32 operating system HANDLE. Then there are those MFC classes such as CFile and CStdioFile. And these are just some of the handles you see. What does handle inheritance mean and how is it done? What is handle duplication and why is it useful? In this essay (still under construction) I explore some of these issues. |
How
Big Is My Program? A question that comes up a lot in the newsgroup is "Why is my program so large?", usually followed by an explanation like "I created this nearly-empty application and it consumes (some large number) of megabytes". This is usually followed by a question of the form of "how to I reduce the size of my program?" The answer is: you're worrying about the wrong problem, based on incorrectly-interpreted information Go concentrate on the real problems. This essay explains both why there is a misunderstanding of the data, and what you should actually be worrying about. |
![]()
If Theodore Seuss
Geissel had been an MFC Programmer Some people's careers go different ways. Had Ted Geissel lived in the current era, he might have been an MFC programmer, and this might be the result. |
An
Introduction to Messaging This is an introduction to messaging, and in particular, MFC messaging. It is tutorial on several of the major messaging API functions, when to use them and not to use them, and some peripheral topics such as PreTranslateMessage and UpdateAllViews, and suggests that certain approaches, frequently taken by people writing their first, or first complex, MFC program, are probably wrong. |
|
One of the problems of using PostMessage is that if you are in a situation where you have a lot of messages being generated, you can in effect shut down the GUI because of the backlog of messages that appears in the input queue. This technique shows how to use an I/O completion port combined with an OnIdle handler to keep your GUI responsive. |
|
This is some supplementary material on memory allocators; the "sausage" aspects of some of the issues of my Memory Damage Primer ("like sausage and laws, you're better off not knowing what goes on [inside a storage allocator]") That's fine for beginners, but after a while you begin to realize that what goes on inside a memory allocator can matter, and for those who care, this discusses some of the issues of memory allocation. |
![]()
KB103788: Creating
Modeless Dialog Boxes done right The Microsoft article on creating modeless dialog boxes is confusing, misleading, and incomplete. It suggests unnecessary steps, such as overriding the Create method, the actual Create method is poorly written, the invocation of the Create method is poorly done, it fails to handle errors properly, it does not show how to avoid multiple instances, and it does not handle all of the destruction of the modeless dialog correctly. |
|
Over the years, I've noticed a lot of beginners are clueless about getting assertion failures in the heap routines in debug mode. Some even believe that they shouldn't use debug mode "because it has too many errors" (oh, someone just put me out of my misery now!) But even experienced programmers are sometimes at a loss when it comes to really tracking down memory damage problem. This essay is both a primer for beginners and a set of techniques for the experienced programmer. |
|
The use of user-defined messages gives you additional power and control over your application, and provides an often convenient method for passing information between threads and applications. This essay goes into considerable depth on how to handle user-defined messages, inter-thread messages, and inter-process messages. |
In spite of the fact that I have reported numerous problems with the MSDN documentation over the years, many problems remain outstanding. I have finally given up and simply created this list of documentation errors and omissions. |
|
I've become really good at spotting major failures in Windows programs just by finding certain key blunders that programmers seem to make consistently. Some errors are so deep and fundamental that nothing short of a rewrite can solve the problem. Others lead to code that is eventually unmaintainable. Many are style issues dealing with modularity, a concept that seems foreign to all too many programmers. And some are just style problems I've found that create programs that are hard to write, debug, and/or maintain. There's something in this essay to outrage everyone! |
|
Optimizing a program before you know where the time is going is a meaningless activity. It wastes your time, produces code that is harder to write, harder to debug, and harder to maintain, than unoptimized code. This essay discusses some of the issues of why you should not do pre-optimization. |
Process
Management Some techniques for managing processes in a program. Oriented to MFC programmers, since it includes MFC examples and defines a class for asynchronous process completion notification. The essay has an accompanying set of code which is the notification class and an example application. |
|
Feeling out of sorts? Want some order in your life? Or in your controls, or in your data structures? This essay talks about some issues about how to sort arrays, CArray, CList, CComboBox, CListBox, and CListCtrl. |
Subclassing
Dialogs and Property Pages Often when creating a set of dialogs or property pages, you find that they share a lot of common controls and actions. It would be natural to subclass these, but ClassWizard does not help you in any way in this. However, it is fairly easy to do by hand. This essay explains how to subclass a dialog or property page. |
|
OK, you've built the project, debugged it, and you're ready to ship. You compile the Release version of the program, and your world crumbles to dust. You see errors that you never imagined. In code that was completely debugged! You think "#$%@! optimizer bugs did me in!!!" You're probably wrong: your program wasn't correct in ways that didn't matter in the debug version, but really matter in the release version. Find out what can be wrong, and what you can do about it. |
|
You just set things up with a Sleep(10) and notice that the program does not wake up every 10 milliseconds. Or you did a SetTimer(..., 10, ...) and you're not getting the message or callback every 10ms. What's wrong? Well, welcome to the world of non-real-time operating systems. Very few general-purpose operating systems can support real-time constraints, and Windows is not a real-time operating system. Read this essay to find out what can go wrong. Then stop trying to do it, it won't work. |
![]() This essay shows some code that produces a printed tree from a CTreeCtrl. The third time I reused this code, I decided that it should be written up. |
The
Ultimate (DLL) Header File Creating a header file is usually simple. You declare the function prototype for each function and you're done. Well, not really; you may want to avoid multiple declarations, particularly if structures and typedefs are involved, so you conditionalize it. Well, that's not enough; you want to take advantage of the new compiler #pragma that avoids multiple file opens. But that's not enough, and the additional trick you need to deal with a DLL is addressed in this essay (with a cut-and-paste sample included!) |
|
This describes techniques for initializing properties of a window when it is used in a dialog. PreCreateWindow and OnCreate are inaccessible because the window is created long before the subclassing in the dialog happens, and PreSubclassWindow is a convenient place to do certain kinds of initialization. |
|
I discovered the utility of user-interface threads a few weeks ago. This essay captures what I learned. In particular, there are some interesting issues of thread initialization that are not readily addressed. This also discusses why a user-interface thread may have no GUI objects associated with it. |
|
This describes techniques for proper use of worker threads. It is based on several years' experience in programming multithreaded applications. |
Who
Owns the GUI? One of the critical design questions you confront as a programmer is "Who owns the GUI?" If you think you do, you're already in trouble. Read this to find out why. Includes a number of examples on how to avoid being trapped by the GUI assumptions. |
|
Secrets of doing Asynchronous I/O. Discusses various techniques such as waiting on an Event handle, using callback I/O, and using I/O Completion Ports. There is an accompanying program that illustrates how asynchronous disk I/O can generate requests in one order and receive the responses in a different order, with nice graphical displays of processing times and sequencing of events. In addition, the program illustrates a number of useful Windows programming techniques, and a separate essay on the Building of the Asynch Explorer demonstrates these various techniques. |
|
This is a code sample to accompany my essay on process management. It consists of a simple dialog-based application that can launch another application and have the GUI remain alive while the launched process runs, instead of just blocking and being non-responsive |
![]() ![]()
Asynchronous Socket Programming: KB192570 Done Right Microsoft has an example of doing MFC CAsyncSocket programming with one thread per connection. It is perhaps one of the single worst examples of threading that I have had the misfortune to see in many years. It is also poor MFC programming, poor socket programming, poor GUI programming, and in some cases just poor C/C++ programming. Other than the fact that nothing short of a total rewrite could save it, there's nothing wrong with the code. See how to do the job right. |
|
Need a button that repeats as you hold it down? Don't want to write it from CWnd from scratch? This subclasses CButton and creates an auto-repeat button. It isn't as simple as you might think. |
|
Would you like to have the VERSIONINFO build-number increment automatically on each build. I've looked at the existing solutions, and none of them really thrilled me. So I added to the plethora of tools with one of my own. |
|
Unhappy with the CBitmapButton because it requires too much work on your part to create all the images required, and all you really need is a regular pushbutton with an image instead of text? Here's your solution. Read the documentation, download the sample code. Want a button that toggles on-and-off each time you click the mouse? There's one included with this project as well. |
|
How do I read a bitmap file? How do I display a bitmap I've read from a file? How do I print a bitmap? Plus an assortment of dialog box programming tricks, ListBox programming tricks, and a few tricks that I've not been able to categorize (such as how to highlight a bitmap without actually taking complete control of drawing it!) |
|
This is a handy little class that that allows you to have a button with an arrow and optional text.
|
![]()
Changing Dialog
Box/CFormView Color How to successfully change the color of a dialog box, or a CFormView? Well, it is in theory easy, but there are some side effects you need to deal with, This essay shows how to handle the ones the author is aware of. |
|
Wonder about the mysteries of dynamic DLL loading? Using GetProcAddress? How to really resolve pointers? Well, this essay doesn't explain a lot of the details, but does wrap them up in a nice little class that greatly simplifies using a dynamically-loaded DLL. |
|
I needed a bedside clock that had readable digits. No big deal. I wrote one. Then I needed a little clock to be visible when I was doing PowerPoint presentations. So I adapted it. Then I wanted to play with the Localization APIs, and this was a good experimental testbed. So here it is, along with useful features such as a built-in RTF help facility, layered windows, and a lot of other cute programming tricks. It manages a lot of issues such as time zones without resetting the base machine time.
|
|
This started from a project to see about improving performance by making a particular algorithm be aware of the cache properties. To do this, I had to figure out how to find out what those cache parameters were. This program is the result of the need to understand the CPUID instruction, and the fact that I have had several transcontinental and one transatlantic trip in just a few weeks, and needed something to keep me occupied on the plane. It is a very fancy way to see the output of the CPUID instruction. |
|
I found myself in need of understanding exactly how CTime representations worked. Much to my dismay, I found that the base time is not January 1, 1970, 00:00 but in fact is December 31st, 1969, 19:00. I also got tired of playing with CTime::Format, so I added controls to test out formatting. I can copy the formatting string I develop out of the edit control in the CTime explorer, and paste it into my application. When I'm debugging, I often need to figure out what time is actually represented by a hex or decimal number, so I added the ability to copy a value from the debugger, paste it into the CTime explorer, and convert it to a time. Since this was useful, I'm putting its source and executable up here for you do download. |
|
In a large project with lots of CWnd-derived classes, it is sometimes difficult to track all the class relationships. The old, old Browse Info option of VS used to give a class map, albeit poorly drawn, and not available except on the screen and printer. This little utility derives the CWnd class information from the source files, and from the MFC source as an option, and allows the creation of a class map in visual form, text form, graphical metafile form, and printable form. |
|
Unhappy with the Zoomin utility? Want one that is more powerful, easy to use, and will help you do color matching? This is the project to use. Prompted by a question on doing color picking, it took a few hours to write this up. It illustrates topics as diverse as mouse capture, rubber-banding, screen capture, putting bitmaps in the clipboard, use of mapping modes, and a few other useful tricks. |
Controls
in the Status Bar A collection of controls designed to be placed on the status bar, including a progress control, a static control, and an edit control. This is a link to the CodeGuru site. |
![]() ![]()
Copying
ListBox Contents to the Clipboard Often, when I suggest that a ListBox is a better means of doing logging than an Edit control, I get the objection, "But I will need to do a copy to the clipboard! And you can't copy ListBox contents to the clipboard!" That is obviously not true, it just takes a few lines of code. This project demonstrates how to build a CListBoxEx class that supports copying to the clipboard. It also illustrates some useful debugging techniques, and is folded in as part of another essay on handling control rearrangement on a resizable dialog. |
|
Working with the WinINet classes such as CInternetSession? Need to convert an error code to a printable string for logging or presentation? This little code fragment shows how to catch a CInternetException and log it to a ListBox control. |
|
This is a program that illustrates that it is possible to create a 3-D-looking cylinder that can be rotated and viewed from different positions. It also illustrates the use of SetWorldTransform and transformation matrices. It illustrates the use of complex clipping regions, and how to create a clipping region that is based on a complex transformation matrix. What is interesting about this is that it draws using only the basic GDI functions, and if rotations are not desired, it does not even have to use the GM_ADVANCED mode!
|
|
Forget to put a shortcut (&-character) name on a dialog control? Have more than one control with the same shortcut? Find out using this handy dialog consistency checker, which can even be added to the VC++ Tools menu! |
|
Code sample: A dynamically self-adjusting combo box. This combo box will drop down (or up) in such a way as to minimize the need for a scroll bar. It will only introduce a scroll bar if the dropdown cannot fit between the control and the screen bottom or top. |
|
Fibers are a lightweigtht cooperative threading mechanism, or a coroutine mechanism, depending on how you look at them. Besides providing a very efficient thread-like implementation, fibers allow you to provide "continuations", that is, computations which perform some function, suspend themselves, and then resume where they left off. The fiber documentation is not always obvious, and appears to be erroneous in some places. This essay discusses some of the issues about fibers, and there is an accompanying code example. |
|
This essay came from a question about how to compute log2(n) where n is known to be a power of 2. Two algorithms were posed in the replies, one of which was a loop that shifted right until the value went to 0, and another was particularly horrible, using the formula log(n)/log(2), which is about the worst possible way to do the computation. This happened to correspond to some work I was doing in preparing a course on high-performance computing, so I wrote and measured several alternative algorithms. This essay is primarily an essay on the techniques for measuring performance, but also demonstrates a solution which is 200 times faster than the log(n)/log(2) solution, and between 4 and 88 times faster than the loop approach. |
|
This program allows you to play with the bitwise representation of floating-point numbers and see the effects of arithmetic operations, changes in representation, and output conversion formats. Every once in a while, some naive beginner believes that binary floating point should give the same representations as decimal arithmetic. Unfortunately, many of them cannot be convinced that reality is different from their delusional mathematical system. But this program tries its best to show that binary floating point representation is as precise as you are going to get. |
|
I needed to generate some gradient filled areas, and figuring out GradientFill was challenging. So I wrote a little program to help me understand it. I created a set of rectangular gradient fills, but didn't need triangular fills so did nothing about them. Recently, I resurrected the project, added triangular fills and several other features. Learn to use GradientFill, create gradient resources, grab gradient bitmaps, write gradient metafiles, and all kinds of fun things. |
|
I needed to generate regular timer events in a CDocument class. This is not as easy as you might think, because a WM_TIMER message won't get routed to a CDocument class. So I developed a technique to embed timer events in a CDocument.
|
![]()
I needed a way to validate the correctness of over a thousand HTML pages that were being generated by an automated system. The tidy library is a powerful library for doing HTML validation, but the "wrappers" that pretended to be useful were not very; they were designed to validate one file at a time, not many hundreds. My solution was to write a new "tidy" wrapper. The link on the left downloads the executable; the complete source is available, just click the "Read Me" link. |
|
This essay tries to clean up some of the confusion that seems to arise when using global hook functions. It includes a "cute" GUI interfacing to a global hook that watches the mouse. |
|
Have you tried to get a horizontal scrollbar on a ListBox and wondered why it didn't work? This essay explains the secrets of horizontal scrolling in listboxes and shows a subclass that handles this automatically for you! |
![]() An
Image Comparator Program Have you ever wondered what transformations a JPEG or GIF format does to your image? I recently had to prepare some lectures on this subject, so I wrote a program to help me generate some interesting slides for that purpose. |
Initializing
a Combo Box Code sample: A combo box loadable from the string table. Simplifies the issues of preloading a combo box. |
![]() Limiting
the Minimum and Maximum Sizes of a Resizable Dialog
A question which often comes up is "How can I limit the minimum size that a user can resize a dialog to?" The answer is very simple and easily made display-parameter-independent. This essay explains how to accomplish this. It also folds in two other projects, one of which is how to dynamically rearrange controls to follow the dialog resizing, and another, separate essay, on how to copy ListBox contents to the clipboard. |
![]() The
LoadLibrary Explorer
It can be confusing to figure out how LoadLibrary and LoadLibraryEx work. There are a variety of places in which the documentation appears, and piecing it together is a major effort. This essay brings together all the aspects of library loading and path management, and allows you to perform experiments. The understanding of LoadLibrary and LoadLibraryEx is confused by the fact that the documentation of the APIs is itself erroneous. |
![]() The
Locale Explorer The APIs for National Language Support and other localization aspects can be quite complex to use. It is also not obvious what they do in many cases. The Locale Explorer illustrates a large number of the NLS-related APIs, and furthermore generates code that can be copied from an edit control in the Locale Explorer and pasted into your application. |
|
Have you ever needed a slider control calibrated logarithmically instead of linearly? This little project shows a log-calibrated control with one decade of representation, and the generalization I hope is obvious. |
|
One of the most powerful tools I have is a CListBox-derived class that I use as my output log. It provides for fancy formatting, colors, saving to a file, logging to a file, copy, cut, paste and printing. This code also contains a number of really cool examples of MFC techniques. |
|
This project lets you see what all the MessageBox calls do, and what effects their options produce. It also generates the necessary code to support AfxMessageBox, CWnd::MessageBox, ::MessageBox, and ::MessageBoxIndirect calls, which can be copied to the clipboard and pasted into any application. |
![]() The
MetaFile Explorer This project lets you examine the contents of a Windows Metafile (.wmf) or Enhanced Metafile (.emf). It will also convert a .wmf file to a .emf file (although at the moment there appear to be interesting problems with coordinate transformations--suggestions for how this can be fixed would be appreciated) |
|
This project contains a class Process that allows you to spawn a child process and capture its output for display. The sample project does this using a simple list box for logging the output. |
An
MFC Interface to ::FormatMessage This essay shows an interface that allows the ::FormatMessage API to be easily accessed from MFC. The code is so small it can by copied and pasted directly from this Web page. |
|
This control provides for many of the simple accesses, and includes methods for testing that the contents are blank, and methods for specifying a string conversion format. No, it is not a general-purpose masked edit control. But it is a quick-and-easy implementation of a set of useful methods. |