|
|
|
Windows string typesNow, let us see what are the string types we use in windows. Windows provides large number of API functions for programs running on windows. For an example, let us take the API function DeleteFile which we use to delete a file. Actually there are 2 DeleteFile functions provided by windows, DeleteFileA and DeleteFileW. The difference between these functions is that the first one accepts ASCII string as argument (the path of the file to delete) and the second one accepts UNICODE string as argument. Without knowing it, we just use DeleteFile to delete a file. How are we able to do it like that? When we are using a wizard to build an application in Visual Studio, the wizard asks us whether we need to use UNICODE libraries or ASCII libraries. If we selected UNICODE, the class wizard adds a command line argument to the compiler which is similar to the following line added to one of the header files it includes for our project. You may not be that familiar with preprocessor directives, but the directives used in these examples are so easy to understand. #define UNICODE The above statement defines a constant UNICODE. Now let us see how DeleteFile is defined. It is defined in WinBase.h, which is included automatically through the header stdafx.h which the wizard includes for our project. #ifdef UNICODE This code specifies to the preprocessor if UNICODE is defined somewhere above, replace DeleteFile with DeleteFileW, or if UNICODE is not defined, replace it with DeleteFileA. So, if we chose to use UNICODE, because the wizard defines UNCODE, we automatically use the correct function DeleteFileW. Now, think what will happen if we chose to use to use UNICODE functions, but we send ASCII strings to those functions as arguments. Simply, the code will not compile, but one can use a cast and make it compile. But certainly, because of the different encoding, the function will not get what we needed to send it. Note that some people do not even know that this kind of a scenario exists. So, how this problem has overcome? In windows, another string type TCHAR is introduced to solve this problem. TCHAR is not a separate character type. Inspect the following definition of TCHAR. #ifdef UNICODE Here, if we have defined UNICODE, TCHAR will be simply wchar_t and if we do not have defined UNICODE, TCHAR will be char. So, we can send a TCHAR string to API functions such as our previous example DeleteFile without a fear that we are sending the incorrect string type. If we have defined UNICODE, DeleteFile is actually DeleteFileW, and TCHAR is wchar_t. So sending TCHAR string will cause no problem. If we have not defined UNICODE, then DeleteFile is actually DeleteFileA, and TCHAR is char. Then also, sending a TCHAR string will not cause a problem. Next problem is, how to initialize a TCHAR string. We use the macro TEXT to initialize a TCHAR string. The macro TEXT is defined as something like this. #ifdef UNICODE In the above definition of TEXT, if UNICODE is defined, TEXT is equal to prefixing L to the quote, making the string a unicode string. if UNICODE is not defined, the macro TEXT will not do anything. Take the following line of code. TCHAR *string = TEXT("this is a string"); If UNICODE is defined, after preprocessing the above line becomes, wchar_t *string = L"this is a string"; If UNICODE is not defined, after preprocessing, the same line will become, char *string = "this is a string"; So, as you can see, the appropriate types are selected automatically by the preprocessor due to the definitions of TCHAR and TEXT. If you find it difficult to type TEXT, you can use _T instead. Both TEXT and _T are equivalent. You do not need to declare a string variable separately to send as an argument to an API function. You can simply do like this. DeleteFile(TEXT("C:\\abc.txt"));
In Win32 functions, various string types are expected as arguments. Here is a list of the string types used in those functions and the meaning of those types when you use UNICODE and when you are not using UNICODE.
|