by Michael S. Kaplan, published on 2008/09/22 10:01 -04:00, original URI: http://blogs.msdn.com/b/michkap/archive/2008/09/22/8960832.aspx
The question (asked over in the microsoft.public.win32.programmer.international newsgroup) was:
I think there is something fundamental that I missing about the CompareString API. Distilling a lot of confusion, I have an example where something like...
LPCTSTR cTest = L"{\rtf";
CompareString( LOCAL_INVARIANT, 0, cTest, -1, cTest, -1) does not return CSTR_EQUAL.
CompareString( LOCAL_INVARIANT, NOM_IGNORECASE, cTest, -1, cTest, -1) does not return CSTR_EQUAL.
It does return CSTR_EQUAL on XP with English locales (UK and US), but fails with a German locale.
Shouldn't a string be equal to itself? What am I missing?
Alternatively, can someone suggest a better way to do a case insensitive test of equality that works independent of the locale? I can see where sorting would be locale dependent, but it seems that equality should not depend on locale.
Thanks.
Now there are a whole bunch of problems here, but I thought I'd open it up to the peanut galleryreaders if anyone wants to enumerate errors here, and by errors I mean technical errors, process errors, errors in the questions being asked, usage errors, conventional errors, best practice errors, errors in language usage, errors in spelling, errors in the color coordination of the person asking, literally anything -- provided you can prove it by using the text above to do so (i you can figure out how to prove the color coordination issue I will be quite impressed!).
Anyone who was there for the first time but has not forgotten the answers, and anyone who tries to find the old thread in the newsgroups is disqualified.
Psychic debugging encouraged, and I'll be using it to determine if people cheat on any of the above. :-)
Ready, set, go!
Rob on 22 Sep 2008 11:10 AM:
Someone forgot to #define UNICODE?
LPCTSTR cTest = L"{\rtf";
If you're using a Unicode string, why not declare cTest as LPCWSTR?
Christian Kaiser on 23 Sep 2008 10:06 AM:
My first thoughts:
a) it's not "LOCAL_INVARIANT", but "LOCALE_INVARIANT"
b) comparing binary key strings like "{\rtf" does not make sense using CompareString and collational compare - such a comparison has no meaning for to the binary stream that an RTF stream is.
c) why CompareString does differ on the (assumed) thread locale, or the user locale, while it has a 'invariant' locale parameter, looks strange to me, but you will surely have a reasonable answer ;-)
d) the return value of the API is not checked - does CompareString possibly fail? 0 is not CSTR_EQUAL. As you see, I have not compiled or run that code above.
Christian
Christian Kaiser on 23 Sep 2008 10:28 AM:
Oh, just found two more while waiting for a build to complete here:
d) "\r" is an escape ;-))) -> could be a reason to return 0 for the API?
e) NOM_IGNORECASE -> NORM_IGNORECASE
Christian
Michael S. Kaplan on 24 Sep 2008 1:15 AM:
Okay, I am going to let this go on a tiny little bit longer, as I'm still looking for a couple more answers, especially the "Gregory House" type answer that ties everything together and explains it all. :-)
(That is a hint that there is still one clever issue out there has not been caught yet!)
Michiel on 26 Sep 2008 9:55 AM:
Weird, that \r escape followed by tf. Probably unintentional, considering the RTF text format.
CompareString is of course capable of returning equal, smaller, greater and wrong parameter (0) . Since we're not going to get smaller of greater, it means we must be getting wrong parameter. What's wrong? Well, for starters ignoring case is hard without a locale. What's the lowercase 'I'?
And of course, if "{\\rtf" is indeed a markup code, it shoud not be compared with CompareString. That's intended for human-consumable text.