MVP Tips, Techniques, and Goodies |
|
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. If you find the code useful, that's cool, too.
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)
Converting a CDialog to a CFormView (19-Oct-08)
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)
Indexed Information: Creation and Lookup (20-Jun-11)
Inside Memory Allocation (21-Aug-06)
Inside A Storage Allocator (18-Apr-09)
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)
Managing fonts in a CView- and CWnd-derived classes (27-Jul-11)
Memory Damage Primer (18-Aug-06)
MSDN Documentation Errors and Omissions (15-Dec-07)
Mythology in C++: Exceptions are expensive (21-Apr-11)
Mythology in C/C++: Shift by more than one bit is expensive (21-Apr-11)
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)
Adding a View to a Document (link created 17-Aug-09)
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)
The Character Functions Program (14-Jul-08)
A Checksum Algorithm (3-Feb-01)
ComboBox/ListBox Explorer (14-Dec-08)
Computing the Multiplicative Inverse for Optimizing Integer Divide (30-Sep-10)
Converting a CInternetException to a printable string (14-Mar-02)
Copying ListBox Contents to the Clipboard (1-Sep-06)
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 Font Explorer (5-Nov-08)
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)
The HTMLEditView done right (14-Jul-08)
An HTML validator (20-Oct-04)
Inside A Storage Allocator (18-Apr-09)
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 NUMA Explorer (10-Apr-09)
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, 29-Dec-09)
A PowerPoint Sequence Generator (23-Jul-08)
The PolyDraw Explorer (10-Feb-08)
Polygon Transformations (15-Sep-01)
Printing Bitmaps (8-Jan-03)
The QueryDosDevice Explorer (24-Nov-08)
Rearranging Controls on a Dynamically Resizable Window (1-Sep-06, revised 17-Jun-11)
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)
VirtualAllocExNuma (4-Apr-09)
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 Bitmap File 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
ComboBox/ListBox Explorer (14-Dec-08)
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)
Managing fonts in a CView- and CWnd-derived classes (27-Jul-11)
The MessageBox Explorer (9-Apr-07)
Rearranging Controls on a Dynamically Resizable Window (1-Sep-06, revised 17-Jun-11)
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
ComboBox/ListBox Explorer (14-Dec-08)
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)
Managing fonts in a CView- and CWnd-derived classes (27-Jul-11)
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)
Managing fonts in a CView- and CWnd-derived classes (27-Jul-11)
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)
Mythology in C++: Exceptions are expensive (21-Apr-11)
Mythology in C/C++: Shift by more than one bit is expensive (21-Apr-11)
Avoiding EN_CHANGE notifications (17-Aug-06)
An Introduction to Messages (21-Oct-01)
I/O Completion Ports and Cross-Thread Messaging (21-Nov-03, Revised 1-Apr-06)
An Alternative Spin Lock Implementation 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. |
A Bug in the _CrtMemCheckpoint function 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). Or generate your own using the Character Functions Program. |
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 CCriticalSection The 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 notifications Handling 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. |
Computing
the Multiplicative Inverse for Optimizing Integer Division A trick used by the Microsoft C/C++ compiler to optimize integer division is to convert it to either a shift (if a power of 2) or a multiplication (a 32x32 bit multiplication by the right value produces the quotient of the division in the high-order 32 bits! Really!). If you want to reverse-engineer code, you need to recognize the optimization pattern, and if you want to optimize the inner loop of some intense computation when the divisor is not a compile-time-constant, the code for doing this computation is included. |
Converting
a CDialog to a CFormView
Every once in a while, you will create a class, put down a ton of controls, and realize that whoops, this should have been a CFormView, not a CDialog. By this time, you have added variables, handlers, etc. and it is really painful to have to re-create the class. This article gives the simple hand-edits that will allow you to convert the existing CDialog class to a CFormView. |
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. |
The Graphical Developer Interface 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. |
Inside
a Storage Allocator This is an introduction to how a storage allocator works internally. I find myself answering the same questions over and over, which indicate that there is very little true understanding about storage allocators out there in the world. This article attempts to remedy that by showing an allocator in less than 100 executable lines of code. It's not a very good allocator, but it demonstrates all the principles on which storage allocators are based. It comes with the Storage Allocation Explorer, which allows you to see "animations" of the way storage is managed inside the allocator. |
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. |
I/O Completion Ports and Cross-Thread Messaging 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. |
Indexed Information: Creation and Lookup One common problem in choosing the representation of indexed information in memory is the issue of what the appropriate representation should be, for example, an array, linked list, or balanced tree. There are a number of classical arguments against using an array, which I show are often fallacious. But when a linked list is proposed, there are often some suggested optimizations for accessing data quickly in linked lists, which are qualified by comments about how expensive such techniques would be to keep consistent with the list contents. I also dispel these myths. The key to all of this is fundamental understandings of performance issues, why big-O notation is misleading, and why partially-correct information ("hints") are often effective enough. |
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. |
Managing fonts in a CView- or CWnd-derived class One of the odd experiences you can have in creating your own views and controls is that you will call SetFont or GetFont, but no matter what you set in SetFont, the GetFont returns NULL? Where did that font go? You didn't get a compilation error, or even a runtime error on the SetFont, but your program (usually) fails horribly when the GetFont returns NULL, usually with an access fault (0xC0000005) on some location near 0. This essay explains what you have to do to get correct behavior with your font management. |
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. |
Mythology in C++: Exceptions are Expensive There are a number of Urban Legends in C and C++. One of the sillier ones I have seen is advice to avoid exceptions "because they are expensive". This essay demonstrates, with hard performance data (not claiming the authority of repetition of myth) that exceptions are remarkably cheap, and for all practical purposes, free. |
Mythology in C/C++: Shifts are Expensive There are a number of Urban Legends in C and C++. One which I've seen repeated numerous times in various Web sites is the foolish assertion that "shifting by a non-constant amount or more than one bit is expensive, and should be avoided." This myth is apparently based on the performance of the 4.77MHz 8-bit 8088 architecture. It has no relevance to modern Pentium and AMD processors. They are 32-bit or 64-bit pipelined superscalar architectures with clock speeds typically exceeding 2GHz. |
The n Habits of Highly Defective Windows Programs 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! |
Optimization: Your Worst Enemy 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. |
This is a piece of my MSDN Errors and Omissions essay, which gives the formulaic code for adding a new view to a document. The Microsoft example sucks, and in any case handles only the bizarre case of trying to show multiple views in SDI, which is uncommon.
|
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. |
Asynchronous Process Notification 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. |
An automatic Build Number Incrementer 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. |
A Better Bitmap Button Class and a Toggle Button Class 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. |
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. |
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. |
The Character Functions Program/HTMLEditView rewrite Want to see that the character functions do in various locales? Use the Character Functions program. Not only is this a useful program for showing the character functions, but it is a massive rewrite of the incredibly-poorly-written HTMLEditView program example from the MSDN.
|
A Class for Dynamic DLL Loading 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.
|
The
ComboBox/ListBox Explorer This is a simple little test program that illustrates the effects of WM_MEASUREITEM, WM_COMPAREITEM, WM_DRAWITEM and WM_DELETEITEM, and was used to discover several serious bugs in the documentation and implementation of WM_DELETEITEM.
|
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. |
Converting a CInternetException to a printable string 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 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. |
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!
|
A Dialog Shortcut Consistency Checker 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! |
A Dynamically-Resized Combo Box 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. |
A very extensive update to the original Font Explorer I designed for Win32 Programming. This has been upgraded from VS4.2 to VS2005, completely rearranged internally, and has many new features. Explore how the LOGFONT structure works; explore how the CFontDialog (or ChooseFont) dialog works; look at the effects of font rotation; study how rasterization works.
|
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. |
Getting Timer Events in a CDocument-derived class 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. |
A Horizontal-Scrolling ListBox Class 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 is a useful little example that demonstrates how OpenMP can split a task among multiple threads.
|
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. |
This is a useful little example that demonstrates how OpenMP can split a task among multiple threads.
|
Owner-Draw Control Example: RGB Color Table This is a useful little example that creates an RGB Color Table for use in a C/C++ application. It also illustrates an owner-draw ComboBox, an owner-draw ListBox, two owner-draw buttons (see the companion essay on "A Better Bitmap Button") and a simple example of subclassing a CStatic to show a color block. Many other techniques from other of my essays are also illustrated. |
In writing my MetaFile Explorer, I needed a test case to show the use of the EMR_POLYDRAW and EMR_POLYDRAW16 records, whose documentation is simply erroneous. I wrote this program to show the use of the PolyDraw API and generate a metafile which I could then reverse-engineer to prove that my interpretation of what was the correct documentation was correct.
|
One of the frequent complaints I get about my two courses is that there is no index for the thick manual. I needed a way to create an interactive index the students could use during class, and take it with them. So I wrote this little tool to help me. This is a rather simple project, having occupied only about four days, so it is not yet a completed work; as I use it more, I'll probably be adding more features. |
A PowerPoint Web Page Sequence Generator I wanted to generate a sequence of HTML pages that represented a PowerPoint presentation, that could run on any target platform even if PowerPoint and the PowerPoint Viewer were not installed. This program creates a series of Web pages around the .png files that PowerPoint writes out. |
Want to rotate a polygon without actually going the whole way to OpenGL or DirectDraw? Here's a little class I did that does simple polygon rotations, computes bounding boxes, and other useful features. It draws the rotating pointer in a little compass control, but can be applied to any polygonal form. |
A frequent question on the newsgroup is "how do I print a bitmap?" This code sample covers bitmap printing and also capturing a screen image with the cursor image as well (which is, strictly speaking, not possible). The actual printing code comes directly from the Microsoft DIBSHOW example code. The cursor capture code is my own. |
A frequent problem that arises in many applications is writing a collection of data lines to a printer. Often the MFC Document/View printing mechanism is unsuitable; in other cases it is simply unavailable. This essay has a class that simplifies doing a line-printer simulation. |
There is an API, QueryDosDevice, that reveals interesting information about symbolic names of devices. This little program lets you see what it does.
|
Rearranging Controls on Resizing A frequent problem that arises when you have a resizable dialog is how to manipulate the controls so that they will take advantage of expanded window space. This essay, which is really three essays in one, shows how to manage control layout when you don't have a lot of controls to manipulate and therefore don't need the heavy-duty effort of a layout management library.. |
Using the Registry is more complex than it really needs to be for simple tasks. You can avoid this by using GetPrivateProfileInt or WritePrivateProfileString and similar legacy interfaces, but they deny you much of the power of the Registry. The classes defined here simplify the interfaces for simple data types, and a rich library allows you to store and retrieve font, window placement, int64, GUIDs, and arrays of DWORDs easily. |
Rearranging
Controls Dynamically When a dynamically-resizable dialog is created, you may find it desirable to have controls resize or rearrange themselves dynamically in response to these changes. This project shows some simple techniques to use when the arrangements are not too complex. In also incorporates two other projects, the ability to copy ListBox contents to the clipboard, and limiting the minimum (or maximum) size that a window can be resized to. |
Screen
Capture to Clipboard This is a very simple subroutine that fits on a single HTML page and illustrates a technique for capturing the bitmap of an arbitrary window, and then shows how to save it to the clipboard. |
A Self-Registering Window Class Need a custom window class, for example, in a dialog, and want it to automatically register so you don't have to tell the clients how to register it? This outlines a technique for accomplishing this without additional effort on the part of the clients, and includes a sample control, a small compass control. It also does rotational transformations of a polygon, and detects mouse clicks inside a control defined by an arbitrary region. |
Programming a serial port seems to be a black art. There is a lot of really bad code out there which tries to do it. The first thing to do is forget that SetCommEvent and WaitCommEvent ever existed. Use asynchronous I/O and create reader and writer threads. Do not use an Event to signal that something is ready; use an actual queue to avoid race conditions and lost data. See actual code here. |
SHGetFolderPath is used to locate various shell-style directories (which aren't really directories, but fake virtual directories created by the shell). It also replaces such API calls as GetWindowsDirectory and GetSystemDirectory. This Explorer lets you see what the actual paths are for each of the CSIDL_ options, and generates the necessary code to access the desired directory name; |
The
Thread Affinity Explorer When a dynamically-resizable dialog is created, you may find it desirable to have controls resize or rearrange themselves dynamically in response to these changes. This project shows some simple techniques to use when the arrangements are not too complex. In also incorporates two other projects, the ability to copy ListBox contents to the clipboard, and limiting the minimum (or maximum) size that a window can be resized to. |
Threads
and Pipes in Console Apps This describes how to use threads and anonymous pipes in a console app. |
The
ToString
Function When I found myself writing too many temporary variables just so I could call FormatMessage, I got rid of the idea of having to create temporary variables to hold strings just so I could print into them. The result was my ToString function, a function so simple it doesn't even need a download. |
FormatMessage is a very useful API for reporting error messages from ::GetLastError() in a meaningful way to the user, or to the tech support person at your company the user calls. This essay gives a quick overview and includes a code download for a function called ErrorString which I use for this purpose. |
Confused about what a "semaphore" is and/or how to use one? This essay contains the entire code for an interlocked multithreaded queue to be used by one or more producer threads and one or more consumer threads. The accompanying demo code shows a single producer and two consumers. |
Bored by rectangular windows? Want to create windows with weird and wondrous shapes? Custom-shaped buttons? Here's a little essay that creates a window in the shape of a Gray Cat, and buttons in the shapes of letters, popup windows that follow their parent window around, and a lot of other useful techniques. This is a study of how a simple specification was turned into working code. |
Messaging is a convenient method of sending data between two processes. However, user-defined messages can only pass, at most, 64 bits of information. Sometimes this is just too little information. WM_COPYDATA allows you to send more than 64 bits, in fact, an arbitrary amount of data. But it is not without risk. Read how I got caught by someone misusing it, and how I now make my WM_COPYDATA transfers safe and robust. |
UTF-8 encodings for data exchange One of the common questions that comes up is how to represent Unicode data in files and for transmission. This essay talks about how to write code that transforms UTF-16 (Unicode) encoding to UTF-8 encoding, and shows some code that can be copied to your app. |
Have you ever wanted a control that only accepted valid values and gave feedback to the user? I consider DDV to be so primitive as to be utterly useless, and prefer more powerful interaction methods. This is a little project that illustrates the techniques for building a validating edit control. This particular edit control parses floating point numbers. The FSM recognizer can be replaced by something of your choice, including sophisticated validation algorithms of your own. |
I had an application that required a couple dozen small, scalable, rotatable icons. This meant that a bitmap representation was not exactly ideal, so I chose a vector representation. After struggling for about 20 minutes to get a simple shape looking good, I wrote a small editor to edit sets of points. These can be used as resources in my Polygon class. |
The
Viewport Explorer
This came about because I found what I thought was a typo in a document describing the coordinate systems. The author insisted that the text was correct. To demonstrate it was wrong, I wrote a little program that shows what really happens in coordinate transformations. Since it was an interesting program, I spent a few hours enhancing it so it now illustrates a number of GDI features, illustrates the use of mapping modes, shows how to do dragging using logical coordinates, shows coordinate reversal, and other neat features. |
VirtualAllocExNuma
example
This cam about because I wanted to play with the VirtualAllocExNuma API, and the code example that showed how to use it had been written by someone relatively inexperienced, who made a number of beginner programming blunders. I had to rewrite it to Best Practice. |
Virtual
Screen Coordinates
When you have to deal with modern multi-monitor arrangements, you need to deal with virtual screen coordinates. This essay shows some code that allows you to manipulate windows within the virtual coordinate space. |
A
whereis utility
The Unix whereis utility simulates a search along the Unix search paths to locate a specified executable. The problem with Windows is that various releases of Windows and various service packs implement different search algorithms. In addition, there are other executable image types besides .exe, such as .dll, .ocx, .sys and .com files. This program uses the current search path and current search algorithm to locate the executable image. It does not make the common mistake of searching the path manually. |
PKZIP Registered Version The folks at PKWARE have made a significant contribution to the state-of-the-art for all of us by their shareware distribution of PKZIP. Alas for them, I've moved on. |
WINZIP Registered Version The PKZIP product seems to have stalled; I now use WinZip. While I liked PKZIP for years, since the death of their founder they have, in my estimation, slipped behind the state-of-the-art. I have found their product harder and harder to be comfortable with. So I'm now recommending WinZip. I held out as long as I could. Now that I use WinZip, I find that I like it a lot more than PKZIP. Sorry, PKZIP, but I just don't love you any more. These folks have a shareware version which anyone can get free, but I believe that a product like this should be supported by those who can afford it. (I have a 10-node site license, for example). |
Count |
Date |
Description |
38 | 21-Dec-99 | Started maintaining change log |
39 | 21-Dec-99 | Added essay on A Better Bitmap Button Class |
40 | 23-Dec-99 | Added essay on A Dialog Shortcut Consistency Checker |
28-Dec-99 | Revised essay on A Better Bitmap Button Class | |
41 | 28-Dec-99 | Added essay on A Toggle Button Class |
28-Jan-00 | Revised essay on Using Worker Threads | |
4-Feb-00 | Revised essay on A Dialog Shortcut Consistency Checker | |
4-Mar-00 | Revised the article on Avoiding Multiple Application Instances | |
42 | 13-Mar-00 | Added essay on An automatic build-number incrementer |
43 | 5-May-00 | Added essay on The CTime Explorer |
44 | 24-May-00 | Added essay on Dialog Boxes in Console Apps |
45 | 21-Jun-00 | Added a Handy Guide to Handling Handles |
46 | 12-Jul-00 | Added a discussion of "How Big is my Program?" |
47 | 19-Oct-00 | Added essay on The Ultimate (DLL) Header File |
48 | 30-Oct-00 | Added essay on A Validating Edit Control |
20-Jan-01 | Revised essay on Using Worker Threads | |
49 | 3-Feb-01 | Added a Checksum Algorithm |
50 | 7-Feb-01 | Added essay on A Registry Class and Library |
51 | 8-Feb-01 | Added essay on CString techniques |
52 | 19-Feb-01 | Added a class for saving DCs |
24-Feb-01 | Revised essay on CString techniques | |
53 | 11-Mar-01 | Added essay on A Horizontal-Scrolling ListBox Class |
54 | 13-Mar-01 | Added essay on Hooks and DLLs |
10-Apr-01 | Revised essay on Using Worker Threads | |
55 | 8-May-01 | Added ASCII-to-EBCDIC tables |
56 | 14-Jun-01 | Added essay on Using Semaphores |
22-Jun-01 | Revised a Handy Guide to Handling Handles | |
57 | 10-Jul-01 | Added essay on Generating GUIDs programmatically |
58 | 1-Sep-01 | Added essay on An MFC Process Class |
59 | 15-Sep-01 | Added essay on Polygon Transformations |
60 | 15-Oct-01 | Added essay on Dialog-Based Applications |
61 | 15-Oct-01 | Added essay on A Self-Registering Window Class |
62 | 16-Oct-01 | Added essay on A Vector Editor |
63 | 18-Oct-01 | Added essay on Getting Timer Events in a CDocument class |
64 | 21-Oct-01 | Added essay on an Introduction to Messaging |
65 | 22-Oct-01 | Added essay on An Auto-Repeat Button |
66 | 25-Nov-01 | Added a class and macros for doing Dynamic DLL Loading |
67 | 12-Jan-02 | Added essay on Owner-Draw Controls: A Color Table Generator |
68 | 14-Mar-02 | Added essay on Converting a CInternetException to a printable string |
69 |
8-Jan-03 |
Added the bitmap file explorer |
70 | 8-Jan-03 |
Added the bitmap printing example |
71 | 8-Jan-03 |
Added the more elaborate screen capture program |
72 | 8-Jan-03 |
Added more material to the Handy Guide to Handling Handles |
8-Jan-03 | Revised essay on Dialog Boxes in Console Apps | |
73 | 10-Jan-03 |
Added the essay The n Habits of Highly Defective Windows Programs |
74 | 18-Mar-03 |
Added the C# entries, including the C# HP16C calculator |
75 | 04-Jul-03 |
Added an entry for CAsyncSocket |
76 | 04-Jul-03 |
Added an essay on sorting |
20-Nov-03 | Added a discussion of an Alternate Spin-Lock Implementation | |
77 | 20-Nov-03 |
Added an essay on using I/O Completion Ports for interthread messaging |
78 | 21-Nov-03 |
Added a Logarithmic Slider Control |
79 | 16-May-04 |
Added an essay on using SetWindowRgn |
80 | 20-Oct-04 |
Added the HTML validator |
81 | 13-Jun-05 |
Added the Better Zoomin utility |
3-Jul-05 | Revised essay on A Registry Class and Library | |
82 | 8-Jul-05 |
Added the Viewport Explorer |
5-Mar-06 |
Updated the Dialog Based Application essay |
|
83 | 7-Mar-06 |
Added the Asynchronous I/O Explorer |
84 | 7-Mar-06 |
A whereis utility |
85 | 21-Mar-06 |
Added clock project |
86 | 1-Apr-06 | Revised the essay on I/O Completion Ports to cover Dialog-based apps |
87 | 1-May-06 | Added the essay on fibers |
88 | 7-May-06 | Added the LoadLibrary Explorer |
89 | 14-Jun-06 | Added an essay on programming serial ports |
90 | 17-Aug-06 | Fixed some bugs in the Serial Port examples |
91 | 17-Aug-06 | Added an essay on Avoiding EN_CHANGE notifications |
92 | 17-Aug-06 | Added an essay on Using ::FormatMessage within MFC |
93 | 18-Aug-06 | Added the Memory Damge Primer |
94 | 21-Aug-06 |
Added a discussion of Memory Allocation |
96 | 1-Sep-06 | Added the Limiting Dialog Box Resizing essay which also includes the Control Rearrangement subproject |
97 | 1-Sep-06 | Added an essay on copying the contents of ListBox to the clipboard |
98 | 1-Sep-06 | Added a reference to a shared essay, on Rearranging Controls on a Dynamically Resizable Window |
99 | 2-Sep-06 | Added essay speculating on what might have happened If Theordore Seuss Geissel had been an MFC Programmer |
100 | 2-Sep-06 | Added essay on Building under both VS.NET 2003 and VS.NET 2005 |
101 | 29-Dec-06 | Added The SHGetFolderPath Explorer |
29-Dec-06 | Added some updates to the UTF-8 section of the CString essay | |
102 | 14-Feb-07 | Added the _CrtMemCheckpoint bug description |
103 | 10-Mar-07 | Added the CPUID Explorer |
104 | 19-Mar-07 | Added the CWnd Class Mapper Utility |
105 | 4-Apr-07 | Added an article correcting the massive deficiencies in KB192570, on CAsyncSocket programming with multiple threads |
106 | 9-Apr-07 | Added The MessageBox Explorer |
107 | 9-Apr-07 | Added The Thread Affinity Explorer |
108 | 18-May-07 | Added A Fast log2(n) function essay |
109 | 30-May-07 | Added A Tree Printing Algorithm |
110 | 4-Jun-07 | Added The Floating Point Explorer |
111 | 5-Jun-07 | Added The Best Synchronization is No Synchronization |
112 | 18-Jun-07 | Added A Button with an Arrow |
113 | 10-Jul-07 | The ToString Function |
114 | 22-Jul-07 | Added the essay on Virtual Screen Coordinates (it had actually been uploaded on 31-May-06, but didn't have a link on this page or have a download link) |
115 | 31-Aug-07 | Added the PowerPoint Indexer project |
116 | 18-Sep-07 | Added essay on Changing Dialog Box Color |
117 | 25-Sep-07 | Added essay "Inside the PowerPoint Indexer" which talks about implementation details |
118 | 18-Nov-07 | Added essay "Threads and Pipes in Console Apps" |
119 | 16-Dec-07 | Added a list of MSDN Documentation Errors and Omissions |
120 | 16-Dec-07 | Enhanced my discussion of UTF-8 encodings for data exchange in what was already a separate page, and created a separate link to it. |
4-Jan-08 | Enhanced my Color Table Generator to read color tables from GIF and BMP files. | |
6-Jan-08 | Updated the PowerPoint Indexer to version 2.0.0.87, and the accompanying essay on Inside the PowerPoint Indexer | |
121 | 8-Jan-08 | Added an Image Comparator program |
122 | 22-Jan-07 | Added an essay on The GradientFill Explorer |
123 | 22-Jan-07 | Added an essay describing the internals of The GradientFill Explorer |
25-Jan-08 | Added hyperlinks to the serial port essay to explain the shutdown event. | |
124 | 10-Feb-08 | Added the MetaFile Explorer |
125 | 10-Feb-08 | Added the PolyDraw Explorer (so I could test the MetaFile Explorer) |
10-Feb-08 | Added a version of The GradientFill Explorer that can write a metafile (so I could test the MetaFile Explorer) | |
10-Feb-08 | Created a new category, the "GDI Series", as another way of locating essays. | |
10-Feb-08 | Rearranged the items to make them a little better alphabetically ordered | |
126 | 19-Feb-08 | Added a rewrite of KB103788. |
127 | 26-Mar-08 | Added an article on A Cylinder Drawing Class |
128 | 23-Jun-08 | Added the OpenMP Explorer |
129 | 24-Jun-08 | Added an article explained why CMutex, CSemaphore, CEvent and CCriticalSection must never be used for any purpose whatsoever. |
130 | 28-Jun-08 | Added an essay and comparison table for the Character Functions in both the C library and the Windows API |
131 | 14-Jul-08 | Added The Character Functions Program, which is also a rewrite of the incredibly-poorly-written HTLMEditView example from the MSDN. |
132 | 23-Jul-08 | Added A PowerPoint Sequence Generator program |
Added some additional information to The Character Functions Program essay | ||
Fixed several incorrect links (thanks, Les) | ||
133 | 19-Oct-08 | Added an essay on Converting a CDialog to a CFormView |
134 | 5-Nov-08 | Released a new, vastly improved version of The Font Explorer from the Win32 Programming book. |
135 | 24-Nov-08 | Released the The QueryDosDevice Explorer |
136 | 14-Dec-08 | Released the ComboBox/ListBox Explorer |
137 | 4-Apr-09 | Rewrite of Microsoft's poorly-written VirtualAllocExNuma example. |
138 | 10-Apr-09 | Added The NUMA Explorer |
139 | 18-Apr-09 | Added Inside A Storage Allocator |
17-Aug-09 | Created a link to the technique for adding a view to a document | |
140 | 30-Sep-10 | Added an essay Computing the Multiplicative Inverse for Optimizing Integer Divide |
141 | 21-Apr-11 | Added an essay on the cost of exceptions, and created a new "MythBusters" category. |
142 | Added an essay on shift time mythology | |
17-Jun-11 | Massive cleanup of internal links; apparently FrontPage has been adding entropy for years! | |
143 | 20-Jun-11 | Added an article on Indexed Information: Creation and Lookup |
144 | 27-Jul-11 | Added an article on Managing fonts in a CView- and CWnd-derived classes |