*
Microsoft.com Home|Site Map
Microsoft*
Search Microsoft.com for:
Search for

Advanced Search
Registration & Travel
Global Development and Computing Portal Global Development and Computing Portal
Hands-On

The Microsoft Layer for Unicode on Windows 95/98/Me Systems

Posted:
Related Links

The Microsoft� Layer for Unicode™ on Windows� 95/98/ME Systems

For years, Microsoft has evangelized the benefits of creating applications that support Unicode.� On Windows NT/2000/XP, these benefits are obvious, and include:

  •  Improving international and multilingual support;
  •  Better integration with the features of the NT platform;
  •  Shipping a single binary instead of separate builds for each locale;
  •  Better support of the Multilingual UI (MUI) features of Windows 2000/XP;
  •  Support for the many new "Unicode only" languages such as Hindi and Georgian.

The problem was the difficulty in supporting a Unicode application on Windows 95/98/ME; developers had to support those customers as well. Because those platforms do not have the native Unicode support provided by the NT family of operating systems, it was just easier to write non-Unicode applications.

However, times have changed....

Starting with the Windows XP RC1 version of the Platform SDK, the Microsoft Layer for Unicode on Windows 95/98/ME Systems (MSLU for short) can help you solve this important challenge. This component provides a layer over the Win32 API on Windows 95/98/ME so that you can write a single Unicode version of your application and have it run properly on all platforms.

Feature Overview

  •  Easy to integrate - All you need to do is compile your application as a Unicode component and include the unicows.lib file with the other libraries you use.
  •  Does not slow down applications on WinNT/2K/XP - The custom loader for unicows.dll is built into unicows.lib and compiled with your application.� It does not even load MSLU unless you are on a Win95/98/ME machine! The technology is similar to the VC++ delayload mechanism, but is an independent solution that does not rely on any particular compiler.
  •  Easy customization - Developers who use the MS Layer for Unicode can override any API they want to and still take advantage of the custom loader.
  •  Good coverage of the Win32 API - MSLU provides fully implemented wrappers for over 440 API calls, with an additional group of "stub" wrappers that developers can override to implement themselves.
  •  Lightweight and easy to use - Weighing in at ~160kb and with no dependencies, no registration requirement, no special file location needed, its careful avoidance of "DLL Hell" issues, and its APIs staying so nearly identical to those found on the Unicode platforms, MSLU is exceptionally easy to add to your application.
  •  Works well with commonly used libraries - You may be using the Microsoft Foundation Classes (MFC), the VC++ Runtime (CRT), or the ActiveX Template Library (ATL). If you statically link these DLLs and subsequently integrate the MS Layer for Unicode, all of them will properly use the Unicode APIs that MSLU provides.
  •  Good interoperability - Whether you need to work with other components that use MSLU in the current process, applications that are out of the current process, or even solutions that do not have Unicode support at all, The Microsoft Layer for Unicode is able to behave appropriately.
  •  Comprehensive documentation - The Platform SDK will provide information in the topics for every single API that is supported by MSLU, including special issues for those few APIs to which you need to pay special attention. In addition, there are many specific topics to assist with integration.
  •  Developer newsgroup support - You can visit , the dedicated newsgroup for MSLU. Here you can receive the help of both Microsoft Product Support specialists and other developers who are working with this exciting new technology.
  •  Part of a complete package - There are many other components that Microsoft develops, such as RichEdit, the Windows Common Controls, MLang, Uniscribe, and GDI+, which can be combined with the MS Layer for Unicode.� This helps developers provide a full cross-platform experience that leverages the best features of every OS upon which their applications run.

Of course, MSLU is not a panacea for creating well-globalized applications that run just as well on Windows 95/98/Me as on Windows NT/2000/XP. The architectural challenges inherent in creating a multilingual application on Windows code page–based platforms still exist. First, there is considerably less multilingual support available on Windows 95/98/Me than on Windows NT/2000/ XP3 even after implementing MSLU (such as when entering Arabic on Korean versions of Windows 98). Second, MSLU does not make these code page–based platforms support Unicode internally. Third, MSLU was not designed to support existing solutions and components for code page–based platforms that provide their own Unicode functionality, such as MLang, Uniscribe, Rich Edit, common controls, and others. Fourth, you must still follow best practices associated with globalization. Finally, from an international standpoint, MSLU has a distinct disadvantage when compared to a Unicode platform. While MSLU does provide a Unicode “face” to your applications, it must talk internally to a non-Unicode operating system. Therefore, when your Unicode application that is running on Windows 95/98/Me is limited to a single code page, it is important to make sure that the application behaves properly. A good Unicode application would not be expected to have too many problems. However, you should test your application on each of these three platforms to make sure that nothing breaks and that the user does not lose any data. By first seeing what happens if your application is used beyond what the system can support, you can address any problems before the application is shipped.)

How MSLU Works

