by Michael S. Kaplan, published on 2005/02/19 10:20 -05:00, original URI: http://blogs.msdn.com/b/michkap/archive/2005/02/19/376607.aspx
MSLU covers a lot of territory, considering how small it is -- less than 250k yet it covers over 500 APIs!
One of the questions I was often asked was what I thought was the most difficult API to wrap.
My answer, without hesitation, was always the same: FormatMessage.
Let's look at how the Platform SDK describes it:
The FormatMessage function formats a message string. The function requires a message definition as input. The message definition can come from a buffer passed into the function. It can come from a message table resource in an already-loaded module. Or the caller can ask the function to search the system's message table resource(s) for the message definition. The function finds the message definition in a message table resource based on a message identifier and a language identifier. The function copies the formatted message text to an output buffer, processing any embedded insert sequences if requested.
Ok, so it sounds complicated. When I started out, I figured it would be easy. Of the 32 different Unicode layers inside of Microsoft almost half of them had a FormatMessage wrapper already. With so
much code to work from, we should be covered, right? The reality was far stranger, unfortunately! It seems that even with 14 samples to steal from, no one had ever implemented the whole function. After all, FormatMessage is pretty complicated:
You can load from system messages, from your own binary, or format a string you pass in
Turns out no one had ever done it all -- in fact, none of them used arguments at all, except in the simplest of ways to avoid problems (i.e. a version that only accepted strings, a version that never accepted them, and so on). I won't names or anything, but I really don't have to -- from my point of view everyone stunk at this point, and I did not care how many interesting bugs for ExtTextOutW on Win9x had been fixed....
So, the MSLU Triage Committee met (which sounds more impressive than it was -- it was just my lead and a PM and me talking). We decided that ideally MSLU ought to just to do it right, for all of the cases. After all, you never know what a user might be depending on!
But trying to completely support all possible aspects was tricky. After all, you have to accept an arbitrary number of parameters, only some of which might be strings (and of course all strings have to be converted!). They can be used in any order and although it is not documented it it entirely legal to skip inserts in the actual string being used (thank God for beta testers, thats all I can say!).
In the end, I kept a very simple strategy to handle all the weirdnesses of inserts:
Lots of minor flourishes about allocations and language info, etc., but in the end this was a pretty hellaciously complicated API to try to totally support!
This post brought to you by "ฑ" (U+0e11, a.k.a. THAI CHARACTER THO NANGMONTHO)
# AC on 19 Feb 2005 1:01 PM:
# CN on 19 Feb 2005 4:42 PM:
# Michael Kaplan on 19 Feb 2005 7:52 PM: