Category: Articles

Unicode – Why Use It?

In this article, I’m going to answer the question most of the developers have before beginning to use Unicode.  Why should one bother to write code that supports Unicode, especially if they are not targeting any non-English language market?  Before we fall into it, I’d like you to know of Character sets, and their three varieties.  If you’re seeking for a how-to guide on using Unicode, this article won’t help you.  I suggest taking a look at my Unicode article.

Character Sets

Single-Byte Character Sets

In a single byte character set, all characters occupy only one byte.  This means that a string would simply be a series of bytes coming one after another, and the end is indicated by a NULL character, which is a zero byte.  This is the simplest of all character sets.  Most of the well-known C runtime functions like strlen expect the characters to be in this format.  But using this kind of character sets can cause problems when you want to build a program in a different language other than English.  The problem is not only you should have a coding system (called a code page) for each and every language, but also some languages (like the Japanese Kanji) need so many characters that can’t be fit in a single byte, and 255 characters in a single byte character set is not room enough for them.  This need, caused in the birth of double-byte character sets.

Double-Byte Character Sets

Sometimes called the Multi-Byte Character Sets (MBCS), the double byte character sets (DBCS) are just like the single byte character sets at the beginning.  The fist 128 codes for each code page is the same as ASCII character codes.  The other 128 codes are there and each language can define these characters to be whatever symbols they need in writing that language.  So what’s the difference with single byte character sets?  The difference is that for each code page, there are some codes that specify that the next byte following them should also be interpreted with that code, making a double byte.  This results in a code page in which some characters require one byte, and the others require two bytes.  Like the single byte character sets, the end of the string is specified by a single NULL character.  This implementation is kind of painful.  Consider you need to find out the size of a string.  You can’t pass such a string to strlen directly, because it expects each byte is a character.  You need to write your own string parsing routines for each CRT function that checks to see if a byte in the string specifies that the next byte should also be interpreted together with it or not.  Fortunately enough, the MSVC CRT library has some functions that are called the MBCS functions, and can handle both the single byte and double byte character sets.  For example, the MBCS version of strlen is called _mbslen.

The Windows API offers some functions that let you manage the MBCS strings to some extent.  These API functions are listed in the below table.

LPTSTR CharNext( LPCTSTR pszCurrentChar );Retrieves a pointer to the next character in a string.
LPSTR CharNextExA( WORD CodePage, LPCSTR pCurrentChar, DWORD );Retrieves a pointer to the next character in a string.  This function can handle both SBCS and DBCS strings.
LPTSTR CharPrev( LPCTSTR pszStart, LPCTSTR pszCurrent );Retrieves a pointer to the preceding character in a string.
LPSTR CharPrevExA( WORD CodePage, LPCSTR pStart, LPCSTR pCurrentChar, DWORD );Retrieves a pointer to the preceding character in a string.  This function can handle both SBCS and DBCS strings.
BOOL IsDBCSLeadByte( BYTE TestChar );Determines whether the specified byte is the first byte of a character in DBCS.
BOOL IsDBCSLeadByteEx( WORD CodePage, BYTE TestChar );Determines whether the specified byte is the first byte of a character in DBCS.

Although these functions make DBCS programming a lot easier, still DBCS is more pain that one would take.  The solution to this mess is the Wide-Byte Character Set, or Unicode.

Wide-Byte Character Sets

The wide-byte character sets have been born to eliminate the problems with DBCS.  What was the problem?  The characters in DBCS had different lengths.  What does the wide byte character sets offer to eliminate this problem?  It simply dictates that each and every character is made of two bytes, with no exception.  This makes working with string a lot easier.  A string is a series of two-byte characters following each other, with two NULL bytes at the end to indicate a NULL character, and hence the end of the string.  So, the CharNext/CharPrev and other MBCS related APIs are no longer necessary.  Easy, eh?  But wait.  Like anything that has some dark sides, there is a dark side to Unicode also!  The dark side of it is all your strings will take up two much the space of a SBCS string, and much more space than a MBCS string.  This results in higher memory usage, as well as larger executables.  The answer to this problem (if one can call it a "problem") is that this extra space is necessary if you want international applications, and even if you only use English in your applications, then you can simply *ignore* this price you pay because of two reasons.  The second (!) reason is that these days, large capacity hard disks and RAMs are really cheap.  The first reason, you’ll know by going on through this article.

Unicode Support on Different Platforms

Unicode and Windows 95/98

Windows 95/98 are not new operating systems, they are just a layer built upon the the old 16-bit Windows.  Because Unicode was not considered in the design of 16-bit Windows operating systems, Microsoft did not pull Unicode into Windows 95/98.  So, Windows 95/98 do all (well, almost all) their internal work using ANSI strings.  Of course they offer some Unicode functions I’ve pointed out in my other article, but, as Jeffrey Richter states in his book, Programming Applications for Microsoft Windows, many of these functions are bogus.  So, if you’re only targeting Windows 95/98, then you don’t need to think about Unicode at all.

Unicode and Windows NT/2000/XP

Windows NT was built using Unicode from the start.  All of the internal operating system functions do their jobs using Unicode strings.  And, it’s the same on both English and non-English versions of Windows NT.  Windows 2000, which was built on Windows NT, and also Windows XP, which is built upon Windows 2000, both inherit all the Unicode support.

So, it’s somehow incorrect to say that Windows NT/2000/XP support Unicode.  Instead, one must say they support ANSI!  The ANSI support does not come free of course.  All the ANSI functions in Windows NT/2000/XP are simply wrappers around the Unicode functions, and their only job is converting between Unicode and ANSI strings, and calling the Unicode version.

This means that if an ANSI function which expects an ANSI string as input is called in Windows 2000 for example, the system internally copies the ANSI string to a Unicode buffer, and calls the Unicode version, passes the Unicode buffer to it, and returns the result of the Unicode function.  Also if the ANSI function has an ANSI buffer for output, the system internally allocates a Unicode buffer, passes it to the Unicode version which fills in that buffer with Unicode characters, and then converts that Unicode string to ANSI and copies it to the specified ANSI buffer that you pass to the function.  This introduces a lot of overhead which we’ll discuss later.

Unicode and Windows CE

Like Windows NT, Windows CE is natively Unicode.  This means that you can call the Unicode version of the APIs successfully on Windows CE.  But, note that because Windows CE was designed to be as small as possible, it does not support ANSI at all.  So, if you are targeting Windows CE, you should always use Unicode, else your application will not run.

Unicode and the Component Object Model (COM)

As a general rule, all COM interfaces should expect the string to be Unicode.  This is true even on Windows 95/98.  So, if you are developing for Windows NT/2000/XP or Windows CE, you can easily use COM, and all your source code would be Unicode.  However, if you’re developing for Windows 95/98, here the pain starts!  You should convert string between Unicode and ANSI all the time.  The simplest way I know of to do this is using the Conversion macros I’ve discussed in my Unicode article.

To Unicode, or Not to Unicode – That’s the Question

My answer to the above question is simply "Use Unicode".  Of course, I mean you should use Unicode if you are developing for any other platform other than Windows 9x, and also you should create generic source code that you can compile both using Unicode and ANSI, and distributing the ANSI modules for Windows 9x, and Unicode modules for the rest of the operating systems.

I understand that unless you want to write a Windows CE application, you can stick to ANSI, but I’ll show you something in a minute that is all the reason not to use ANSI on Windows NT/2000/XP.  All this is about is efficiency.

Inside the NTDLL.DLL, which is the core of Windows NT, you can find a lot of API functions that together form the ANSI support on Windows NT.  Some of these functions are RtlInitAnsiString, RtlInitUnicodeString, RtlAnsiStringToUnicodeString, RtlUnicodeStringToAnsiString, RltUnicodeToMultiByteN, RtlMultiByteToUnicodeN, Basep8BitStringToUnicodeString, BasepUnicodeStringTo8BitString, etc.  I won’t go into describing these functions, you can find a good description on them in the December 1997 "Under the Hood" section.

Now let’s see how the ANSI support is implemented on Windows NT.  Each thread is associated with a Unicode buffer.  The ANSI functions that need to have ANSI strings as input need to copy it to a Unicode buffer.  Some of these functions use the thread’s Unicode buffer and copy and convert the ANSI string to that Unicode buffer, and some other allocate a Unicode buffer using HeapAlloc.  The latter group should free the buffer using HeapFree once they are done with the buffer.

The ANSI functions that need to have an output string work alike.  They call the Unicode version either passing is the thread’s Unicode buffer, or the memory buffer they allocate themselves using HeapAlloc, and then convert the resulting string to ANSI and copy it to the buffer that the caller specifies.  If they’ve allocated some memory, they should free it using HeapFree.

So, let’s summarize it.  The ANSI functions need to specify/allocate some memory buffer to the Unicode functions (overhead), and convert the input ANSI strings to Unicode and the output Unicode strings to ANSI (overhead), copy the ANSI strings to Unicode buffers and vice versa (overhead), and most of the time free the allocated memory (overhead).  So, using the Unicode API does not add anything but overhead to your application, no?!  This is the first reason to ignore the dark side of the Unicode I had promised.  If you care about efficiency a bit, you’ll never ever use ANSI on Windows NT/2000/XP again!

Ok, now you know about all the overhead this can cause, but, hey, how much is that overhead?  It’s quite a bit!  To prove it, use the following benchmarking application that is adapted from the "Under the Hood" article pointed to above.  When I ran it on my system, I got some results you might be interested to know!

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>

#define BUFFER_SIZE MAX_PATH
#define ITERATION 1000000

int main(int , char* [])
{
LARGE_INTEGER before, after, freq;
double dAnsi, dUnicode;
char szAnsi[ BUFFER_SIZE ];
wchar_t wszUnicode[ BUFFER_SIZE ];
unsigned long ul = 0;

::QueryPerformanceFrequency( &freq );

::SetThreadPriority( ::GetCurrentThread(),
THREAD_PRIORITY_TIME_CRITICAL );

::Sleep( 0 );
::QueryPerformanceCounter( &before );

while (ul ++ < ITERATION)
{
HMODULE hMod = ::GetModuleHandleA( "kernel32.dll" );
}

::QueryPerformanceCounter( &after );

dAnsi = (double) after.QuadPart - before.QuadPart;
dAnsi /= freq.QuadPart;
ul = 0;

::Sleep( 0 );
::QueryPerformanceCounter( &before );

while (ul ++ < ITERATION)
{
HMODULE hMod = ::GetModuleHandleW( L"kernel32.dll" );
}

::QueryPerformanceCounter( &after );

dUnicode = (double) after.QuadPart - before.QuadPart;
dUnicode /= freq.QuadPart;
ul = 0;

::printf( "GetModuleHandle:\n\tANSI version:\t\t%lf"
"\n\tUnicode version:\t%lf\n\n\n", dAnsi, dUnicode );

::Sleep( 0 );
::QueryPerformanceCounter( &before );

while (ul ++ < ITERATION)
{
::GetCurrentDirectoryA( sizeof(szAnsi) / sizeof(szAnsi[ 0 ]),
szAnsi );
}

::QueryPerformanceCounter( &after );

dAnsi = (double) after.QuadPart - before.QuadPart;
dAnsi /= freq.QuadPart;
ul = 0;

::Sleep( 0 );
::QueryPerformanceCounter( &before );

while (ul ++ < ITERATION)
{
::GetCurrentDirectoryW( sizeof(wszUnicode) / sizeof(wszUnicode[ 0 ]),
wszUnicode );
}

::QueryPerformanceCounter( &after );

dUnicode = (double) after.QuadPart - before.QuadPart;
dUnicode /= freq.QuadPart;

::printf( "GetCurrentDirectory:\n\tANSI version:\t\t%lf"
"\n\tUnicode version:\t%lf\n\n\n", dAnsi, dUnicode );

return 0;
}

And here are the results I got when I ran this program on my machine.  BTW my machine is a Windows XP Professional system, with an AMD 1GHz CPU, and 192MB of RAM:

H:\Projects\VC++\test\UniBenchmark\Release>UniBenchmark
GetModuleHandle:
        ANSI version:           1.500179
        Unicode version:        1.283605


GetCurrentDirectory:
        ANSI version:           0.497415
        Unicode version:        0.201535



H:\Projects\VC++\test\UniBenchmark\Release>UniBenchmark
GetModuleHandle:
        ANSI version:           1.507318
        Unicode version:        1.290783


GetCurrentDirectory:
        ANSI version:           0.498030
        Unicode version:        0.201641



H:\Projects\VC++\test\UniBenchmark\Release>UniBenchmark
GetModuleHandle:
        ANSI version:           1.496500
        Unicode version:        1.281841


GetCurrentDirectory:
        ANSI version:           0.497670
        Unicode version:        0.202688



H:\Projects\VC++\test\UniBenchmark\Release>UniBenchmark
GetModuleHandle:
        ANSI version:           1.498664
        Unicode version:        1.282629


GetCurrentDirectory:
        ANSI version:           0.496627
        Unicode version:        0.201643

The results are approximately the same each time.  On the average, the ANSI version of GetModuleHandle that has an input string parameter takes 16.81 percent more time to complete than the Unicode version, and the ANSI version of GetCurrentDirectory that has an output string parameter takes 146.41 percent more time to complete than the Unicode version, which is well above two times the Unicode version!  While this may not be much of an issue in normal and small utility applications, its quite a bit important on heavy applications that need to run fast, for example a server application, or a graphics package.

So, the final word is that Unicode applications run at least two times faster than ANSI applications on my machine.  Also consider the fact that they require more memory to run than the Unicode applications.  Now the choice is yours, you can forget about learning how to program in Unicode, and have slow Windows NT application, or you can learn it, and have super fast Windows NT applications, and distribute an ANSI version for Windows 9x if necessary.  But, anyway, always think twice before writing ANSI applications for Windows NT at least!

This article originally appeared on BeginThread.com. It’s been republished here, and may contain modifications from the original article.

Client COM

I have seen many people who want to start writing COM code, but don’t know where to start.  Not that COM is under-documented, the problem is exactly the other way: there are just enough resources available for one to study to get them lost along their way, wondering how to create a simple COM object and do something with it.  In this article I try to explain how you can write client COM code, and I’ll stay away from all the internal details as much as possible.  If you need more details in a specific topic, you can both consult the MSDN documentation or send me an email.

First, I try to give you some general knowledge of COM, just enough details to get you going:

What is COM?

COM is the abbreviation for Component Object Model.  COM is a binary standard issued by Microsoft, and as long as an object sticks to the COM specification for its binary model in the memory, it can be called from any language which supports COM.

Suppose you have a piece of C++ code, and you want to use it in JavaScript.  You only have one way to do this: rewrite the whole code.  Note that I don’t say there’s no other easy way than COM, there simply is no way at all to do this except using COM.  The reason is that an object in C++ is not the same thing as an object in JavaScript, so JavaScript has no knowledge about how to create your C++ object, and use it.  Sadly even rewriting the code is not usually an option, because of the limitations of the JavaScript language which don’t give you enough power to translate a C++ object into JavaScript.

Using COM, you write a C++ object that only has to follow some basic rules, and everything else is on the compiler’s shoulders to create a binary module (DLL or EXE) compatible with the COM specification.  Then you can easily use that COM object from JavaScript.  But I’m not going to discuss how to write a COM object in this article, so I’ll stop this topic now.

What is client COM?

Client COM is simply code which uses a pre-written (and possibly 3rd party) COM object.  Don’t get cheated by the "client" term here.  It has nothing to do with the usual notion you might have of client/server applications which communicate over a certain kind of network.  Any code which uses a COM object is called client COM code, and likewise any code which actually implements a COM object is so-called COM server code.  In this article, we’ll only cover client COM, so you will be able to use a COM object after finishing this article, but not to write one.

What is a COM object?

A COM object is a piece of binary data which follows the COM specification.  Logically, but not technically, a COM object is just like a C++ object: it has methods and properties used to manipulate the object.  But note that a COM object is not the same thing as a C++ object; they’re different beasts.  The client of the COM object does not care at all about how the object is implemented.  In fact, they can’t even see inside of an object.  All they know of the object is what the object itself claims to be, which is the COM interface of the object.

What is a COM interface?

A COM interface is the layout of a COM object, which shows the methods and properties the object supports.  I want to make it clear here that methods and properties in COM are different to what we already know of them in C++.  A method is a function related to a COM interface.  A property is a special kind of method which can be called with a simpler syntax from some languages (such as Visual Basic).  A property usually consists of a "get" and a "put" method (unless it’s read-only, in which case it does not have the "put" method; or it’s write-only, in which case it does not have the "get" method).  When you want to query a property’s value, you call the "get" function, and when you want to change the value of the property, you call the "put" function.  More on this soon.

OK, back to the interfaces.  An interface shows what functions an object has.  A COM interface cannot have a data member (like C++ classes, for example).  Data members are implemented using properties in COM, which I will explain later.  In C++, a COM interface is equivalent to an abstract class (a class with no data members, and with only pure virtual functions).  As you know, abstract classes show nothing about the implementation, and that is what I said above.  In COM, you don’t care about how an object is implemented (or even which language it’s written in); you just use it.  You don’t know anything about a COM object, instead of a set of interfaces which it implements.  Interfaces are so called the "contracts" that a COM object accepts and based upon which it works with its clients.

COM interfaces can themselves be derived from other COM interfaces, but there is no multiple inheritance in COM interfaces.  A COM class can support multiple interfaces.  Don’t worry if it all seems weird, you’ll learn all these points soon.

The mother interface, IUnknown

All the COM interfaces have to be derived from a pre-defined interface, called IUnknown.  IUnknown is the root for all the interface hierarchies.  Many interfaces derive from IUnknown directly, and many others derive from other interfaces which in turn derive from IUnknown.  IUnknown has only three functions, and every COM interface has to support these functions.  Here is how IUnknown is defined in C++ (its actual definition is in unknwn.h, but the below is the meat of it):

#define interface struct

interface IUnknown
{
virtual HRESULT __stdcall QueryInterface( IID & riid,
void ** ppv ) = 0;
virtual ULONG __stdcall AddRef( void ) = 0;
virtual ULONG __stdcall Release( void ) = 0;
};

I will describe the QueryInterface( ) function here, and will discuss AddRef( ) and Release( ) later.  Suppose somehow (I’ll show you how later) you obtain an IUnknown pointer to a COM object.  Suppose this object supports the IAnotherIFace interface, and you want to call a method on this object’s IAnotherIFace interface.  Obviously you should first obtain a pointer to the IAnotherIFace interface.  You do this using QueryInterface( ).  QueryInterface( ) takes to parameters, an IID, and a void **.  The IID parameter is the identity of the COM interface.  The void ** parameter is a pointer to the interface pointer variable you have already allocated.  If QueryInterface( ) succeeds, it returns the interface pointer in *ppv.  Now let’s see what the identity is.

COM uses a method to identify everything, called GUIDs.  A GUID (Globally Unique Identifier, sometimes referred to as UUID, Universally Unique Identifier) is a 128-bit number which is guaranteed to be unique (i.e. no one else uses the same GUID as you decide to use).  Its uniqueness is guaranteed because of the very minor chance to generate two identical GUIDs.  I won’t discuss what factors are used to make repetitive GUIDs as rare as possible, but you can have my word that any GUID the system creates for you will be unique (by the way, to create a GUID, you can call the CoCreateGuid function).  A GUID is shown like this in C++ (see the guiddef.h header file):

typedef struct _GUID {
unsigned long Data1;
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[ 8 ];
} GUID;
typedef GUID UUID;
typedef GUID IID; typedef GUID CLSID;

But you rarely have to work with GUIDs in that form.  Most of the time, they are shown in a human readable form by the pattern: {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}, for example: {E464E05E-C102-499c-9B35-C1D569B065AB}.  An IID (Interface Identifier) and a CLSID (Class Identifier) which we’ll cover later are GUIDs as well.  Also COM type libraries are identified by a LIBID, but we won’t discuss them in this article.  So, in short, each interface has an associated IID which uniquely identifies the interface.  So, to obtain an interface pointer from another interface pointer, you pass the IID of the desired interface to the QueryInterface( ) function.  Note that a usual naming convention dictates the IIDs to be named in the form of IID_InterfaceName, so in our example, the IID of the IAnotherIFace will be IID_IAnotherIFace.

