Holy cow, I wrote a book!
In 2006, via the suggestion box,
Chris J asks why the OLE variant date format has such a strange
Its zero point is 30 December 1899, as opposed to 1 January 1900
(SQL Server's zero point) or 1 January 1970 (the unix zero point).
It turns out I don't have to answer this because
Eric Lippert explained it three years before the question was posted,
and then some time later posted
a puzzle regarding date calculations.
Public Service Announcement:
This weekend marks the start of Daylight Saving Time
in most of the United States.
Some time ago,
a customer asked this curious question (paraphrased, as always):
we have a program that was originally designed for Windows XP
and Windows Server 2003,
but we found that it runs into difficulties on Windows Vista.
We've found that if we set the program into Windows XP
compatibility mode, then the program runs fine on Windows Vista.
What changes do we need to make to our installer so that when
the user runs it on Windows Vista, it automatically runs in
Windows XP compatibility mode?
Don't touch that knob;
the knob is there for the customer, not for the program.
And it's there to clean up after your mistakes,
not to let you hide behind them.
It's like saying,
"I normally toss my garbage on the sidewalk in front of the pet store,
and every morning, when they open up,
somebody sweeps up the garbage and tosses it into the trash.
But the pet store isn't open on Sundays,
so on Sundays, the garbage just sits there.
How can I get the pet store to open on Sundays, too?"
The correct thing to do is to figure out what your program is doing wrong
and fix it.
You can use the Application Compatibility Toolkit to see all of the
fixes that go into the Windows XP compatibility layer,
then apply them one at a time until you find the one that
gets your program running again.
For example, if you find that your program runs fine once you apply
the VersionLie shim, then go and fix your program's operating system
But don't keep throwing garbage on the street.
At an informal gathering,
my colleagues and I started talking about our experiences
being interviewed at Microsoft.
One of the people there remembered how
one of the pieces of feedback on the interview lo these many years ago
was that although my colleague was certainly smart enough
and hardworking enough,
there seemed to be insufficient enthusiasm for the subject matter.
I mean, my colleague cared about the subject matter
but apparently didn't care enough to satisfy the interviewer.
The offer was extended despite this reservation,
and my colleague joined the team.
Years passed, and the details of the encounter were largely forgotten.
Microsoft is a large company, and
the group you end up assigned to may not have any members from
your original interview loop.
The assessment of my colleague as insufficiently enthusiastic was
ironic since this particular informal gathering took place at the PDC.
If you're speaking at the PDC,
then presumably you're not totally disinterested in the material.
Upon completion of this story, another colleague spoke up.
"Hey wait, I think I was that interviewer!"
was puzzled by a sign
reminding drivers that the fine for obstructing an intersection is $101
and wonders what the extra $1 is for.
The laws of the State of Washington defer the monetary value of
traffic fines to the
Infraction Rules for Courts of Limited Jurisdiction
(more commonly known as the IRLJ),
specifically section 6.2:
Monetary Penalty Schedule for Traffic Infractions [pdf].
But wait, the fine listed in the IRLJ is only $42.
Where did $101 come from?
In addition to the base fine in the IRLJ,
RCW 3.62.090 specifies additional assessments:
specifies a 70% assessment for public safety and education,
section (2) specifies an additional public safety and education
assessment equal to 50% of the earlier assessment.
On top of that,
specifies various fees and penalties:
Section 7(a) specifies a $5 fee for emergency services,
section 7(b) specifies a $10 fee for auto theft prevention,
section 7(c) specifies a $2 fee for the traumatic brain injury account,
section 8(a) specifies a $20 penalty to be shared between the state
and the local jurisdiction.
There are probably other clauses which add to the fines and penalties.
I remember investigating this a few years ago and convincing myself that
after taking all the fines and penalties and assessments and
whatever-else-they-call-its into account, the total did come to $101.
(Actually, they bring it to something close to $101, and then another
rule about rounding kicks in.)
And you won't get the numbers to add up to $101 any more because
there were changes to the fee schedule in July 2007.
The fine for basic traffic infractions is now $124.
The new calculation appears to be
42 × 2.05 + 5 + 10 + 2 + 20 = $123.10,
which rounds up to $124.
Dialog boxes and property sheets are similar in that most of the
time, you use them modally.
You call DialogBox or
and the function doesn't return until the user closes the dialog box
or property sheet.
But you can also use dialog boxes and property sheets modelessly,
or by including the PSH_MODELESS flag when you call
One of the more common problems people have when managing a modeless
property sheet is finding that keyboard navigation doesn't work.
The reason is the same as with modeless dialog boxes:
You forgot to process dialog messages.
But if you use the wrong function to process the dialog messages,
then you don't get the right behavior.
If you get confused and use IsDialogMessage to process
dialog messages for a property sheet,
things will seem to work mostly okay,
but most notably,
the Ctrl+Tab and Ctrl+Shift+Tab keyboard shortcuts won't work.
Those hotkeys are new to property sheets; those keys mean
nothing special to dialog boxes,
so the IsDialogMessage function won't do anything
special if the user types them.
There are other property sheet behaviors that go beyond
plain dialog boxes,
but the keyboard navigation among tabs is what users will probably
The other mix-up I've seen is sending the
PSM_ISDIALOGMESSAGE message to a modeless dialog box,
even though the dialog box isn't a property sheet.
The PSM_ISDIALOGMESSAGE message is handled only
by property sheets; if you send it to something else,
who know what'll happen?
Remember that PSM_ISDIALOGMESSAGE is in the
WM_USER range, and messages in that range
belong to the window class.
This is simply another case of keeping track of what you're doing
and using the mechanism appropriate for what you have.
You're already used to doing this in real life:
If you travel to Canada and want to buy something from a vending
machine, you have to put in Canadian money,
not Turkish lira.
Now let me get this straight.
The Oscars honor, among other things,
the best actors in Hollywood.
These are people who have devoted their professional careers
to reciting dialog in front of a camera and making it look
spontaneous and natural.
But for some reason, put them on stage at the Oscars,
and instead of reciting dialog spontaneously and naturally,
they read it stiltedly and lean into the microphone while doing it.
And these are the best actors in the business?¹
It's like hosting a music award show and finding that all the performers
suck at singing.
¹Oh wait, sorry, it's not a business.
It's a craft.
I don't know whose idea it was to start referring to movie-making as
a craft, but I'm sick of it already.
why double-right-click isn't a shortcut for Properties.
In the case of context menus, the proposed double-right-click action
is not an extension of the single-right-click,
because the single-right-click displays a menu,
whereas the double-right-click would go directly to the Properties dialog.
Indeed, the way context menus are positioned on the screen
specifically negates the possibility
of double-right-click, for the context menu positions itself (under
normal conditions) so that the click point is aligned with a dead spot
on the menu.
That way, when people who instinctively double-click everything
do their double-right-click on an item, they get a context menu on the
first right-click, and the second right-click is ignored.
If the context menu were positioned so that the click point was aligned
with an active location on the screen, then those habitual
double-clickers would be accidentally invoking some context menu command
when they really wanted to call up the context menu.
Now, if you decide to ignore the extension principle
(and there are certainly lots of people who do),
and if you decide that habitual double-clickers deserve to lose
(and you're perfectly happy telling them that they're idiots who
don't deserve the privilege of using a computer when they complain,
"Your operating system is hard to use"),
then you have to add
to single-clicks so you can perform separate
single-click and double-click actions.
Seeing as using right-click to display a context menu was not
widely known prior to Windows 95,
it would probably be even more confusing if a right-click
on Windows 95
didn't do anything... only to have a menu appear a half second later
after you had given up on the click and moved on.
The Alt+double-click (and equivalently, Alt+Enter) shortcuts were
added as a concession, so that people whose lives wouldn't feel
complete without a shortcut for calling up properties can finally
When friends of mine were expecting their first child,
the wife frequently received comments like
eating for two now."
The husband had a response ready:
"If she's eating for two, I'm drinking for three!"
There are functions like
for detecting that a floating point value is one of the special
values like NaN,
but how do you actually generate one of these values?
You can access these values from the std::numeric_limits
std::numeric_limits<float>::infinity(); // positive infinity
std::numeric_limits<float>::quiet_NaN(); // non-signalling NaN
Wait, where's negative infinity?
The compiler folks provided these handy little definitions
for when you need to generate a special value (as opposed to merely
and for which the numeric_limits template comes up short.
DECLSPEC_SELECTANY extern const float FLOAT_POSITIVE_INFINITY = ((float)(1e308 * 10));
DECLSPEC_SELECTANY extern const float FLOAT_NEGATIVE_INFINITY = ((float)(-1e308 * 10));
DECLSPEC_SELECTANY extern const float FLOAT_NaN = ((float)((1e308 * 10)*0.));
Applies to Microsoft Visual Studio.
Your mileage may vary.
Use the template when available.
Note that you must use functions like
_isnan to detect special values,
because floating point special values behave very
strangely in comparisons.
(For example, NaN does not compare equal to itself!)
March fourth is not just a pun on march forth,
but it's also
National Grammar Day,
Society for the Promotion of Good Grammar.