Holy cow, I wrote a book!
Design for readability.
Even if you don't intend anybody else to read your code,
there's still a very good chance that somebody will have to
stare at your code and figure out what it does:
That person is probably going to be you, twelve months from now.
advised against the use of BOOL function parameters,
one commenter pointed out that
Intellisense shows you what the parameters are.
Sure, that's a great help when you're writing the code,
but you write the code only once.
You read it a lot.
An anonymous commenter pointed out that
hovering over the offending function in the IDE shows the function
While that may be true, it's still not a great solution.
First, it means that you have to read code with your hand on the mouse.
Second, it means that you can't skim code because you're going to hit
a CreateEvent and then have to wait
a little while for the tooltip to appear and then read and parse
the tooltip and match the parameters up to what you have on the screen.
This throws off your rhythm.
Imagine if you had to read code that had gone through a ROT-13 filter.
Sure, the IDE might help you by decoding the text under the cursor
if you hover over it, but even instant help isn't fast enough.
And finally, another commenter pointed out that
this doesn't help you
if you're reading code anywhere outside your IDE.
It might be in a magazine,
in a printout,
in a bug report,
on an overhead projector,
on a web page,
in a Usenet message,
or in an email message.
Good luck getting Intellisense to help you out there.
Conan O'Brien airs clips from Walker, Texas Ranger.
The putative excuse for this is that,
as a result of the merger of NBC with Universal Studios,
he can air clips from the show without paying royalties.
The real excuse, of course, is that the clips are
just so unintentionally funny.
This appears to be a recurring sketch on Conan,
so a little hunting around will reveal
This is, of course, not to be confused with
Chuck Norris Facts
Chuck Norris Fact Generator
Young Chuck Norris sketch from Saturday Night Live...
Here's a question that floated past my field of view some time ago:
When the mouse hovers over a disabled window, the tooltip associated
with that window does not appear.
Why is this?
Why isn't this documented in MSDN?
Actually, you already know the answer, and it is documented.
You just have to connect the dots.
When a window is disabled, it does not receive keyboard or mouse input.
The documentation for EnableWindow
says so in so many words, right in the first sentence.
Next, how do tooltips know when to appear and disappear?
Well, one way is to
modify your window procedure so it
takes all its input messages and forwards them to the tooltip
control via the
That way, the tooltip control knows where the mouse is and can
show and hide itself accordingly.
you can use the TTF_SUBCLASS flag
to tell the tooltip control to subclass the tool window and grab
the input itself.
Both of these methods are also documented.
Now put this all together.
The tooltip control peeks at all the input destined for the
tool window, either automatically via TTF_SUBCLASS
or manually with TTM_RELAYEVENT.
If the window is disabled, then it receives no input.
Consequently, the tooltip control has no input to peek at
and therefore doesn't know when to appear or disappear.
This is also why you don't get tooltips for hidden windows
and why you don't get tooltips when the mouse is captured to
So you see, you knew the answer all along.
You just didn't realize it.
There's been a slight change in plans.
I will be in Palo Alto on April 23rd
rather than April 20th.
Not that anybody is affected by this beyond the folks at
Microsoft's Silicon Valley Campus, since nobody else
took me up on my offer.
I guess I'm not as popular as I thought.
Here's my schedule for April 23rd when I'm down San Jose way.
Now the term "presentation" is a bit of an overstatement.
It's really just me telling a bunch of stories,
but instead of sitting at a table with a bunch of people,
I'll be standing in front of a room.
Same stories, different audio system.
I'll have a number of stories prepared,
but I'm hoping some of the chatter will inspire other stories.
(I won't do a coding presentation because,
I mean really, a presentation on
Win32 programming topics is bo-ring.)
Extremely limited guest
seating—we're talking one or two people—may be
available at the Apple chat.
The other appearances are closed-door.
Dinner plans have yet to be settled,
but I suspect that's your better bet.
Contact me directly for details (if you haven't already).
Q: How do you know when a lawyer is lying?
A: His lips are moving.
This is of course a completely unfair and discriminatory joke.
Many lawyers are women.
Anyway, today I'm going to rant about the phrase
"In order to serve you better."
Whenever you hear this phrase, you are pretty much guaranteed
that whatever follows will in fact not serve you better at all.
When I bought tickets to see
Real Madrid play against some Americans,
the online ticket service gave me multiple options for receiving my tickets.
I could have them mailed to me, or I could have the
tickets sent to me electronically.
And for some reason, there was a "convenience fee" for
receiving electronic tickets,
even though sending me electronic tickets costs them approximately
one gazillionth of a penny†, whereas paper tickets cost them
paper, handling, and postage.
They are inviting me to pay more so they can save money.
To maximize their revenues, they also put "(Recommended)"
next to the electronic ticketing option and selected it by default.
I can't believe they get away with this.
It used to be that when you looked up somebody's office number
in the address book at Microsoft,
you got something like "9S/1044", which means
"Room 1044 in the South wing of Building 9."
These buildings are big, and knowing which half to start in
can save you a lot of walking,
especially in some buildings where the two wings are not
For example, in Building 26
the north and south wings are connected only on the first two
If you want to get from the north wing of the third floor to
the south wing,
you have to go down a flight of stairs, then across, then up.
But several years ago,
they removed the wing designation from the address book.
That same office is now listed as simply "9/1044".
When I asked why they removed the wing designations,
I was told, "We did this in order to serve you better.
Many people were confused by it."
I have yet to find any of those people who are being served better.
Every single person I asked wanted the wing designations restored, too.
†A gazillion is not an actual number.
The thread pool is about reducing thread creating/termination
overhead by consolidating work that would normally go onto separate
threads into a small number of threads.
In a sense, you shouldn't be surprised that the thread pool is using
only one thread; instead, you should be happy!
I switched to using the thread pool, and I'm finding that it's
using only one thread.
To demonstrate this, I wrote a test program that fires off a bunch
of "work items" into the thread pool via
Each work item does some intensive computations.
What I'm seeing is that they are all running serially on a single
thread instead of running in parallel.
Since I have a dual-processor machine, this leaves half of
the computing capacity unutilized.
If I create a separate thread for each "work item",
then I get (not surprising) multiple threads and 100% CPU utilization.
Why does my thread pool use only one thread?
The purpose of the thread pool, as I noted above, was to reduce
the overhead of creating and terminating threads by running
multiple tasks on a thread.
For example, suppose you have three short tasks, say 1ms each.
If you put each one on its own thread, you have
Now suppose, for the purpose of this discussion, that creating
and terminating a thread take 1ms each.
if you create a separate thread for each task, you've spent
6ms on thread overhead and only 3ms doing actual work.
What if we could run multiple tasks on a single thread?
That way, the cost of creating and terminating the thread
could be amortized over all the tasks.
Ah, now we have only 2ms of overhead for 3ms of work.
Not great, but certainly better than what we had before.
If we can pack more tasks into the thread pool,
the fixed overhead of creating and terminating the thread
becomes proportionally less.
The thread pool is designed for handling a collection of
brief tasks, since those are the tasks that would best benefit
from thread pooling.
If you had a task that ran for ten seconds, putting it on
the thread pool wouldn't yield much in the way of savings;
that 2ms overhead you avoided is just noise compared to your
ten seconds of running time.
(Last year, we saw
another case of a series of tasks ill-suited to thread pooling.)
As an accommodation for people who will put the occasional
long-running task onto the thread pool (perhaps because it
simplifies the program logic by treating everything as a
work item), the thread pool allows you to give it a heads-up
passing the WT_EXECUTELONGFUNCTION flag.
But that's not really what the thread pool is for.
It's for quick-running tasks for which the overhead of creating
a separate thread would be disproportionate to the work
done by the task itself.
The Russian constitution limits the president to two consecutive
and Vladimir Putin is coming up on the end of his third.
When he ran for his third term, he explained that his first
term didn't count since it was served under the old constitution.
This explanation appears to have been widely accepted because everybody
reports that he is coming up on the end of his second term,
not his third.
(But I think it's funnier if you think of it as his third.)
Now it appears that
the groundwork is being laid
for Putin to run for his fourth term.
Out of a maximum of two.
I'm not saying he does or doesn't deserve to be president for another term.
(And he does say that he plans to step down, though he doesn't rule
out the possibility of running again.)
I'm just amused by the machinations involved in keeping him there.
Former Moscow bureau chief for the
Globe and Mail
chimes in with his thoughts
(much better informed than mine).
asks a duplicate of a
question that was already submitted to the Suggestion Box:
why operating system† files still (for the most part)
adhere to the old 8.3 naming convention.
There are a few reasons I can think of.
I'm not saying that these are the reasons;
I'm just brainstorming.
First, of course, the name of a DLL cannot change once it has been
chosen, because that would break programs which linked to that DLL
by its old name.
Windows 95 did not require the system volume and user profile
volume to support long file names, although that was certainly the
case by default.
Companies which used
may have had a heavy investment in servers which did not support
long file names.
Therefore, all system files on Windows 95 had to conform to the
8.3 naming convention.
I believe that
Windows NT permitted the system volume to be a short-file-names-only
FAT partition as late as Windows 2000.
Therefore, any DLL that existed in the Windows 2000 era
had to conform to the 8.3 naming convention.
Starting in Windows XP, long file names became mandatory,
and a few system files
waded tentatively into the long file name world.
(The .NET Framework folks jumped in with both feet with their managed
DLLs, but notice that their unmanaged DLLs like
mscoree.dll still conform to 8.3.)
But the waters in this world can be treacherous for operating
First of all, you have to worry about the automatically-generated
Suppose the operating system setup program is copying the
shellstyle.dll file, but there is already a file
The short name for shellstuff.dll will probably be
and therefore the short name for
shellstyle.dll will likely be
Now, this may not be a big deal, except that some programs
like to hard-code a file's short name.
(There are a lot of programs that assume that the Program Files
directory is C:\PROGRA~1, for example.)
Furthermore, you can create confusion if the same DLL is loaded
by both its short and long names, since the loader treats them as
int __cdecl main(int argc, char **argv)
If you run this program, you will get something like this:
Even though the two paths refer to the same DLL,
the loader treats them as different, and you end up with two
copies of the same DLL loaded into memory.
Now things get confusing, since you now have two sets of
global variables, and if two components both use
SHELLSTYLE.DLL but one used the short name and
the other the long name, things get exciting when those two
components try to talk about what they think is the same thing.
It's like that time when I was a child and our family
took a trip to Disneyland.
Our parents put my brother and me on the gondola ride,
and upon arrival at the other end, we were to go to the
Autopia ride which was right next door.
The plan was that our parents would meet us at the exit to
When my brother and I exited Autopia, we expected our parents to
be waiting there for us, but they were nowhere to be seen.
Sticking to the plan, we waited patiently for our parents to arrive.
We sat there for what seemed like two hours
(but which was probably much less),
we decided that my brother would stay put and I would go looking around,
at which point it didn't take long for me to find my father,
who was walking around looking for us.
What went wrong?
Well, the problem was that the map of Disneyland showed Autopia,
but what the map didn't say was that there were two
Autopia rides (and therefore two Autopia exits) right next to each other.
My brother and I were waiting by one exit, and our parents
were waiting by the other.
Each of us thought the other party was simply late.
Similarly, if a DLL goes by multiple names, you can end up with two
copies of it loaded into the process, with different components talking
about different copies, unaware that they are talking about different
And one final reason I can think of for sticking with 8.3 file names
for operating system DLLs is simply,
"Well, that's the way we've always done it.
All the problems with 8.3 names are well-understood and under control.
If we switched to long file names, we'd end up discovering a whole
new set of problems.
Why mess with something that works if it isn't broken?"
Better the devil you know.
Exercise: Why is it okay for the .NET Framework to use long
file names for their managed DLLs?
†s/operating system/Windows operating system/.
Apparently nothing is obvious from context any more.