As you see, the QueryInterface( ) returns an HRESULT type.  In fact, all the methods and properties in COM are required to return HRESULTs (that is, all the methods and properties except IUnknown::AddRef( ) and IUnknown::Release( )).  HRESULT is a typedef to LONG, and is a rich facility to transfer error/success status from the COM object back to the COM client.  The Platform SDK documentation describes the elements of an HRESULT, so I won’t discuss them here.  Only get familiar with the SUCCEEDED() and FAILED() macros for now.  Suppose you have a variable of type HRESULT names hr, then SUCCEEDED(hr) will evaluate to TRUE if hr is a success status code, and FAILED(hr) evaluates to TRUE if the hr is a failure status code.  You can use the Error Lookup tool which comes with Visual C++ to see what each HRESULT code means.  The most common HRESULT codes are S_OK (which shows a general success, defined as 0x00000000) and E_FAIL (which shows a general failure, defined as 0x80004005).

Using what I described, now we can write out first piece of COM code which is a call to QueryInterface( ):

// suppose we have somehow obtained pUnk
void foo(IUnknown * pUnk)
{
IAnotherIFace * pAnother = NULL;
HRESULT hr = pUnk->QueryInterface( IID_IAnotherIFace,
reinterpret_cast< void ** > (&pAnother) );
if (SUCCEEDED(hr))
{
// succeeded, pAnother is non-NULL
}
else
{
// failed, pAnother is NULL
}
}

Now the above code should make sense to you: it takes an IUnknown pointer and obtains an IAnotherIFace interface from the pointer using the QueryInterface( ) function, then checks the result of the QueryInterface( ) call to see if the operation has succeeded or not (the operation would fail when the object does not support the IAnotherIFace interface, in which case it returns the E_NOINTERFACE error code).  The above code is a common piece of code when writing client COM code, so you should keep it in mind.

A small point, as you’ve noticed, is that all the IUnknown methods have the __stdcall calling convention.  This is true for all the interface methods in COM, so in the rest of this article I assume that __stdcall is the default calling convention, and do not state it explicitly.

COM object creation and destruction

In C++, you create an object using operator new( ), and destroy it using operator delete( ).  But things are different in COM.  In COM, you create an object using the CoCreateInstance function, but never destroy an object.  Before you say that would cause memory leaks, read on to see how things work in COM.

The CoCreateInstance( ) function is prototyped like this in objbase.h:

HRESULT __stdcall CoCreateInstance( CLSID & rclsid,
IUnknown * pUnkOuter,
DWORD dwClsContext,
IID & riid,
void ** ppv );

The first parameter is the CLSID of the object to be created.  A CLSID is a GUID like an IID.  Like IID identifies an interface, a CLSID uniquely identifies a COM object (which is referred to as a coclass, which is COM Class in abbreviated form, and in essence is a COM object).  Again like IIDs, CLSIDs usually follow a naming convention like this: CLSID_coclassName.  CoCreateInstance needs the CLSID to know which object to create.  The second parameter is used for aggregation which is beyond the scope of this article.  You can always pass NULL for this parameter.  The third parameter identifies the context in which the object is to be created.  What this exactly means is beyond the scope of this article, but you should know that you usually pass CLSCTX_INPROC_SERVER for COM objects which are in DLLs, and CLSCTX_LOCAL_SERVER for COM objects that reside in EXE modules, or alternatively CLSCTX_ALL when you don’t care where the COM object resides.  The fourth and fifth parameters are just like the parameters of the IUnknown::QueryInterface( ) function.  In fact, CoCreateInstance internally performs a QueryInterface( ) using these parameters.  When you know what interface the object supports, you can pass the related IID as well as a pointer to an interface pointer of that time for the void ** parameter.  When you are not sure which interface(s) an object supports, you can pass IID_IUnknown and a pointer to an IUnknwon *, and later call QueryInterface( ) on the pointer to test the interface for the interfaces you’re interested in.

So, let’s look at how we can create a coclass of type AnotherIFace using its CLSID (CLSID_AnotherIFace).

void bar(void)
{
IUnknown * pUnk = NULL;
HRESULT hr = ::CoCreateInstance( CLSID_AnotherIFace,
NULL,
CLSCTX_INPROC_SERVER,
IID_IUnknown,
reinterpret_cast< void ** > (&pUnk) );
if (SUCCEEDED(hr))
{
// call our foo method to obtain a IAnotherIFace pointer
foo( pUnk );
}
else
{
// error
}
}

This function creates a AnotherIFace coclass, gets its IUnknown pointer, and uses the foo( ) function showed earlier to obtain a IAnotherIFace pointer.  Note that you could request the IAnotherIFace pointer directly, so that calling foo( ) wouldn’t be necessary:

void bar2(void)
{
IAnotherIFace * pAnother = NULL;
HRESULT hr = ::CoCreateInstance( CLSID_AnotherIFace,
NULL,
CLSCTX_INPROC_SERVER,
IID_IAnotherIFace,
reinterpret_cast< void ** > (&pAnother) );
if (SUCCEEDED(hr))
{
// now we have an IAnotherIFace pointer
}
else
{
// error
}
}

That’s how you construct a COM object.  Now let’s see how COM objects are destroyed.  As I said above, you can’t destroy a COM object directly.  In other words, if you call operator delete( ) on an interface pointer, the result would be disastrous.  But COM objects should have some way to be destroyed, otherwise they’ll stay in memory forever.  Fortunately they have such a way, which is implemented by a technique called reference counting.  When an object is being reference counted, it maintains an internal variable keeping track of the clients who are using it.  When a client obtains an interface pointer, the reference count is incremented by one.  When they no longer need the object, the reference count is decremented by one.  Because multiple clients can use an object simultaneously, this is a nice way to ensure that the object won’t be destroyed too soon, and also won’t stay in memory forever.  An object will only be destroyed after its reference count reaches zero.  There are two points to consider when implementing reference counting.  The first one is that the COM object’s code is responsible to perform this reference counting, since it doesn’t happen automatically, but this won’t worry us since we don’t care about the object’s implementation.  The second point is that the client is responsible to tell the object when it’s using the object, and when it’s done with the object.  This imposes a burden on us as the COM client programmers.  Let’s see how we should respect the rules here.

