Holy cow, I wrote a book!
Need to add 1.5kg and 350g?
Don't take any chances.
a Certified Metrication Specialist.
In the absence of an explicit threading model for your COM object,
you get the "main" threading model.
The "main" threading model is little-known, and that's a good thing.
It's a relic from the days before multi-threading.
The first thread in a process to initialize COM becomes declared
the "main" thread.
(It might be the first thread to initialize COM in apartment model;
When a "main" threaded object is created, COM marshals the creation
call to the main thread, creates the object, then marshals the result
back to the creator's thread.
Similarly, when you invoke any method on the object, the call is
marshalled to the main thread, invoked, then the result is marshalled back.
In other words, a "main" threaded object is like an apartment threaded
object, with the additional constraint that the only apartment that
can use it is the one that the "main" thread belongs to.
As you can imagine, this is a horrific performance penalty
in any multithreaded application, since there is so much marshalling
going on. Even worse, it completely bottlenecks the main thread
because there are now all these objects that must
be serviced on that thread and no other thread.
Even worse than worse, all this marshalling creates
new opportunities for re-entrancy.
While waiting for the main thread to do its thing, the calling
thread will likely process messages, which means that you can
receive a window message at a time when you didn't expect it.
So why does this awful threading model exist at all?
For backwards compatibility with COM objects written before
multithreaded support was added to COM.
Back in those days, there was only one thread, so COM objects
could be extremely lazy with their synchronization.
In fact, they didn't need any! If you have only one thread,
then you certainly don't need to coordinate your actions with
other threads because there are none.
That's also why "main" threading model is the default.
Threading models were invented when multithreading support
was added to COM. Before then, there were no threads, so no
threading models. All old objects therefore didn't specify
a threading model in their registration.
The only reason you should even be aware of this ancient threading model
in the first place is that
if you forget to specify a threading model in your object
registration, you will get the dreaded "main" threading model by
And then you will wonder why your application's performance is horrible,
and why you have all these strange re-entrancy problems.
Letter carriers in both
Scotland have taken to refusing to deliver
political advertisements from parties they personally find
This isn't quite the stunning synchronicity as it may appear
at first glance: Europe is gearing up for a continent-wide
One of the flags you can pass to the
SHGetFileInfo function is
What does this flag mean?
It means, "Do not access the disk. Pretend that the file/directory exists,
and that its file attributes are what I passed as the
dwFileAttributes parameter. Do this
regardless of whether it actually exists or not."
You can use this flag to get the icon for a file type.
For example, to get the icon for text files, pass a filename of
"x.txt", pass SHGFI_USEFILEATTRIBUTES in the uFlags, and specify
FILE_ATTRIBUTE_NORMAL as the file attributes.
Why is the filename "x.txt"?
Because you want it to have the extension ".txt", and you want it
to be a valid filename. (Don't pass illegal filenames like
Why are the file attributes FILE_ATTRIBUTE_NORMAL?
Because you want SHGetFileInfo to pretend that it is a normal file.
(If you passed, say, FILE_ATTRIBUTE_DIRECTORY, then you would have
gotten the folder icon back, since you told the function to pretend
that "x.txt" was a directory.)
Note that since you are telling SHGetFileInfo to "pretend",
there are some things you lose by the nature of make-believe.
For example, if the extension is a filetype whose icon changes
depending on the contents of the file,
then the dynamic icon will not be returned since there is no file.
You told the function to "pretend", after all,
and a pretend file has no contents.
They choose fast food, fat people, and Bush in a tank.
In January, a cartoon festival was held in the town of Carquefou,
just outside of Nantes in the northwest corner of France.
Students of all ages competed in a contest to illustrate their vision
of the United States.
They drew obese Americans devouring Coca-Cola and McDonald's hamburgers.
They drew the Statue of Liberty with fangs or in chains or
being run over by a wicked Uncle Sam on a motorcycle.
And they drew George W. Bush:
Bush riding a tank to war;
Bush taking over the world;
Bush as a liar;
Bush as a monster.
the drawing of ravenous overweight superheroes.)
The French image of the United States as the land of hamburgers and
obesity extends beyond the minds of schoolchildren.
one of the salient features of
"Belleville" (a thinly-disguised New York City) in the
Academy Award-Nominated animated film
Triplets of Belleville.
(Note: I saw Triplets and found it unsatisfying.)
(In another case of blog synchrony,
Eric Gunnerson discussed the frustrating trend of "size inflation".)