Holy cow, I wrote a book!
In the history of Windows, there have been four versions of
dialog templates. And despite the changes, you'll see that
they're basically all the same.
My secret goal in this six-part series
is to address questions people have had along the lines of
"I'm trying to generate a dialog template in code, and it's
not working. What am I doing wrong?"
As it turns out, that you can get the resource compiler to tell you
what you're doing wrong. Take the template that you're trying
to generate, create an *.rc file for it and run it through
the resource compiler. Attach the resource to a dummy program
and dump the bytes! Compare the compiler-generated template
against the one you generated. Look for the difference.
In other words: To see what you're doing wrong, take somebody
who does it right and compare. Clearly there's a difference
somewhere. It's just bytes.
Anyway, enough of the rant against laziness. The next several
days will cover the evolution of the dialog template, with
annotated byte dumps for people who are trying to figure out
why their dialog template isn't working.
Non-geeks may want to go into hibernation for a while,
since this will take over a week to play out.
I'll try to keep you amused with the non-technical
Last year there was
a recall of exploding frying pans.
For some reason I found this funny.
"The pans can explode or separate when preheated,
used on high heat or used for frying,"
the safety commission said in a statement.
It explodes when you
fry something in it.
Apparently "frying stuff" was not in the test plan for the frying pans.
If you want to re-check that the files on your system
haven't been tampered with, you can run
(by typing its name into the Start.Run dialog)
and tell it to start scanning.
(UI note: If you go into the Logging page on the Advanced dialog,
you can get trapped where it insists on having a valid
log file name even if you didn't ask for logging!)
The signature verification process takes a while, so go and
do something else while you're waiting. When it's done, you'll
get a list of all the system files that are not digitally
signed by Microsoft. Just because a file is listed here
doesn't mean that it's necessarily bad, however.
For example, it might be a video driver or printer driver.
(Another UI note: You can't right-click the items in the list
to view their properties, say, to see what company issued the files.)
One case when you would want to run sigverif is after you remove
the test root certificate
which was causing your desktop to say "for test/evaluation purposes
That way you can find all the uncertified drivers that snuck in
under cover of the test signature.
It's often fun to go back and see
the kooky ideas for television shows that floated around years ago.
Here are some from 1997:
Plenty more on the linked web site.
What's really scary is that a lot of these kooky ideas
turned into actual television programs!
Once your average GUI program picks itself up off the ground,
control begins at your
The second parameter, hPrevInstance, is always zero in Win32 programs.
Certainly it had a meaning at some point?
Of course it did.
In 16-bit Windows there was a function called
GetInstanceData. This function took an HINSTANCE, a pointer, and a length,
and copied memory from that instance into your current instance.
(It's sort of the 16-bit equivalent to
ReadProcessMemory, with the restriction that the second and
third parameters had to be the same.)
(Since 16-bit Windows had a common address space,
the GetInstanceData function was really nothing more than a hmemcpy,
and many programs relied on this and just used raw hmemcpy instead
of using the documented API.
Win16 was actually designed with the possibility of imposing separate
address spaces in a future version
- observe flags like GMEM_SHARED - but the prevalence
of tricks like hmemcpy'ing your previous instance reduced this potential
to an unrealized dream.)
This was the reason for the hPrevInstance parameter to WinMain.
If hPrevInstance was non-NULL, then it was the instance handle
of a copy of the program that is already running. You can use
GetInstanceData to copy data from it, get yourself up off the ground
faster. For example, you might want to copy the main window handle
out of the previous instance so you could communicate with it.
Whether hPrevInstance was NULL or not told you whether you were the
first copy of the program. Under 16-bit Windows, only the first
instance of a program registered its classes;
second and subsequent instances continued to use the classes that
were registered by the first instance. (Indeed, if they tried,
the registration would fail since the class already existed.)
Therefore, all 16-bit Windows programs skipped over class
registration if hPrevInstance was non-NULL.
The people who designed Win32 found themselves in a bit of a fix
when it came time to port WinMain: What to pass for hPrevInstance?
The whole module/instance thing didn't exist in Win32, after all,
and separate address spaces meant that programs that skipped over
reinitialization in the second instance would no longer work.
So Win32 always passes NULL, making all programs believe that they
are the first one.
And amazingly, it actually worked.
It appears that
beverage preferences are a matter of national security.
The web site offers the original and redacted versions of the same
document, so you can see what sorts of information the U.S. government
considers to be worthy of redaction.
On a related redactorial note,
researchers demonstrated last month a technique for
identifying blacked-out words and phrases in confidential
On a related Pinochet note:
In the United States, it has become common for grocery stores to offer
"loyalty cards", which offer discounts on selected goods in
exchange for the store being able to track every single item you
Everybody hates these cards but uses them anyway because the
non-card prices are often absurd.
What people often did when signing up for the cards was to provide
My card is in the name of
former Chilean dictator
"Augusto U. Pinochet".
It turns out that this particular grocery chain has a policy that
all cashier must thank the customer by name
at the conclusion of the transaction. So after I pay for my
groceries, the cashier says, "Thank you, Mr. Pinochet."
Except that it turns out that "Pinochet" is
hard to pronounce.
(Consensus on this continues to be hard to achieve.
Many others claim the correct pronunciation is
I use that pronunciation, too, myself, for no good reason.)
I've been called "Mr. Peanut-Chew",
"Mr. P'Notch-et", and "Mr... how do you pronounce that?"
(To which I say, "Pee-no-chet. It's a Chilean name."
And the cashier says, "Ooh, that's very interesting.")
Only one person even recognized the name as that of the man
under whose brutal rule thousands of people simply "disappeared".
(I never actually expected the fake name to go through.
I assumed that somebody would have recognized
it and deleted it from the system. But no, the entry remains.
Occasionally, when Pinochet makes international headlines,
I consider the possibility
that some people may show up at my house looking for him.)
Norway locks its grip on "Best place to live" status:
As I pointed out last month,
this then leads to...
Shoulda studied Norwegian
like I had planned to do originally before I got sidetracked by Swedish.
They mean the same thing today, but at one time they were quite different.
It all comes from 16-bit Windows.
In those days, a "module" represented a file on disk that had been
loaded into memory, and the module "handle" was a handle to a
data structure that described the parts of the file, where they come
from, and where they had been loaded into memory (if at all).
On the other hand an "instance" represented a "set of variables".
One analogy that might (or might not) make sense is that a "module"
is like the code for a C++ class - it describes how to construct
an object, it implements the methods, it describes how the objects
of the class behave. On the other hand, an "instance" is like
a C++ object that belongs to that class
- it describes the state of a particular instance of
In C# terms, a "module" is like a "type" and an instance is like an
(Except that modules don't have things like "static members",
but it was a weak analogy anyway.)
Here's a diagram.
we discussed 16-bit HRSRC in a previous entry.)
In 16-bit Windows, all programs ran in a single address space,
and if a DLL was used by five programs, it was loaded only once
into memory. In particular, it got only one copy of its data
(In C++/C# terms, a DLL is like a "singleton class".)
DLLs were system-global rather than per-process.
The DLL did not get a separate copy of its data for
each process that loaded it.
If that was important to your DLL, you had to keep track of it yourself.
In geek terms, there was only one "instance" of a DLL in the system.
On the other hand, if you ran two copies of Notepad, each one got its
separate set of variables - there were two "instances".
Both running copies of Notepad shared the NOTEPAD module
(so the code and resources were shared), but each had its own
copy of its variables (separate data segment).
There were two "instances" of Notepad.
The "instance" handles in the above diagrams are the data segments.
Programs are identified by their the instance handle.
You can't use the module handle, because the two copies of Notepad
have the same module handle (since the same code is running in each).
The thing that makes them different is that each has its own
set of global variables.
This is why the
ShellExecute functions return HINSTANCE:
They are holdovers from 16-bit Windows, where HINSTANCEs were the way
to identify running programs.
The method by which code receives its HINSTANCE (i.e., knows where its
global variables are) I will leave for a future article.
It is somehow related to the now-obsolete MakeProcInstance function.
When it came to design Win32, the question then arose, "What do we do
with HINSTANCE and HMODULE for Win32?" Since programs ran in separate
address spaces, you didn't have instance handles visible across process
boundaries. So the designers took the only thing they had:
The base address of the module. This was analogous to the HMODULE,
since the file header describes the contents of the file and its structure.
And it was also analogous to the HINSTANCE, since the data was kept in the
data segment, which was mapped into the process directly.
So in Win32, HINSTANCE and HMODULE are both just the base address of the
Tomorrow, I'll talk about that mysterious hinstPrev parameter to WinMain.