As you remember, when I was talking about IUnknown, I didn’t say anything about its AddRef( ) and Release( ) methods.  These two methods are responsible for performing the reference counting.  The AddRef( ) method increments the internal reference count by one, and the Release( ) function decrements the reference count by one.  If the reference count reaches zero after decrementing in Release( ), the object performs a self-destruction.  The AddRef( ) function returns the new reference count, and the Release( ) function returns the reference count after decrementing (so if Release( ) returns 0, the object is most likely destroyed before Release( ) returns.  But you should never store the return values of AddRef( ) and Release( ) and should never rely on them, because these values might not be the true reference count of the object.

A very important thing that most beginners in COM client programming forget is the fact that QueryInterface( ) performs an AddRef( ) on the interface pointer before returning it (if the function succeeds, of course), and expects the caller to call Release( ) when it no longer needs the object.  This implies that the CoCreateInstance function also performs an AddRef( ) on the interface pointer before returning it, because like I said, CoCreateInstance internally calls QueryInterface( ).

As you see, you should completely know the disciplines for reference counting to avoid problems in your code.  Through the article, I show a list of all the rules that you must follow to write safe COM client code.  Here are the first three:

  1. For each time you call AddRef( ) on an interface pointer, you must call Release( ) once, so that for each AddRef( ) you can easily find a corresponding Release( ).
  2. For each time you call QueryInterface( ) and obtain a new interface pointer, you must call Release( ) once on the resulting interface pointer.
  3. For each time you call the CoCreateInstance( ) function and obtain a new interface pointer, you must call Release( ) once on the resulting interface pointer.

Because of the rule number 1, you can’t assign interface pointers like normal variables.  See the following code, and try to determine the problem caused:

void DoSomethingAndRelease(IAnotherIFace * pPtr)
{
// Do something on pUnk
pPtr->Release();
}

void bar3(void)
{
IAnotherIFace * pAnother = NULL;
HRESULT hr = ::CoCreateInstance( CLSID_AnotherIFace,
NULL,
CLSCTX_INPROC_SERVER,
IID_IAnotherIFace,
reinterpret_cast< void ** > (&pAnother) );
if (SUCCEEDED(hr))
{
IAnotherIFace * pSecondPtr = pAnother;
DoSomethingAndRelease( pAnother );
DoSomethingAndRelease( pSecondPtr );
}
else
{
// error
}
}

Do you see the problem in bar3( )?  The pAnother variable is being assigned to pSecondPtr, but this doesn’t increment the reference count on the AnotherIFace object, so the result of executing this code is that AddRef( ) is called only once (inside the CoCreateInstance function) and Release( ) is called twice (in the two DoSomethingAndRelease calls).  Fixing this code is really simple:

void DoSomethingAndRelease(IAnotherIFace * pPtr)
{
// Do something on pUnk
pPtr->Release();
}

void bar3_fix(void)
{
IAnotherIFace * pAnother = NULL;
HRESULT hr = ::CoCreateInstance( CLSID_AnotherIFace,
NULL,
CLSCTX_INPROC_SERVER,
IID_IAnotherIFace,
reinterpret_cast< void ** > (&pAnother) );
if (SUCCEEDED(hr))
{
IAnotherIFace * pSecondPtr = pAnother;
pSecondPtr->AddRef();
DoSomethingAndRelease( pAnother );
DoSomethingAndRelease( pSecondPtr );
}
else
{
// error
}
}

So, a correct assignment in COM is done using a built-in C++ assignment as well as an AddRef( ) call.  This simplifies the things a lot: you can call Release( ) on any pointer you no longer need.  This leads us to the rules number 4 and 5:

  1. Never assign an interface pointer without calling AddRef( ) on the new pointer.
  2. Call Release( ) on the interface pointers when you no longer need them.

Also look at the rule number 6 which is really important:

  1. Never use an interface pointer after you call Release( ) on it.

If you forget about this rule, you may use an object which has already been destructed, and I’m pretty sure the results will be anything but what you expect to be.  In order to guarantee that you won’t make this mistake, I suggest you to assign the interface pointer to NULL so that if you accidentally use it later, you’d get an access violation which would remind you something fishy is going on.  You can write a function like below to release an interface pointer:

inline void Release( IUnknown *& pUnk )
{
pUnk->Release();
pUnk = NULL;
}

// always call the ::Release( ) function instead of
// calling IUnknown::Release( ) directly:

void bar4(void)
{
IAnotherIFace * pAnother = NULL;
HRESULT hr = ::CoCreateInstance( CLSID_AnotherIFace,
NULL,
CLSCTX_INPROC_SERVER,
IID_IAnotherIFace,
reinterpret_cast< void ** > (&pAnother) );
if (SUCCEEDED(hr))
{
// do something with it
::Release( pAnother ); // automatically sets pAnother to NULL
}
else
{
// error
}
}

Using this code, you should only remember to call the global Release( ) function instead of the IUnknown::Release( ) function.

Actually if you stick to the above three rules (rules 4, 5, and 6), you have all you need to know about writing safe COM client code with regard to reference counting.  If you follow rules 4, 5, and 6; then the rules 1, 2, and 3 will also be implicitly in effect.

Object/interface relationships

A very important aspect of COM is the relationship between a COM object and its interface(s).  In COM, objects are pieces of code which are abstracted by the use of interfaces.  What it means to you, as the COM client programmer is that you don’t know anything about an object’s internal behavior and how it works.  The only thing you know is which interfaces a particular object exposes.  You acquire interface pointers through calls to the QueryInterface( ) function of the IUnknown interface, and call the desired methods on the interfaces which results in some code of the object being executed.

Most objects expose multiple interfaces.  As you know, all objects have to support IUnknown, so in fact it doesn’t make sense to have an object with only one interface being exposed, because that one interface would be IUnknown, and the object actually provides no way for the client to ask it to do some work.  Each interface the object exposes provides a logically distinct properties and methods which together form the appearance of the object from a specific point of view.  To make myself clear, suppose you have an object called Person implementing a human being.  This object would expose several interfaces, such as IPerson, ILivingThing, ISocialBehavior, IPersonalBehavior, which can be defined like below:

interface IPerson : public IUnknown
{
HRESULT GetName( BSTR * pName ) = 0;
HRESULT GetAge( long * pAge ) = 0;
};

interface ILivingThing : public IUnknown
{
HRESULT IsLiving( BOOL * bLeaving ) = 0;
HRESULT Breathe( void ) = 0;
};

interface ISocialBehavior : public IUnknown
{
HRESULT TalkToSomeone( IPerson * pPerson ) = 0;
};

interface IPersonalBehavior : public IUnknown
{
HRESULT EatFood( void ) = 0;
};

With such a structure, you can call CoCreateInstance to create a CLSID_Person object requesting the IID_IPerson interface.  You can get the name of the person using the IPerson::GetName( ) method (which is a good candidate to be converted into a property, as I’ll show next).  Then to get the person to talk to somebody else (perhaps another Person object created by a CoCreateInstance call) you can QueryInterface( ) the IPerson interface pointer for the IID_ISocialBehavior interface.  Note that there is no limitation to the number of interfaces an object can expose.

One other point to keep in mind is that nothing prevents different object from exposing the same interface.  In fact, this is natural, since all the objects expose the IUnknown interface.  So, for example if we have a COM object named Cat representing a cat, it can expose the ILivingThing interface (which provides the client with the information about whether the cat is alive or dead, and asking it to take a breath).  Likewise if we have a COM object called Martian representing a Martian man, it can expose the ISocialBehavior interface (provided that Martians can have social behavior with us humans and talk to us!).

Parameter types

In COM, we can have some knowledge on what each parameter is supposed to do.  Most significantly, we have three types of parameters: in, out, and retval.  An ‘in’ parameter, as its name suggests, is the input to a function.  For example, in the ISocialBehavior interface above, the pPerson parameter of the TalkToSomeone function is an ‘in’ parameter, because it’s an input for the function so that it knows which person to talk to.  An ‘out’ parameter is the output of a function.  Unlike C++ functions, COM methods and properties have to return HRESULT, so any other output a function might have should be in the form of an ‘out’ parameter.  Note that ‘out’ parameters have to be in form of a pointer, so that the called function can set the value pointed by them.  As an example, in the IPerson interface above, the pAge parameter of GetAge is an out parameter, because it allows the function to return the age of a person.  A ‘retval’ parameter specifies the return value of a function.  In some higher level languages, like Visual Basic, the programmer cannot see the HRESULT return values, so the function can specify a pseudo return value which just seems like a return value, but in essence is an out parameter.  In C++ we don’t have such a thing, so you should treat a ‘retval’ parameter just the same as an ‘out’ parameter.  Only you should know that usually the ‘retval’ comes with ‘out’, and is shown like ‘out, retval’.

A nice combination of parameter types is the ‘in, out’ parameters.  An ‘in, out’ parameter is both an input to a function, and an output as well.  When a function takes an ‘in, out’ parameter, it internally frees the original value of the parameter, and then sets the value to the new value.  But we as the COM client programmers don’t care about it.  The only thing you must keep in mind is that an ‘in, out’ parameter, the value of the variable can be changed after the function called.  Obviously the ‘in, out’ parameters should be pointers.

There is no way to show these types in C++.  The Interface Definition Language (IDL) which I won’t cover in this article has vuilt-in support for these types, but C++ lacks such a support.  To come around this, two techniques are usual: usage of preprocessor macros, and comments:

#define IN
#define OUT
#define RETVAL

interface ISomeIFace : IUnknown
{
HRESULT Method1( IN IUnknown *, OUT ISomeOtherIFace ** ) = 0;
HRESULT Method2( IN OUT long, OUT RETVAL IUnknown ** ) = 0;
};

or

interface ISomeIFace : IUnknown
{
HRESULT Method1( /* in */ IUnknown *, /* out */ ISomeOtherIFace ** ) = 0;
HRESULT Method2( /* in, out */ long, /* out, retval */ IUnknown ** ) = 0;
};

I prefer the latter method.  If we want to specify the parameter types for the Person interfaces, we would have some code like this:

interface IPerson : public IUnknown
{
HRESULT GetName( /* out, retval */ BSTR * pName ) = 0;
HRESULT GetAge( /* out, retval */ long * pAge ) = 0;
};

interface ILivingThing : public IUnknown
{
HRESULT IsLiving( /* out, retval */ BOOL * bLeaving ) = 0;
HRESULT Breathe( void ) = 0;
};

interface ISocialBehavior : public IUnknown
{
HRESULT TalkToSomeone( /* in */ IPerson * pPerson ) = 0;
};

interface IPersonalBehavior : public IUnknown
{
HRESULT EatFood( void ) = 0;
};

Note that the ‘out, retval’ parameters could be ‘out’ parameters without the C++ programmer seeing the difference, but if they’re ‘out, retval’, the other fellow programmers would have an easier time.

This discussion leads us to the next rules of COM client programming:

  1. The interface pointers which are passed as ‘in’ and ‘in, out’ parameters should follow the same rules stated above, so that Release( ) should be called on them after being passed as the parameter when you no longer need the interface pointer.
  2. The interface pointers obtained via ‘out’ and ‘out, retval’ parameters should be Release( )-ed once they are no longer needed.  If the interface pointer is not NULL before being passed as those parameters, Release( ) should be called on it before being passed.

Casting in COM

Here I’m going to discuss one of the biggest mistakes people make when writing client COM code: casting.  I have seen people who freely cast COM interfaces to their heart’s content, and think it’s safe because it would be safe in the normal C++ world.  But the moment you begin to cast a COM interface into another one is the moment you invite malicious bugs and memory corruptions and access violations into your code.  There are only two situations where casting won’t harm: when you cast a pointer to an interface pointer to void**, and where the compiler allows an implicit cast.  The first case is necessary in all calls to CoCreateInstance, IUnknown::QueryInterface and similar functions, where they accept a void** parameter, and you should cast a pointer to an interface pointer to void** using either reinterpret_cast (the preferred method) or the C-style cast (the deprecated and should-be-avoided method).  The second case happens when you use an interface pointer in place of another interface pointer higher in the derivation hierarchy.  For example, you can use the IPerson interface where an IUnknown interface is expected, and the compiler does the cast implicitly.  This cast is completely safe in COM.  Of course in these situations, you can still write the case explicitly (either using static_cast of C-style cast), but I suggest you allow the compiler to do the cast implicitly, so that the compiler catches you where you’re doing an illegal cast.  So, the ninth rule of COM client programming is as follows:

  1. Never cast COM interface pointers using any of the static_cast, dynamic_cast, const_cast, reinterpret_cast, or C-style cast, except the two situations pointed out above.

The prohibition of casting in COM does not mean that COM disables casting; it just shows that C/C++ style casts are not appropriate with COM.  COM provides its own method of casting, which is (as you might guess) the IUnknown::QueryInterface function.  You pass the correct IID, and the QueryInterface function returns the desired interface pointer as its second parameter, or alternatively returns E_NOINTERFACE in case of an illegal/unsupported cast.

  1. Stay with the IUnknown::QueryInterface function to do all the castings between interface pointers as you need.

Methods and properties

In COM, we have two distinct types of functions supported by an interface: a method, and a property.  A method is pretty similar to a C++ member function.  A method usually does some work on the client’s behalf, and returns the result in the form of a HRESULT status code (which can be either a standard code, like S_OK, or a custom code).  A method can take any number of ‘in’ and/or ‘out’, or ‘retval’ parameters.  A property consists of either one or two special ‘get’ and/or ‘put’ methods.  Their names will be in the form of get_Property, and put_Property.  The ‘get’ method retrieves the property’s value, and the ‘put’ method changes it.  A certain property can only have the ‘get method (a read-only property) or only have the ‘put’ method (a write-only property).  If a property is of type TYPE, the get/put functions should be declared like this:

    HRESULT get_Property( /* out, retval */ TYPE * ) = 0;
HRESULT put_Property( /* in */ TYPE ) = 0;

In some higher level languages, like Visual Basic, the syntax for getting or setting a property is simplified like a C++ object’s data member, but in C++ properties are actually the get/put methods, and an interface cannot have any data members like normal C++ classes.

To provide an example, here I change the interfaces of the Person object to use properties:

interface IPerson : public IUnknown
{
HRESULT get_Name( /* out, retval */ BSTR * pName ) = 0;
HRESULT put_Name( /* in */ BSTR name ) = 0;
HRESULT get_Age( /* out, retval */ long * pAge ) = 0;
HRESULT put_Age( /* in */ long age ) = 0;
};

interface ILivingThing : public IUnknown
{
HRESULT get_Living( /* out, retval */ BOOL * bLeaving ) = 0;
HRESULT Breathe( void ) = 0;
};

interface ISocialBehavior : public IUnknown
{
HRESULT TalkToSomeone( /* in */ IPerson * pPerson ) = 0;
};

interface IPersonalBehavior : public IUnknown
{
HRESULT EatFood( void ) = 0;
};

In the above example, the IPerson interface has two properties, Name and Age, which can be both read and changed, and the ILivingThing interface has one read-only property, Living.

COM runtime initialization

Like many libraries available, the COM library must also be initialized before being used.  You should use the CoInitialize function to initialize the COM library, and the CoUninitialize function to allow the COM library to clean up.  CoInitialize takes only one parameter which should always be set to NULL, and CoUninitialize does not take any parameters.

Because this is such a common task, I have written a class called CComInit as follows:

class CComInit
{
public:
CComInit(void)
{
::CoInitialize( NULL );
}

~CComInit(void)
{
::CoUninitialize();
}
};

To use this class, it’s enough to create a global object of this class in one of the .cpp files of your project.  This way you can be sure that usage of COM from your application will always be safe.  Note that if your application is multi-threaded, you need to create an object of this class inside each thread of your application which will use the COM API or COM objects.  You can just create an object of this class in your thread entry point function’s stack so that it would be created when the thread starts, and would be destroyed when the thread terminates.  This ensures that the COM library is safely available to your code during the whole life time of your thread.

Strings and COM

Strings in COM are the source of much confusion for almost every beginner COM client programmer.  In C, a string is usually represented as a char*.  In C++, we have a more advanced string, which is the std::string class.  In COM1, a string is something different.  We represent a string using a BSTR in COM.  A BSTR is a typedef for an array of wchar_t elements, and wchar_t is (according to the C++ standard) a built-in type to represent wide characters (but it’s a typedef to unsigned short in compilers like VC++ 6, but fortunately it’s been fixed in VC++ .NET).  In other words, a BSTR looks like a Unicode string.  If you have never worked with Unicode strings, check out my Unicode article.  But a BSTR has some additional properties which is beyond the scope of this topic, but the most important one is that it can contain NULL characters, unlike C/C++ strings, where a NULL character means the end of the string.

You create a BSTR using one of the SysAllocString, SysAllocStringByteLen, or SysAllocStringLen functions.  Of the three, the former and the latter are of most use.  They both take a constant Unicode string as their first parameter, and return a BSTR which is a copy of the Unicode string passed to them.  SysAllocStringLen also has a second parameter which specifies the length of the string.  SysAllocString assumes the Unicode string is NULL terminated, and calculates its length using the lstrlenW function.  To free the BSTR when you’re done with it, you call SysFreeString.  You can change the size of an existing BSTR using one of the SysReAllocString or SysReAllocStringLen functions.  To get the length of the BSTR, you call the SysStringLen or SysStringByteLen functions.  Please see the Platform SDK Documentation for more information on these functions.

If you keep in mind that can contain embedded NULL characters, you’re safe to use the wcsxxx functions to manipulate the BSTRs.  There are some classes like _bstr_t (declared in comutil.h), and CComBSTR (declared in atlbase.h) which can simplify working with BSTRs.  You can also use the ATL Conversion Macros (check out the Unicode article) to convert from BSTRs to C strings, and vice versa.  To work with strings in COM, keep in mind that you should follow rules 7 and 8 for BSTRs as well.  Of course you call SysFreeString on a BSTR instead of Release( ).

Enough theory, let’s see it in action

OK, now you need almost everything you know to get started in writing COM client code for C++.  Of course, there are dozens of details which are left unspoken in this article, but covering all of them requires a book or two.  You know enough to start surfing in the MSDN and reading up books to get a firm grasp on COM.  But no theory has the effect of a piece of sample code.

I wrote a simple Win32 SDK application to demonstrate the topics discussed in the article.  The sample application which is called Wallpaper (and you can download it at the bottom of the article) does a very simple task: displaying the location of the wallpaper picture selected by the user, and changing it.  To perform this task, the sample utilizes the IActiveDesktop interface offered by the Active Desktop component.  Here is the relevant pieces of the source code:

bool Initialize()
{
if (!pActiveDesktop)
{
HRESULT hr = ::CoCreateInstance( CLSID_ActiveDesktop, NULL,
CLSCTX_INPROC_SERVER, IID_IActiveDesktop,
reinterpret_cast< void ** > (&pActiveDesktop) );
return SUCCEEDED(hr);
}
else
return true;
}

void Destroy()
{
if (pActiveDesktop)
{
pActiveDesktop->Release();
pActiveDesktop = NULL;
}
}

bool GetCurrentWallpaper(LPTSTR pszBuffer, DWORD cch)
{
if (!pActiveDesktop && !Initialize())
return false;

LPWSTR pwsz = reinterpret_cast< LPWSTR > (::_alloca( cch * sizeof(WCHAR) ));
HRESULT hr = pActiveDesktop->GetWallpaper( pwsz, cch, 0 );
if (SUCCEEDED(hr))
{
USES_CONVERSION;
::lstrcpyn( pszBuffer, W2CT( pwsz ), cch );
return true;
}
else
return false;
}

bool SetCurrentWallpaper(LPCTSTR pszBuffer)
{
if (!pActiveDesktop && !Initialize())
return false;

USES_CONVERSION;
HRESULT hr = pActiveDesktop->SetWallpaper( T2CW( pszBuffer ), 0 );
pActiveDesktop->ApplyChanges( AD_APPLY_ALL );
return SUCCEEDED(hr);
}

As you see, the code seems extremely easy.  And in fact, when you respect the rules in COM client coding, the whole process is easy!  So, welcome to the world of COM!

Glossary

Here is a list of the terminology used in this article which might be new to you, together with a short definition for them.

COM
A binary standard which allows objects communicate with each other at runtime without respect to the language they are developed in. [back]

COM object, CoClass
An object which adheres to the rules of COM.  Not to be confused with a C++ object.  There is a subtle difference between COM objects and CoClasses which is like the difference between C++ objects and classes.  Objects live in memory, CoClasses are specifications of those objects (i.e. what interfaces they support). [back]

Client COM
Code which utilizes a COM object. [back]

Server COM
Code which implements a COM object. [back]

COM interface
A set of contracts (expressed in terms of functions) which a COM server promises to fulfill and a COM client can depend upon. [back]

IUnknown
The mother of COM interfaces: the interface which all other COM interfaces should derive from either directly or indirectly, and the only possible interface which does not derive from an interface.  It provides a basic set of functionality (reference counting and runtime polymorphism) which all COM objects must support. [back]

GUID, UUID
A 128-bit unique identifier used to identify things in COM world. [back]

CLSID
A GUID for identifying a CoClass. [back]

IID
A GUID for identifying an interface. [back]

LIBID
A GUID for identifying a library. [back]

HRESULT
The standard return value for all COM functions and methods stating a success/error status. [back]

Acknowledgements

Max provided some nice comments on the first version of this article which lead to some improvements in the structure and understandability of this work.  Thanks a lot, Max!

 Download source code for the article


Footnotes:

1 – Strictly speaking, COM itself has no definition of a string like BSTRs.  BSTR is the standard string type in Automation, one of the technologies based upon COM.  Because of the reasons that fall outside the scope of this article, it’s preferred to use BSTRs to represent strings in COM as well, but nothing prevents the developer of a COM server from using C style strings in designing her interfaces.

This article originally appeared on BeginThread.com. It’s been republished here, and may contain modifications from the original article.

Changing IE Show Picture Setting

The following sample program demonstrates how to change the Internet Explorer Show Picture setting.  This program toggles the state of this setting.  Note the usage of the SendMessageTimeoutW function with the WM_SETTINGCHANGE message that causes all the open instances of IE to update themselves.  If you use SendMessageW instead, and a window procedure for some window on the system falls into an infinite loop for some reason, then, your process would also stop responding.  Here’s the sample program.  Note that this is a Unicode program, so it doesn’t run on Win95/98/Me.  However, making this an ANSI application is a trivial task, as I’ve done it below the Unicode source code:

int __stdcall wWinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HKEY hkey;
DWORD dwType = REG_SZ;
BYTE pData[100];
DWORD cbSize = 100;
BYTE pDataToWrite[100];
DWORD cbSizeToWrite = 100;
::ZeroMemory( pData, sizeof(BYTE) * cbSize );
::ZeroMemory( pDataToWrite, sizeof(BYTE) * cbSizeToWrite );
DWORD dwResult;

WCHAR szRegKey[] = L"Software\\Microsoft\\Internet Explorer\\Main\\";

LONG lRet;

try
{
lRet = ::RegOpenKeyExW( HKEY_CURRENT_USER,
szRegKey,
0, KEY_READ | KEY_WRITE, &hkey );
if (ERROR_SUCCESS != lRet)
throw L"Failed to open the Internet Explorer registry key.";
lRet = ::RegQueryValueExW( hkey, L"Display Inline Images", NULL,
&dwType, pData, &cbSize );
if (ERROR_SUCCESS != lRet)
throw L"Failed to read the registry value.";

if (::lstrcmpiW( (LPCWSTR) pData, L"yes" ) == 0)
::lstrcpyW( (LPWSTR) pDataToWrite, L"no" );
else
::lstrcpyW( (LPWSTR) pDataToWrite, L"yes" );

cbSizeToWrite = (::lstrlenW( (LPCWSTR) pDataToWrite ) + 1) * sizeof(WCHAR);

lRet = ::RegSetValueExW( hkey, L"Display Inline Images", 0, REG_SZ,
pDataToWrite, cbSizeToWrite );
if (ERROR_SUCCESS != lRet)
throw L"Failed to set the registry key value.";

::RegCloseKey( hkey );

::SendMessageTimeoutW( HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) szRegKey,
SMTO_ABORTIFHUNG | SMTO_BLOCK, 3 * 1000, &dwResult ); // wait 3 seconds on each window
}
catch (WCHAR * pwsz)
{
::MessageBoxW( ::GetDesktopWindow(), pwsz, L"Error", MB_OK | MB_ICONSTOP );
}
return 0;
}

