// // File: mslu.cpp // Date: 11 October 2001 // Purpose: This file contains functions that supplement MSLU // // Special thanks to Rick Cameron for his initial work (upon which this file is based) // #define UNICODE #include "stdafx.h" #include #include // Include for the OLEUI dialogs #include "oledlg.h" // Registry key identifiers static const char CDCommonFilesKey [] = "Software\\My Company", CDCommonFilesValueName [] = "MsluLocation", UnicowsName [] = "\\unicows.dll"; //****************** // LoadMSLU // // Attempt to load MSLU by the reading the registry key; // but exit on failure so MSLU will not crash after the fact. // // TODO: One really ought to be sure that no one put too long of a string // in that registry key ( > MAX_PATH) to avoid a buffer overrun //****************** static HMODULE __stdcall LoadMSLU (void) { HMODULE hUnicows = 0; HKEY hKey = 0; LONG rc = RegOpenKeyExA (HKEY_LOCAL_MACHINE, CDCommonFilesKey, 0, KEY_READ, &hKey); if (rc == ERROR_SUCCESS) { DWORD dwType = 0; DWORD cbData = 0; rc = RegQueryValueExA (hKey, CDCommonFilesValueName, 0, &dwType, 0, &cbData); if (rc == ERROR_SUCCESS && dwType == REG_SZ) { // Found the reg key and we know the size, to lets read it char *unicowsPath = (char *)_alloca (cbData + strlen (UnicowsName)); rc = RegQueryValueExA (hKey, CDCommonFilesValueName, 0, &dwType, (BYTE *)unicowsPath, &cbData); if (rc == ERROR_SUCCESS) { if (unicowsPath [strlen (unicowsPath) - 1] == '\\') strcat (unicowsPath, UnicowsName + 1); else strcat (unicowsPath, UnicowsName); hUnicows = LoadLibraryA (unicowsPath); } } RegCloseKey (hKey); } if (hUnicows == 0) { // The handle can be zero either because the reg key was // not there or because the DLL itself could not be found? MessageBoxA (0, "The Microsoft Layer for Unicode was not found", "My Company", MB_ICONSTOP | MB_OK); _exit (-1); } return hUnicows; } // Set the hook so that our loader function will be called extern "C" HMODULE (__stdcall *_PfnLoadUnicows) (void) = &LoadMSLU; //****************** // UserOleUIAddVerbMenuW // // OleUIAddVerbMenuW is a stub function in MSLU, but it is used by MFC applications // for the OLE menu items. Thus adding an implementation like this one is a useful idea. //****************** static BOOL __stdcall UserOleUIAddVerbMenuW( LPOLEOBJECT lpOleObj, //Pointer to the object LPCWSTR lpszShortType, //Pointer to the short name corresponding to the object HMENU hMenu, //Handle to the menu to modify UINT uPos, //Position of the menu item. UINT uIDVerbMin, //Value at which to start the verbs UINT uIDVerbMax, //Maximum identifier value for object verbs BOOL bAddConvert, //Whether to add convert item UINT idConvert, //Value to use for the convert item HMENU FAR * lphMenu //Pointer to the cascading verb menu, if created ) { char lpszShortTypeAnsi[MAX_PATH + 1]; if(0 == WideCharToMultiByte(CP_ACP, 0, lpszShortType, -1, lpszShortTypeAnsi, MAX_PATH, NULL, NULL)) return(FALSE); return OleUIAddVerbMenuA (lpOleObj, lpszShortTypeAnsi, hMenu, uPos, uIDVerbMin, uIDVerbMax, bAddConvert, idConvert, lphMenu); } // Set the hook so that UserOleUIAddVerbMenuW will be called for MSLU's OleUIAddVerbMenuW extern "C" FARPROC Unicows_OleUIAddVerbMenuW = (FARPROC)&UserOleUIAddVerbMenuW; //****************** // UserOleUIInsertObjectW // // OleUIInsertObjectW is a stub function in MSLU, but it is used by MFC applications // for the OLE menu items. Thus adding an implementation like this one is a useful idea. // // TODO: This function is assuming that a non-stting lpouiiow->lpszTemplate and ->lpszCaption // is being passed; if it is not, this string should be converted from Unicode prior to the API calll //****************** static UINT __stdcall UserOleUIInsertObjectW (LPOLEUIINSERTOBJECTW lpouiiow) { UINT result = OLEUI_CANCEL; OLEUIINSERTOBJECTA ouiioa; // Copy the whole structure over; note that the two structures have identical sizes memcpy (&ouiioa, lpouiiow, sizeof(OLEUIINSERTOBJECTA)); ouiioa.lpszFile = (char *)_alloca (ouiioa.cchFile + 1); ouiioa.lpszFile [0] = '\0'; result = OleUIInsertObjectA(&ouiioa); if (result == OLEUI_SUCCESS) { // Cache the caller's string since we are about to overrwrite it wchar_t *lpszFile = lpouiiow->lpszFile; // Copy the structure back memcpy (lpouiiow, &ouiioa, sizeof (OLEUIINSERTOBJECTW)); // Restore their string lpouiiow->lpszFile = lpszFile; // Copy the string by conversion ZeroMemory(lpouiiow->lpszFile, lpouiiow->cchFile); MultiByteToWideChar(CP_ACP, 0, ouiioa.lpszFile, -1, lpouiiow->lpszFile, lpouiiow->cchFile); } return result; } // Set the hook so that UserOleUIInsertObjectW will be called for MSLU's OleUIInsertObjectW extern "C" FARPROC Unicows_OleUIInsertObjectW = (FARPROC)&UserOleUIInsertObjectW;