MSLU actually consists of two parts. The first part is a dynamic-link library (DLL)— Unicows.dll—that is redistributed with the application that the user creates. The second part is a library (LIB) file—Unicows.lib—that is compiled with this same application. This LIB contains the MSLU loader, which determines whether to load the DLL and call it; alternatively, it can call the original operating-system version of the API. (The former scenario would occur on Windows 95/98/Me; the latter would occur on Windows NT/2000/XP.) The loader also contains all of the necessary failure stubs like the operating system itself does, so that in case the DLL cannot be found, you can gracefully handle the failure of the APIs in your code. From a technical perspective, the only time your code would ever call the functions in Unicows.dll is when you are using Windows 95/98/Me. Even if you circumvent the loader (for instance, by calling LoadLibrary/GetProcAddress yourself, or by using the P/Invoke syntax of the Microsoft .NET Framework) and call the DLL directly, on an NT/2000/XP platform the DLL will simply forward the call to the API rather than call the MLSU “wrapper” function. This is because the wrapper has less functionality than the full operating-system version, which has full Unicode support. If you are using C or C++, it is not a good idea to intentionally slow yourself down by adding a DLL call you do not need that will simply call the operating system anyway. You can instead decide whether to call the operating-system version of a function or the MSLU version yourself, thus avoiding the performance hit. With every Unicode wrapper function in MSLU, there must obviously be a conversion to a non-Unicode string. This is usually done using the system default code page (CP_ACP) of the computer—a setting that cannot be changed on Windows 95/98/Me. There are some specific APIs that do not use CP_ACP Microsoft Layer for Unicode (MSLU) Chapter 18 because they have information in another parameter, such as a locale ID (LCID) value or a device context that would suggest a better code page to use.

How (and When) to Handle Overrides

For the most typical uses of MSLU, there is no need to write any code, with two exceptions:

  •  When you are overriding the loading of MSLU
  •  When you are overriding an individual API

Note Both of these cases assume you are using the MSLU loader. If you are using Microsoft C# or Microsoft Visual Basic .NET P/Invoke mechanism instead of the MSLU loader, you can call the APIs in Unicows.dll directly, and the code in the DLL will determine whether to handle the function itself or to call the operating-system version. Overriding the Loading of MSLU There are two steps required to override the loading of MSLU: 1. Set the “hook” that informs the MSLU loader which function it should call. 2. Provide the function that the loader will call when it first tries to load the DLL. The callback function shown in the following code attempts to load the DLL without a path first. This way, if any other component in the process has already loaded the DLL, you can be sure to share the same instance. If the function still fails to find the DLL, it will cause the process to exit. This is the same logic that the loader will use even without an override. Ideal usage of the override would build a path from information in the registry or from some other application-defined location. Exiting is important for a Microsoft Foundation Class (MFC) application, since MFC does not handle the failure of Unicode APIs very well. MFC assumes that certain functions will work. For this reason, an MFC application will crash when trying to dereference a NULL pointer during its initialization— after a call to an API fails—since it does not check for failure in this case.

	extern FARPROC _PfnLoadUnicows = (FARPROC) &LoadUnicowsProc;
	HMODULE LoadUnicowsProc(void)
	{
	HMODULE hMod = LoadLibraryA("unicows.dll");
	if(hMod == 0)
	{
	// Replace  with your specific path.
	hMod = LoadLibraryA("\\unicows.dll");
	}
	if(hMod == 0)
	{
	// If the load still failed, then exit.
	MessageBoxA(0,
	"Unicode wrapper not found",
	"My Company",
	MB_ICONSTOP | MB_OK);
	_exit(-1);
	}
	return(hMod);
	}

You must not call any Unicode APIs from the callback function, since the very first Unicode API that is loaded causes the loader to call this function. If you cause another Unicode API to be called, it will try to call itself again, recursively, until it runs out of stack space. Thus no APIs that MSLU wraps should ever be called from this function. Overriding an Individual API The syntax for overriding an API is similar to that for overriding the DLL’s load. You simply set a hook to inform the loader of which function it should call, and then provide the actual function. The Microsoft Windows Platform SDK documentation, available at http://msdn.microsoft.com, includes a code sample that overrides the LoadCursorW API. However, the sample here provides an override function for an API that is covered by MSLU only in stub form. This API is OleUIInsertObjectW, which calls the InsertObject method that many applications use to support Microsoft ActiveX object insertion.

	static UINT __stdcall
	MyOleUIInsertObjectW (LPOLEUIINSERTOBJECTW lpouiiow)
	{
	UINT result = OLEUI_CANCEL;
	OLEUIINSERTOBJECTA ouiioa;
	memcpy(&ouiioa, lpouiiow, sizeof (OLEUIINSERTOBJECTA));
	ouiioa.lpszFile = (char *)alloca (ouiioa.cchFile + 1);
	Microsoft Layer for Unicode (MSLU) Chapter 18
	ouiioa.lpszFile [0] = '\0';
	result = OleUIInsertObjectA(&ouiioa);
	if (result == OLEUI_SUCCESS)
	{
	memcpy(lpouiiow,
	&ouiioa,
	sizeof(OLEUIINSERTOBJECTW));
	MultiByteToWideChar(CP_ACP,
	0,
	ouiioa.lpSzFile,
	ouiioa.cchFile,
	lpowiiow->lpszFile,
	lpowiiow->cchFile);
	}
	return result;
	}
	extern "C" FARPROC Unicows_OleUIInsertObjectW =
	(FARPROC)&MyOleUIInsertObjectW;
		

Note that the preceding override will only be called on Windows 95/98/Me. One important limitation of this override is that it is a part of the MSLU loader, so it is only available in C and C++. However, within those languages, you can use the syntax described here to override as many APIs you want. In fact, you could override every API and simply use the MSLU loader around your own application. You could even call the MSLU API after some special processing by making calls to LoadLibrary("unicows.dll") followed by GetProcAddress - (" ").


To top of page


©2004 Microsoft Corporation. All rights reserved. Terms of Use |Privacy Statement