Here’s a version of the same program that can be compiled using both Unicode and ANSI modes.

int __stdcall WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
HKEY hkey;
DWORD dwType = REG_SZ;
BYTE pData[100];
DWORD cbSize = 100;
BYTE pDataToWrite[100];
DWORD cbSizeToWrite = 100;
::ZeroMemory( pData, sizeof(BYTE) * cbSize );
::ZeroMemory( pDataToWrite, sizeof(BYTE) * cbSizeToWrite );
DWORD dwResult;

TCHAR szRegKey[] = _T("Software\\Microsoft\\Internet Explorer\\Main\\");

LONG lRet;

try
{
lRet = ::RegOpenKeyEx( HKEY_CURRENT_USER,
szRegKey,
0, KEY_READ | KEY_WRITE, &hkey );
if (ERROR_SUCCESS != lRet)
throw _T("Failed to open the Internet Explorer registry key.");
lRet = ::RegQueryValueEx( hkey, _T("Display Inline Images"), NULL,
&dwType, pData, &cbSize );
if (ERROR_SUCCESS != lRet)
throw _T("Failed to read the registry value.");

if (::lstrcmpi( (LPCTSTR) pData, _T("yes") ) == 0)
::lstrcpy( (LPTSTR) pDataToWrite, _T("no") );
else
::lstrcpy( (LPTSTR) pDataToWrite, _T("yes") );

cbSizeToWrite = (::lstrlen( (LPCTSTR) pDataToWrite ) + 1) * sizeof(TCHAR);

lRet = ::RegSetValueEx( hkey, _T("Display Inline Images"), 0, REG_SZ,
pDataToWrite, cbSizeToWrite );
if (ERROR_SUCCESS != lRet)
throw _T("Failed to set the registry key value.");

::RegCloseKey( hkey );

::SendMessageTimeout( HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) szRegKey,
SMTO_ABORTIFHUNG | SMTO_BLOCK, 3 * 1000, &dwResult ); // wait 3 seconds on each window
}
catch (TCHAR * psz)
{
::MessageBox( ::GetDesktopWindow(), psz, _T("Error"), MB_OK | MB_ICONSTOP );
}
return 0;
}

