Holy cow, I wrote a book!
There are advanced settings in Windows,
settings which normal users not only shouldn't be messing with,
but which they arguably shouldn't even know about,
because that would give them just enough knowledge to be dangerous.
And no matter where you put that advanced setting,
somebody will tell you that you are an idiot.
Here they are on an approximate scale.
If you dig through the comments on this blog, you can probably find
every single position represented somewhere.
If you implement level N, people will demand that you implement
It doesn't stop until you reach the last step,
which is aggressively user-hostile.
(And then there will also be people who complain that
you went too far.)
From a technical standpoint,
each of the above steps is about ten to a hundred times harder
than the previous one.
If you put it in a configuration file, you have to write code
to load a parser and extract the value.
If you want an Advanced button, now you have to write a dialog box
(which is already a lot of work),
consult with the usability and user assistance to come up with
the correct wording for the setting, write help text,
provide guidance to the translators,
and now since it is exposed in the user interface,
you need to write automated tests and add the setting to the
It's a huge amount of work to add a dialog box,
work that could be spent on something that benefits a much
larger set of customers in a more direct manner.
That's why most advanced settings hang out at level 1
or, in the case of configuring program installation, level 2.
If you're so much of a geek that you want to change these
it probably won't kill you to fire up a text editor and write
a little configuration file.
Joel's count of
"fifteen ways to shut down Windows"
is a bit disingenuous, since he's counting six hardware affordances:
"Four FN+key combinations... an on-off button... you can close the lid."
Okay, fine, Joel, we'll play it your way.
Your proposal to narrow
it down to one "Bye" button, still leaves seven ways to shut down Windows.
And then people will ask how to log off.
Whenever a company says
"In order to serve you better",
you can be pretty sure they're about to do something that will
make your life more miserable.
This time, I'm going to call out Chase Financial Services,
who recently sent out notices to customers who had specified that
they did not want to receive marketing materials
informing them that they now have greater control over which marketing
materials they will receive, and
the default is that they will receive everything.
Strange, you'd think that if somebody said,
"Don't send me marketing materials,"
then they probably meant "Don't send me marketing materials,"
and therefore that the translation of this into a "fine-grained control"
is "no to everything."
Because that's how they've interpreted it up until now anyway.
Of course, the real reason they did this is to reset all their customer's
preferences so they can start sending them advertising again.
Notice that your opt-out choice must be renewed every five years.
Hey, at least it's better than
having to reiterate your preferences every three months
like some companies require.
Depending on what version of Windows you're running,
there may be a variety of support DLLs for things that
aren't formal product components, but which are merely along for the ride.
For example, Windows 95
came with MFC30.DLL because the Fax Viewer was written with
the help of MFC 3.0.
But if you look at Windows 98, MFC30.DLL is gone.
What happened is that Windows 98 didn't have a fax viewer
that used MFC 3.0.
The fact that some MFC 3.0 DLLs wound up on the machine
with Windows 95 was merely a side effect of the implementation
and not a part of the product specification.
And in fact, if you chose not to install the Fax Viewer
during Windows 95 setup, you wouldn't have gotten
MFC30.DLL at all either,
because MFC30.DLL wouldn't have been needed.
We had a category of Windows 98 compatibility bugs from
programs that assumed that MFC30.DLL was a contractual part of Windows.
If the tester did a minimal install of Windows 95 and then
installed the application,
the application wouldn't run there either.
The application vendor simply assumed that MFC was part of Windows,
even though it wasn't.
In other words, the program didn't work even on Windows 95.
Is it a bug in Windows 98 if the program didn't work on Windows 95?
This problem persists today.
People go scrounging around the binaries that come with Windows
looking for something they can remora.
And then they're surprised when those binaries change or vanish entirely.
For example, one customer had reverse-engineered the Kodak image viewer in
Windows 2000 and wanted to keep using it in Windows XP.
those components are not included in Windows XP;
the Kodak image viewer was merely a stopgap solution until the
Windows XP fax and image viewer came along.
(The linked Knowledge Base article has more information on that
I mention this because that customer, a Fortune 500 company,
was trying to copy the files from Windows 2000
and install them onto a Windows XP machine
and actually came to us asking for help in what may very well have
been a violation of the Windows license agreement!
(And certainly a violation of Microsoft's agreement with Kodak.)
(I now predict that everybody will comment on the last two sentences
and completely ignore the point of this article.)
The Windows calculator percent sign works the same way as those
cheap pocket calculators (which are often called four-function calculators
even though they have around six function nowadays).
What you first have to understand is that the percent key on those
pocket calculators was
not designed for mathematicians and engineers.
It was designed for your everyday person doing some simple calculations.
Therefore, the behavior of the key to you, an engineer,
seems bizarrely counter-intuitive and even buggy.
But to an everyday person, it makes perfect sense.
Or at least that's the theory.
Let's look at it from the point of view of that everyday person.
Suppose you want to compute how much a $72 sweater will cost
after including 5% tax.¹
Pull out your handy pocket calculator² (or fire up Calc if you don't
have a pocket calculator) and type
72 + 5% =
The result is 75.6, or $75.60,
which is the correct answer, because 5% of 72 is 3.6.
Add that to 72 and you get 75.6.
Similarly, suppose that sweater was on sale at 20% off.
What is the sale price?
72 − 20% =
The result is 57.6 or $57.60.
This is the correct answer,
because 20% of 72 is 14.4.
Subtract that from 72 and you get 57.6.
You can chain these percentage operations, too.
For example, how much will you have to pay for that 20%-off sweater
after adding 5% tax?
72 − 20% + 5% =
The result is 60.48.
A mathematician or engineer would have calculated the same result via
the equivalent computation:
72 × 0.80 × 1.05 =
Okay, now that we see how the calculator product designer intended the
percent key to be used,
let's look at what the calculator engineer
it has to do in order to match the specification.
When the user enters A + B % =,
the result should be
A × (1 + B/100) or
A + (A × B/100) after you distribute the multiplication
over the addition.
Similarly, when the user enters A − B % =,
the result should be
A × (1 − B/100) or
A − (A × B/100).
Aha, the calculator engineer says,
we can achieve this result by defining the percent key as follows:
When the user enters a value, an operator, a second value,
and then the percent key,
the first two values are multiplied and the product divided by 100,
and that result replaces the second value in the ongoing computation.
Let's walk through that algorithm with our first example.
If you watch the display as you go through this exercise,
you will even see the number 3.6 appear in the display
once you press the % key.
The percentage is calculated and replaces the original value
in the ongoing computation.
This algorithm also works for the chained percentages.
This even works for multiplication and division, but there is
much less call for multiplying or dividing a number
by a percentage of itself.
500 × 5 % =
The result of this is 12,500 because you are multiplying 500
by 5% of 500 (which is 25).
The result of 500 × 25 is 12,500.
You aren't computing five percent of 500.
You're multiplying 500 by 5% of 500.
(It appears that the authors of
this Knowledge Base article didn't consult
with the calculator engineer before writing up their analysis.
The percent key is behaving as designed.
The problem is that the percent key is not designed for engineers.)
What if you want to compute 5% of 500?
Just pick a dummy operation and view the result when you press
the percent key.
500 + 5 %
When you hit the percent key, the answer appears: 25.
You could've used the minus key, multiplication key, or division key
instead of the addition key.
It doesn't matter since all you care about is the percentage,
not the combined operation.
Once you hit the % key, you get your answer,
and then you can hit Clear to start a new calculation.
¹In the United States, quoted prices typically do not include
²In my limited experiments, it appears that no two manufacturers of
pocket calculators handle the percent key in exactly the same way.
Casio appears to handle it in a manner closest to the engineering way.
TI is closer to the layman algorithm.
And when you get into cases like 1 ÷ 2 %,
calculators start wandering all over the map.
Should the answer be 50, since 1/2 is equal to 50%?
Or should it be 0.005 since that is the numeric value of 0.5%?
Should that answer appear immediately or should it wait for you to hit the
I don't know what the intuitive result should be either.
1 ÷ 2 %
investigates the question
"Do hardworking employees make their slacker colleagues more productive?"
Tim Harford cites
Peers at Work by Alexandre Mas and Enrico Moretti
which used a grocery store check-out line as its laboratory,
and the results are illuminating.
(It may be hard to find, but the key paragraph is in the middle
of page 4, the one that begins, "We find that...")
The Swedes haven't quite figured out that my blog entries
do not constitute the official position of Microsoft Corporation.
I like how they don't even mention my name anywhere.
They just say "Microsoft doesn't this" and "Microsoft doesn't that".
If you go back to the article they used as a source,
you'll see that I provided a variety of reasons
for not going into the Start menu point system,
but this author decided to claim that reason 1 was not only
the only reason but in fact the official reason.
Perhaps I should have used a CGI script which randomized the
order of the items each time you refreshed.
Even though I'm signed in,
the page claims that anonymous comments are not allowed,
so I'm reduced to posting my comment here and generating a trackback.
Some time ago, Robert McLaws wrote a function that generates
initials from a name.
Let's set aside completely the issue of non-U.S. names;
the function doesn't even handle U.S. names correctly.
Given Cal Ripken, Jr., the function comes up with the
initials JCR, which is decidedly suboptimal.
Nowadays, a hard drive less than 20 gigabytes is laughably small,
but it used to be that the capacity of a hard drive was measured
in megabytes, not gigabytes.
Today, video files and databases can run to multiple gigabytes in size,
and your programs need be prepared for them.
This means that you need to use 64-bit file offsets such as those used by
the function SetFilePointerEx
if you're willing to fight with the
somewhat roundabout way it
deals with the high 32 bits of the offset).
It also means that you need to pay attention to the
nFileSizeHigh of the WIN32_FIND_DATA
For example, if your program rejects files smaller than a minimum size,
and I give you a file that is exactly four gigabytes, and you check
only the nFileSizeLow, then you will think that the file
is too small even though it is actually enormously huge.
More indirectly, it means that you can't blindly map an entire file
Many programs simplify file parsing by mapping the entire file into
memory and then walking around the file using pointers.
This breaks down on 32-bit machines once the file gets to be more
than about a gigabyte and a half in size, since the odds of finding
that much contiguous free address space is pretty low.
You'll have to map it in pieces or use some other parsing method
The Saint Petersburg Times purchased fish from several local restaurants
and found that
nearly half of the time, the fish they got wasn't what they ordered.
A state DNA lab came to the same conclusion.
Commenter Matt asks
how you're supposed to handle failures in functions
like fclose or CloseHandle.
Obviously, you can't.
If a clean-up function fails, there's not much you can do because,
well, how do you clean up from a failed clean-up?
These clean-up functions fall into the category of
"Must not fail for reasons beyond the program's control."
If a program tries to close a file and it gets an error back,
what can it do?
Practically speaking, nothing.
The only way a clean-up function can fail is if the program
fundamentally screws up,
say by attempting to close something that was never open
or otherwise passing an invalid parameter.
It's not like a program can try to close the handle again
(or worse go into loop closing the handle repeatedly until it
Remember this when writing your own clean-up functions.
Assuming the parameters are valid, a clean-up function must succeed.
(I will now ruin my rhetorical flourish by yammering about the
fclose function because if I don't,
people will bring it up in the comments anyway.
The fclose function does extra work before closing,
and that extra work may indeed run into problems,
but the important thing is that
when fclose returns, the stream is well and truly closed.)
Addendum: Once again I wish to emphasize that while it may
be possible for functions like fclose to run into errors
while they are closing the stream,
the point is that
the result of the call to fclose is always a closed stream.
I think most of the comments are losing sight of the point of my article
and rat-holding on the various ways fclose can run into
That's not the same as failing.
It never fails; it always succeeds, but possibly with errors.