This article originally appeared on BeginThread.com. It’s been republished here, and may contain modifications from the original article.

Unicode

If you have developed applications for Windows, probably you’ve heard about Unicode before.  What is Unicode, and how to use it in writing a program?  These are the questions I try to answer in this article.

What is Unicode?

Unicode is nothing but a set of standards for a character-coding system.  Unicode expects each character to be two bytes wide, instead of the normal one-byte wide ANSI characters.  So, we can have 65,536 different characters in a Unicode character set.  This is room enough for characters of all the current languages of the world, plus a wide free range that can be used for indicating symbols.  The Platform SDK documentations for Unicode can be found at Platform SDK\Base Services\International Features\Unicode and Character Sets.

Unicode and C/C++

To implement Unicode in C/C++, you should consider learning about wide characters. Wide characters are characters that consist of two bytes.  So, wide characters are a good candidate for writing Unicode applications in C/C++.  As you know, the data type for a simple character in C is the char type.  The data type for a wide character is wchar_twchar_t is defined like this inside stdlib.h:

typedef unsigned short wchar_t;

You can use wchar_t instead of char anywhere.  For example, to declare a wide character string, you can write code like this:

wchar_t * pwszMyString = "This is my wide character string";

Well, to correct myself, you can use wchar_t instead of char *almost* anywhere.  What does the above code try to do?  It tries to assign a literal string (which is a pointer to a normal character, or a char *) to a pointer to type wchar_t, or unsigned short.  What will it cause?  A compile error.  So, what should you do?  Should you just make an array of unsigned shorts?  The answer is no.  The Microsoft’s C/C++ compiler that comes with Visual C++ helps you quite a bit.  If you prefix a literal string by a L, the compiler considers that string to be a wide character string, instead of a normal string.  So, to correct the above code, all you need to do is to put a L right before the starting quotation mark (note that there shouldn’t be any spaces between the L and the quotation mark):

wchar_t * pwszMyString = L"This is my wide character string";

One thing to note.  The following pieces of code are the same, because for literal characters, the compiler automatically adds a byte containing zero to the character is it is being a wide character.

wchar_t wc1 = L'A';
wchar_t wc2 = 'A';

Unicode and the Standard C/C++ Library

The standard C/C++ library does support wide characters.  Suppose you want to calculate the length of a wide character string.  If you just call strlen on it, you won’t get the desired result.  Because strlen searches the string char by char, which is byte by byte, not character by character.  You get the difference?  A character could be one byte (char) or two bytes (wchar_t).  But the char data type is always one byte, no matter the application is Unicode or not.

For every C/C++ library function that deals with normal character strings, there is an equivalent for wide characters.  For functions which have "str" in their names, the wide character version has the same name with "wcs" instead of "str".  Like wcslen, wcschr, wcsstr, wcscmp, wcscpy, wcsrchr, wcscat, wcscoll, wcscpyn, wcscspn, wcsicmp, wcsdup, wcsftime, wcslwr, wcsupr, etc….  For other functions, there are also wide character versions, for example, swprintf for sprintf, _wfopen for fopen, _getws for gets, etc….

You’ll use these "wcs" functions just as you use the normal character functions.  Only you should pass wchar_t‘s to them, and also expect to get back wchar_t‘s.  Just to demonstrate:

size_t length = wcslen( L"My String" );
// length will be 9

Unicode and the Windows API

Windows 95 and 98 were built upon 3.1, and they don’t support Unicode.  All the applications written for Windows 98 should be ANSI applications.  Microsoft has considered Unicode from the beginning of the NT project, so Windows NT (and its ancestors,2000, and XP) support Unicode from the ground up.  So, applications that are to be run on NT systems should be Unicode.  So, how come there are applications that work on both 98 and NT systems for example?  The reason is that Windows NT supports a translation layer between Unicode and ANSI.  Whenever an application calls an ANSI function, system allocates a buffer for the strings used in that function, converts the ANSI strings to Unicode strings, and calls the Unicode version of the function with the Unicode temporary buffers as parameters.  After that call returns, the ANSI function is responsible to free the buffers allocated.  So, this translation layer is completely invisible to the application, and hence, to the application developer.  But, this translation involves some overhead of allocating buffers, and converting ANSI text to Unicode and vice versa.  So, if an application is only targeted for NT platforms, the Unicode versions should run faster than the ANSI versions.

Now, let’s take a look at the Unicode system at the API level.  Consider the function CreateFile.  Microsoft documents this function to be located in kernel32.dll.  So, now open up the DEPENDS.EXE tool, and open kernel32.dll.  Surprisingly, you won’t find any exported symbol named CreateFile.  So, is Microsoft lying?!  Not really.  If you look again, you’ll see two other functions:  CreateFileA, and CreateFileW.  The A stands for ANSI, and the W stands for wide character.  CreateFileA is the ANSI version of CreateFile, and CreateFileW is the wide character version of CreateFile.  CreateFile is actually only a preprocessor macro, defined like this:

#ifdef UNICODE
#define CreateFile CreateFileW
#else
#define CreateFile CreateFileA
#endif

The UNICODE symbol, as well as the _UNICODE symbol, indicate that you want to build a Unicode application or not.  If you define UNICODE and _UNICODE before including the header files, your application would be Unicode.  If you don’t define them, which is the default mode, you’ll have an ANSI application.  So, what is a Unicode/ANSI application?  A Unicode application is an application that calls wide character versions of API functions, and uses wide character strings internally, and an ANSI application is an application that calls ANSI versions of API functions, and uses ANSI strings internally.

There are two important points.  The first one is that some API functions, like GetDC, don’t have anything to do with strings at all, so they have only one version that is usable by both ANSI and Unicode applications.  The second note is that actually Windows 98 a handful of Unicode APIs, which are listed in the below table.  Other than these functions, the system DLLs for Windows 98 have export symbols for wide character functions as well, but they all return FALSE, and GetLastError would return ERROR_CALL_NOT_IMPLEMENTED which is defined as 120.

Unicode functions implemented on Windows 98

EnumResourceLanguagesWGetTextExtentPoint32W
EnumResourceNamesWGetTextExtentPointW
EnumResourceTypesWlstrlenW
ExtTextOutWMessageBoxExW
FindResourceWMessageBoxW
FindResourceExWTextOutW
GetCharWidthWWideCharToMultiByte
GetCommandLineWMultiByteToWideChar

Only I should mention a point here.  Some programmers think that because Windows 98 doesn’t support Unicode, they can’t use wcslen for example on Windows 98.  This is completely wrong!  wcslen is not a part of the Windows operating system, but a part of standard ANSI C/C++ runtime library.  So, it’s implemented on Windows 98 as well.

So, these macros defined in the Windows header files enable you to write Unicode-compatible code, which you can compile in Unicode mode only by defining two preprocessor symbols, UNICODE and _UNICODE.  (Actually UNICODE symbol is used in the Windows header files, and _UNICODE is used in the headers of Microsoft C/C++ runtime library.)  But, this is not enough.  How should you handle string literals, and char/wchar_t data types?  One possible way is to write your code like this:

#ifdef UNICODE
MessageBox( NULL, L"My message", L"My caption", MB_OK );
#else
MessageBox( NULL, "My message", "My caption", MB_OK );
#endif

Although it works, but it’s overkill.  You must have #ifdef’s all around your code, making it less manageable and readable.  One better solution is provided with the tchar.h header file.

The Generic Macros

The generic macros which are defined in tchar.h are used to write a single source code that can be compiled for both Unicode and ANSI.  Tchar.h solves three problems:

  1. Data Types
    Tchar.h defines the data type TCHAR.  Here’s a rough definition of TCHAR:

    #ifdef _UNICODE
    typedef wchar_t TCHAR;
    #else
    typedef char TCHAR;
    #endif

    So, the TCHAR data type automatically maps to the correct version of character data type according to whether the application is Unicode (the _UNICODE symbol is defined) or not.  This solves the problem of defining compatible data types for Unicode and ANSI applications.

  2. String Literals
    If you write such a code using the TCHAR data type, your code won’t compile fine in Unicode mode.

    TCHAR szMyString[ ] = "My String";

    Why?  Because if you compile your application in Unicode mode, the compiler tries to assign a pointer to type char to a pointer to type unsigned short, and that’s not acceptable.  Again, if you write your code like below, you’ll again get compile errors.

    TCHAR szMyString[ ] = L"My String";

    If you compile the above code in ANSI mode, you’ll be trying to assign a pointer to type unsigned short to a pointer to type char, which again is not acceptable.  Tchar.h offers a solution to this problem.  You must put any string literal inside a _T macro, like this:

    TCHAR szMyString[ ] = _T("My String");

    If you’re building ANSI, the _T macro expands to nothing, and it is just removed.  However, if you build for Unicode, the _T macro expands to a capital letter L, which is what identifies a wide character string.  This is just what we needed, no?!  Note that the _T macro is defined in other forms, like _TEXT, and TEXT (the latter is defined in the Windows header files), but because typing _T is the simplest form, I myself always use it instead of the other forms.

  3. Standard Library Functions
    As we saw before, the Windows API functions are defined using preprocessor macros to be mapped to the correct version of the API functions.  For example, lstrlen, which is the API equivalent to strlen, is actually in two forms of lstrlenA, and lstrlenW, for normal and wide characters.  So, it’s completely OK to write code like this:

    TCHAR szMyString[ ] = _T("My String");
    int length = lstrlen( szMyString );

    But, if you decide to use strlen instead of lstrlen, boom!  You’ll get build problems all the time for Unicode mode.  Tchar.h helps you by defining the generic form of all the C/C++ runtime functions that have two versions for normal and wide character strings.  Usually for functions with "str" or "wcs" in their names, you can replace them by "_tcs" to get the generic form of functions, like _tcslen, _tcsstr, _tcsupr, and so on.  For other functions, there are similar generic forms as well.  For instance, the generic form of fopen and _wfopen is _tfopen.  You can find the generic forms of all these functions by looking at MSDN documentation for each function.

Writing Unicode-compatible Source Code

Writing Unicode compatible source code has an advantage even if you don’t want to build Unicode at this time.  It can free you from having two source code file sets, one for ANSI and one for Unicode.  It makes it possible to build a Unicode version at any time without having to change even one line in the source code.  Only you’ll need to follow a set of rules.

  1. Use TCHAR instead of char.  This solves the problem of incompatibilities between char and wchar_t data types.
  2. Wrap all the string literals inside a _T macro.   This would let the compiler know whether to consider the string literals as normal or wide character.
  3. Use the generic form of Standard Library as well as API functions.  For example, use _tcslen or MessageBox instead of strlen or MessageBoxA.
  4. Never assume that sizeof( character ) == 1!
    Of course, no matter your application is Unicode or ANSI, always the size of char data type is equal to 1, but the size of a character (which may be normal or wide character varies.  Always try to use sizeof( TCHAR ).  For example, instead of writing code like this:

    //allocate a 100-character string
    TCHAR * pszString = (TCHAR *) malloc( 101 );

    write it like this:

    //allocate a 100-character string
    TCHAR * pszString = (TCHAR *) malloc( 101 * sizeof(TCHAR) );

    Because in wide character version, size of each character is 2 bytes, so 202 bytes should be allocated for a 100 character string (of course, the last 2 bytes would be for the terminating NULL character, 0x0000).

Using these guidelines, you can write source code that compiles fine for both ANSI and Unicode versions.

Also it’s useful to point out some other macros defined in the Windows header files.  LPCTSTR or PCTSTR defines a generic constant pointer to a string.  You may consider the definition of these macros like this in winnt.h:

typedef char CHAR;
typedef wchar_t WCHAR;

typedef WCHAR * LPWSTR, * PWSTR;
typedef const WCHAR * LPCWSTR, * PCWSTR;

typedef CHAR * LPSTR, * PSTR;
typedef const CHAR * LPCSTR, * PCSTR;

#ifdef UNICODE
typedef LPWSTR LPTSTR, PTSTR;
typedef LPCWSTR LPCTSTR, PCTSTR;
#else
typedef LPSTR LPTSTR, PTSTR;
typedef LPCSTR LPCTSTR, PCTSTR;
#endif

These macros are extensively used in Windows header files.  So, the following lines of code are identical:

LPTSTR pszString = TEXT("My String");
TCHAR * pszString = _T("My String");

And only it’s a matter of preference to pick up which one to use.

Conversion Macros

The ATL library offers a set of conversion macros declared in atlconv.h.  These conversion macros simplify the task of converting between Unicode and ANSI strings.  Normally, you convert Unicode strings to ANSI strings using the WideCharToMultiByte function, and ANSI strings to Unicode strings using the MultiByteToWideChar function.  But that offers a lot of work to do.  For using the conversion macros (see MFC technical note 59) you first invoke the USES_CONVERSION macro that creates a number of stack variables, and then, you use the macros as appropriate.  Here’s a list of all macros with information on what type they convert from, and their return types.

Conversion Macros

macrofrom typeto type
A2WPSTRPWSTR
W2APWSTRPSTR
A2CWPSTRPCWSTR
W2CAPWSTRPCSTR
T2COLEPTSTRPCOLESTR
OLE2CTPOLESTRPCTSTR
T2OLEPTSTRPOLESTR
OLE2TPOLESTRPTSTR
A2OLEPSTRPOLESTR
OLE2APOLESTRPSTR
W2OLEPWSTRPOLESTR
OLE2WPOLESTRPWSTR
A2COLEPSTRPCOLESTR
OLE2CAPOLESTRPCSTR
W2COLEPWSTRPCOLESTR
OLE2CWPOLESTRPCWSTR
T2APTSTRPSTR
A2TPSTRPTSTR
T2WPTSTRPWSTR
W2TPWSTRPTSTR
T2CAPTSTRPCSTR
A2CTPSTRPCTSTR
T2CWPTSTRPCWSTR
W2CTPWSTRPCTSTR
A2BSTRPSTRBSTR
W2BSTRPWSTRBSTR
T2BSTRPTSTRBSTR

Note:  POLESTR and PCOLESTR are identical to PWSTR and PCWSTR in Win32 environments when OLE2ANSI preprocessor macro is not defined.  For Win16, Macintosh, and Win32 with OLE2ANSI defined, POLESTR and PCOLESTR are identical to PSTR and PCSTR.

Here’s an example of using these conversion macros in action:

USES_CONVERSION;
TCHAR szFunctionName[ 100 ];
GetWindowText( hwndEditControl, szFunctionName, 100 );
HMODULE hMod = LoadLibrary( _T("mydll.dll") );
FARPROC pProc = GetProcAddress( hMod, T2CA( szFunctionName ) );
FreeLibrary( hMod );

Because GetProcAddress function receives a PCSTR parameter, and szFunctionName is a PTSTR, we have used the T2CA macro to convert the Unicode string to an ANSI string, and pass to the GetProcAddress function.

You don’t need to memorize the whole table of conversion macros.  For a tip on how to remember them, consider the following points.

  • Each macro name is consisted of two parts, the "from" part and the "to" part, separated by a ‘2’:  from2to.  Sometimes the "to" part receives a ‘C’ prefix, which indicates the return value is a constant pointer, like A2T and A2CT.  The "from" part never receives a ‘C’ prefix.
  • Here’s a list of the letters acceptable for "from" and "to", as well as their respective types:
    letter(s)type
    APSTR
    WPWSTR
    TPTSTR
    OLEPOLESTR
    BSTRBSTR

    Also note that the BSTR type does not get the ‘C’ prefix, and is specific to the "to" part.

These conversion macros come handy mostly in writing COM code.  COM expects all the strings to be Unicode strings, even on Windows 98.  Suppose you have an application that reads an ANSI text string from an edit control, passes it to a COM method, and retrieves another string from the COM method, and prints in on a window.  This application should first convert the ANSI string into Unicode to pass it to the COM method, and then convert the string returned by the COM method from Unicode back to ANSI, and then print it on the screen.  Writing this code could involve a lot of coding just to convert the strings from Unicode to ANSI and vice versa, but using the conversion macros, it would be as easy as a piece of cake!


Now you have all the knowledge you need to make your program support Unicode.  Here I want to mention some point that many programmers are confused with.  Categorizing applications as Unicode and ANSI is only meaningful to application developers.  According to the system, there’s no difference between a Unicode and an ANSI application at all.  Unicode applications often call wide character versions of API function, whereas ANSI applications call the normal character versions.  But, this is completely possible to use Unicode functions explicitly in an ANSI application and vice versa.  Consider the following sample that could be a piece of code in an ANSI application which runs pretty fine on both Windows 98 and Windows NT:

MessageBoxW( NULL, L"A Unicode string", L"test", MB_OK );

Also, nothing can prevent you from calling an ANSI function from a Unicode application.  Only you should consider data type compatibility, and you should revise your algorithms so that they consider that a character can be either one or two bytes long, and is not guaranteed to be a single byte.

For a sample of a Unicode application that is revised to be compiled on both Unicode and ANSI modes, see the article Changing IE Show Picture Setting.

This article originally appeared on BeginThread.com. It’s been republished here, and may contain modifications from the original article.

Standard Persian Keyboard For Windows

Persian users have historically had many problems with the level of Persian support on the Windows operating system.  I do not plan to go through a description of these problems in this article, but I would like to mention one serious problem: lack of the standard Persian keyboard.  The Persian Keyboard Layout exists as a national standard (ISIRI 2901:1994) and is supposed to be updated soon.

FarsiWeb has done an excellent job of providing the new layout as a keyboard driver for Windows, and made it available on SourceForge.  Unfortunately this keyboard driver has a small (but very annoying) problem, which is the Shift+Space combination.  Shift+Space is supposed to create a ZWNJ character (so that for example words such as می‌روم can be typed correctly), but using this keyboard driver, it only creates a normal space.

This is actually a bug in the MKLC tool used to build this driver.  MKLC is a proprietary tool available from Microsoft which allows users to define a keyboard layout visually, and creates a driver installation package from it.  MKLC has a bug which does not allow a character to be specified for the Shift+Space combination.  I had solved this problem with a bit of hacking back in 2004, and I’m publishing the details as well as the resulting keyboard driver (which handles Shift+Space correctly) here.  I had tried to submit this work to FarsiWeb guys so that they would update the driver on the SourceForge page, but unfortunately they didn’t seem to be interested.

MKLC works like this: it generates a .c file containing the keyboard definition, and uses a stripped down version of the Visual C++ compiler which comes with it to compile this driver and link it against the necessary Windows libraries.  In order to intercept this process, I wrote a program called shim, which simply printed all of its command lines inside a file.  I then replaced the compiler executable coming with MKLC (cl.exe) with my shim.exe program and re-built the keyboard driver from within MKLC, which gave me some C source code to hack, plus the required commands to compile and build the driver.  I then modified the resulting Persian.c file to change the Shift state key code to 0x200C (which is the hex code for ZWNJ) and ran the compilation command manually, resulting in an installer which can be used to install the corrected driver.

You can grab the source and installer files below.  The installer is what most users want.  It has been tested on Windows XP and Vista.  After installing it, you should add a "Persian experimental standard" keyboard layout from the Regional and Language Options applet in the Control Panel.

Persian Keyboard Installer
Source Files

Update 1: It seems that the installer package cannot be installed on Windows Vista SP1 if UAC is enabled.  To work around this problem, you need to disable UAC before and after trying to install this package.

Update 2: I ported the hack to MKLC 1.4, which generates a setup package for all 64-bit flavors of Windows, including Itanium 64-bit, x64-64 and WoW64.  I have updated the download links for the new version.  If for some reason, you are interested in the older version, you can grab them below:

Persian Keyboard Installer (Note: older version — you probably want the newer version above.)
Source Files (Note: older version — you probably want the newer version above.)

Update 3: There is now an improved version of the keyboard layout available for download by Behnam Esfahbod.  You should really consider using this version of the keyboard.  I’m keeping the original version of the article for historical reference.

Win32 Thread Facility

Traditionally, Win32 threads are implemented using C-style global functions which accept an LPVOID parameter, return a DWORD value, and have the stdcall calling convention.  This is fine for simple and small threads, but it can cause difficulties when writing a complicated thread which needs to call several other functions, or designing an object-oriented thread model.  If one is limited solely with this option, she either has to handcraft some mechanism to turn the old-style free thread proc function into C++ code using classes, which can be repeating, and thus boring, and thus very error-prone.

There are solutions to this problem.  One can use the MFC CWinThread class mechanism together with AfxBeginThread( ), or can write her own threading mechanism in C++.  I have personally chosen the second path for two reasons.  The first one is MFC CWinThread mechanism uses a message loop internally, and many threads don’t need one, so inviting CWinThread into the picture of your project can both cause inefficiency as well as needless complexity.  The second reason is I don’t like the MFC type detection model (using the RUNTIME_CLASS macro) and I think when the language offers this feature in form of C++ templates, one should not invent a new mechanism of his own.

The CWin32Thread class together with two thread creator classes provide the functionality I’ve been after.  CWin32Thread serves two purposes.  It wraps a Win32 thread handle (a HANDLE data type) and provides convenience member functions to manipulate it, and it has the role of a base class for your own thread types.  It is an abstract base class, which means it can’t be instantiated directly.  It is copyable, however, so that your derived thread classes can have copy constructors, as well as assignment operators of their own, if appropriate.

Writing your own thread class is extremely easy.  You typically derive from CWin32Thread like this:

class CThreadClass :
public CWin32Thread // uses public inheritance
{
public:
CThreadClass(); // default constructible

// any possible additional member functions

// CWin32Thread overridables
private:
// Initialization
virtual bool OnInitialize();
// Termination
virtual void OnTerminate();
// The main thread function
virtual UINT Main();

private:
// any possible data members
};

You should always override the CWin32Thread::Main( ) function, because it’s a pure virtual function, and without overriding it your thread class can’t be instantiated.  This is the thread’s main function, which, upon returning, causes the thread to terminate.  The UINT return value of this function is assigned to the thread’s return value when all the job is done.  There are two other virtual functions, which you can override.  OnInitialize( ) is the function which should do the thread’s initialization.  If this function returns false, then the thread is terminated, assuming some initialization code has failed.  The OnTerminate( ) function is supposed to do the thread’s cleanup and anything else which needs to be done during thread’s termination.  These two functions can be left unimplemented, and in that case their default base class versions are called which simply do nothing.  Another point to pay attention to is the thread class can be default constructible, and also derive publicly from CWin32Thread; otherwise the code will fail to compile.

CWin32Thread has a lot of other convenience helper functions, which are adequately documented in Win32Thread.h (which comes in the ZIP package downloadable from the bottom of this article – so I won’t describe them here again.

There are two other utility classes in the library which are used to create threads.  The first one to describe here is a template class called CWin32ThreadCreator.  This class has a single template parameter which should be assigned the name of your thread class.  It has a CreateThread( ) static function which creates a thread of the specified class, and returns a pointer to it, or NULL if it encounters any errors.  To see a documentation of the parameters this function accepts, check out the Platform SDK documentation for the function ::CreateThread( ).  You create a thread of your thread class by simply writing:

CThreadClass * pThread = CWin32ThreadCreator< CThreadClass >::CreateThread();

if (pThread) // if thread started successfully
{
// do anything appropriate
}
else
{
// handle the error
}

Please remember that the library automatically deletes the returned pointer, so you should never call delete on it yourself, or the results are undefined.  Also, please don’t store the pointer for later use, because there’s no guarantee when the spawned thread terminates and the pointer is deleted.  If you need to store the information about the thread in some variable (for example, m_myThread), define it as a CWin32ThreadInfo variable, and write:

// start the thread as paused
CThreadClass * pThread = CWin32ThreadCreator< CThreadClass >::CreateThread(
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED );

if (pThread) // if thread started successfully
{
m_myThread = *pThread; // store the thread information

// ...

// resume the thread (so that it starts its job)
if (pThread->ResumeThread())
{
// success ...
}
else
{
// error ...
}
}
else
{
// error ...
}

CWin32ThreadInfo class is the class responsible for wrapping the thread handle and information, and is a base class of the CWin32Thread class.  Alternatively, you can define m_myThread of type CThreadClass, which, indirectly would derive from CWin32ThreadInfo.

Another class which can be used to create threads is CWin32ProcThreadCreator.  This class is used to create threads which use an old style free function as their thread procedure.  This class is not a template class, and provides a static CreateThread( ) function which accepts several parameters.  The first one is the address of the free function used to implement the thread’s procedure, and the second one is the LPVOID parameter passed to the thread procedure routine.  The rest of the parameters are identical to those of CWin32ThreadCreator::CreateThread( ).  You use this class to create a thread like this:

CWin32Thread * pThread = CWin32ProcThreadCreator::CreateThread( &::ThreadProc, pParams );

And then you can test pThread against NULL to see if the thread creation has failed or not.  Needless to say, ThreadProc would be declared as:

DWORD WINAPI ThreadProc(LPVOID pv);

This is pretty much everything you need to know to use the library.  For more information, consult the header file (Win32Thread.h) and the source file (Win32Thread.cpp).

The sample application which is included in the ZIP package downloadable from the bottom of this article in an MFC dialog application with two threads, which are completely identical, except that one is class based and the other is procedure based.  See the source code of the application (especially TestProcThread.h/cpp and TestClassThread.h/cpp to see what changes should be made to the code when converting from a procedure based thread to a class based one, and vice versa.

 Download source code and sample application

This article originally appeared on BeginThread.com. It’s been republished here, and may contain modifications from the original article.

Persian Sorting for MySQL

It seems like sorting Persian strings stored in a MySQL database is a common problem to many people who develop web-based database applications that support Persian.  I’ve been asked about this problem numerous times, and I’ve decided to write an article about the issue, and present my own solution to it as well.

The problem

Speaking in plain, non-technical words, MySQL versions up to 4.0.x don’t support Unicode, so any language (Persian included) which needs to use a Unicode encoding system (such as UTF-8) is not supported.  If you’re curious about more technical details, read on; otherwise, feel free to skip the next paragraph.

MySQL versions up to the 4.0.x series do not have support for Unicode strings.  All of its support for multilingual data is by use of code-page based encoding systems.  Unfortunately, Persian is not among the languages it supports.  If Persian used a fixed-length encoding system, then it was possible to write a special collation algorithm and feed it to MySQL for proper sorting of Persian strings, but MySQL 4.0.x doesn’t support variable length encoding systems, and since in UTF-8 (the standard encoding system for Persian) the length of UTF-8 characters varies between 1 and 4 bytes, there is no way to add support for Persian collation (and other string manipulation features) in MySQL 4.0.x, unless you wouldn’t mind reading and patching a huge database source code that has no built-in support for Unicode.

Later MySQL versions

The Unicode Consortium defines a global collation algorithm which is able to sort all languages in the Unicode coding system (practically, all languages spoken on the Earth).  MySQL 4.1.x and 5.x are more Unicode compliant, and support UTF-8 internally, so the problem should not happen in those versions.  There was a team working on Persian support of MySQL 4.1.x and 5.x at Research Center of Informatic Industries.  They once invited me to join their team, but that didn’t work out.  I have not followed the results of their efforts yet, but you might find more information on www.rcii-ir.org.  Anyway, Support for Persian collation has been added to MySQL since version 4.1 by Jody McIntyre, so my solution may only be needed for those who are still stuck with older MySQL versions (or work in other environment in which support for Persian sorting is not implemented).

The solution

There is a way to store and use your UTF-8 encoded data in MySQL right now.  You have to convince MySQL that you’re feeding it ASCII data, and then delay all your string processing (including sorting) until you extract them from the database.  That means that you’re going to need support for UTF-8 in the language you’re using to access MySQL.

Many people use the PHP language to access MySQL over the web.  I personally do all my web development in PHP, and I’ve written a number of support routines in PHP for sorting the strings read from the database at the PHP side.  I’ve released the code under the GPL v2 license, and you can download it here.

Using this code couldn’t be any simpler!  The code assumes that you’ve read the data into an array, which has the column names as keys, and data as values.  This is the format returned by the mysql_fetch_assoc( ) function in PHP.  After including the db_sort.php file inside your PHP script, you should call the mysql_persian_sort( ) function, which takes two parameters.  The first one is the name of the array containing the data read from the database, and the second one is a string which contains the name of the column to sort on.  For example, if you have a table in MySQL named contacts, with a last_name field, and you want to sort the data fetched using mysql_fetch_assoc( ) into the $rows array according to that field, it’s enough to write the following:

mysql_persian_sort( $rows, 'last_name' );

 Download source code

This article originally appeared on BeginThread.com. It’s been republished here, and may contain modifications from the original article.

Top