mirror of
https://github.com/reactos/reactos.git
synced 2025-04-04 04:26:32 +00:00
[IMM32][USER32] ImmPutImeMenuItemsIntoMappedFile (#4588)
Implement inter-process menu item retrieving. CORE-11700
This commit is contained in:
parent
fe777bb52f
commit
ffbdb7d39e
6 changed files with 307 additions and 6 deletions
|
@ -355,13 +355,189 @@ Quit:
|
|||
return ret;
|
||||
}
|
||||
|
||||
// We will transport the IME menu items by using a flat memory block via
|
||||
// a file mapping object beyond the boundary of a process.
|
||||
|
||||
#define MAX_IMEMENU_BITMAP_BYTES 0xF00
|
||||
|
||||
typedef struct tagIMEMENUITEM
|
||||
{
|
||||
IMEMENUITEMINFOW Info;
|
||||
BYTE abChecked[MAX_IMEMENU_BITMAP_BYTES];
|
||||
BYTE abUnchecked[MAX_IMEMENU_BITMAP_BYTES];
|
||||
BYTE abItem[MAX_IMEMENU_BITMAP_BYTES];
|
||||
} IMEMENUITEM, *PIMEMENUITEM;
|
||||
|
||||
typedef struct tagIMEMENU
|
||||
{
|
||||
DWORD dwVersion;
|
||||
DWORD dwFlags;
|
||||
DWORD dwType;
|
||||
DWORD dwItemCount;
|
||||
IMEMENUITEMINFOW Parent;
|
||||
IMEMENUITEM Items[ANYSIZE_ARRAY];
|
||||
} IMEMENU, *PIMEMENU;
|
||||
|
||||
/***********************************************************************
|
||||
* ImmPutImeMenuItemsIntoMappedFile (IMM32.@)
|
||||
*
|
||||
* Called from user32.dll to transport the IME menu items by using a
|
||||
* file mapping object. This function is provided for WM_IME_SYSTEM:IMS_GETIMEMENU
|
||||
* handling.
|
||||
*/
|
||||
LRESULT WINAPI ImmPutImeMenuItemsIntoMappedFile(HIMC hIMC)
|
||||
{
|
||||
LRESULT ret = FALSE;
|
||||
HANDLE hMapping;
|
||||
PIMEMENU pView;
|
||||
LPIMEMENUITEMINFOW pParent = NULL, pItems = NULL;
|
||||
DWORD i, cItems, cbItems = 0;
|
||||
|
||||
hMapping = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"ImmMenuInfo");
|
||||
pView = MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
||||
if (!pView || pView->dwVersion != 1)
|
||||
{
|
||||
ERR("hMapping %p, pView %p\n", hMapping, pView);
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
if (pView->Parent.cbSize > 0)
|
||||
pParent = &pView->Parent;
|
||||
|
||||
if (pView->dwItemCount > 0)
|
||||
{
|
||||
cbItems = pView->dwItemCount * sizeof(IMEMENUITEMINFOW);
|
||||
pItems = ImmLocalAlloc(HEAP_ZERO_MEMORY, cbItems);
|
||||
if (!pItems)
|
||||
{
|
||||
ERR("!pItems\n");
|
||||
goto Quit;
|
||||
}
|
||||
}
|
||||
|
||||
cItems = ImmGetImeMenuItemsW(hIMC, pView->dwFlags, pView->dwType, pParent, pItems, cbItems);
|
||||
pView->dwItemCount = cItems;
|
||||
if (cItems == 0)
|
||||
goto Quit;
|
||||
|
||||
if (pItems)
|
||||
{
|
||||
for (i = 0; i < cItems; ++i)
|
||||
{
|
||||
pView->Items[i].Info = pItems[i];
|
||||
|
||||
// store bitmaps to bytes
|
||||
if (pItems[i].hbmpChecked)
|
||||
{
|
||||
Imm32StoreBitmapToBytes(pItems[i].hbmpChecked, pView->Items[i].abChecked,
|
||||
MAX_IMEMENU_BITMAP_BYTES);
|
||||
DeleteObject(pItems[i].hbmpChecked);
|
||||
}
|
||||
if (pItems[i].hbmpUnchecked)
|
||||
{
|
||||
Imm32StoreBitmapToBytes(pItems[i].hbmpUnchecked, pView->Items[i].abUnchecked,
|
||||
MAX_IMEMENU_BITMAP_BYTES);
|
||||
DeleteObject(pItems[i].hbmpUnchecked);
|
||||
}
|
||||
if (pItems[i].hbmpItem)
|
||||
{
|
||||
Imm32StoreBitmapToBytes(pItems[i].hbmpItem, pView->Items[i].abItem,
|
||||
MAX_IMEMENU_BITMAP_BYTES);
|
||||
DeleteObject(pItems[i].hbmpItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRUE;
|
||||
|
||||
Quit:
|
||||
if (pItems)
|
||||
ImmLocalFree(pItems);
|
||||
if (pView)
|
||||
UnmapViewOfFile(pView);
|
||||
if (hMapping)
|
||||
CloseHandle(hMapping);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Win: ImmGetImeMenuItemsInterProcess
|
||||
DWORD APIENTRY
|
||||
Imm32GetImeMenuItemWCrossProcess(HIMC hIMC, DWORD dwFlags, DWORD dwType, LPVOID lpImeParentMenu,
|
||||
Imm32GetImeMenuItemWInterProcess(HIMC hIMC, DWORD dwFlags, DWORD dwType, LPVOID lpImeParentMenu,
|
||||
LPVOID lpImeMenu, DWORD dwSize)
|
||||
{
|
||||
FIXME("We have to do something\n");
|
||||
return 0;
|
||||
HANDLE hMapping;
|
||||
PIMEMENU pView;
|
||||
DWORD i, cbView, dwItemCount, ret = 0;
|
||||
HWND hImeWnd;
|
||||
PIMEMENUITEM pGotItem;
|
||||
LPIMEMENUITEMINFOW pSetInfo;
|
||||
|
||||
hImeWnd = (HWND)NtUserQueryInputContext(hIMC, QIC_DEFAULTWINDOWIME);
|
||||
if (!hImeWnd || !IsWindow(hImeWnd))
|
||||
{
|
||||
ERR("hImeWnd %p\n", hImeWnd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dwItemCount = (lpImeMenu ? (dwSize / sizeof(IMEMENUITEMINFOW)) : 0);
|
||||
cbView = sizeof(IMEMENU) + ((size_t)dwItemCount - 1) * sizeof(IMEMENUITEM);
|
||||
|
||||
RtlEnterCriticalSection(&gcsImeDpi);
|
||||
|
||||
// create a file mapping
|
||||
hMapping = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
|
||||
0, cbView, L"ImmMenuInfo");
|
||||
pView = MapViewOfFile(hMapping, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
|
||||
if (!pView)
|
||||
{
|
||||
ERR("hMapping %p, pView %p\n", hMapping, pView);
|
||||
goto Quit;
|
||||
}
|
||||
|
||||
ZeroMemory(pView, cbView);
|
||||
pView->dwVersion = 1;
|
||||
pView->dwFlags = dwFlags;
|
||||
pView->dwType = dwType;
|
||||
pView->dwItemCount = dwItemCount;
|
||||
pView->Parent.cbSize = (lpImeParentMenu ? sizeof(IMEMENUITEMINFOW) : 0);
|
||||
|
||||
if (!SendMessageW(hImeWnd, WM_IME_SYSTEM, IMS_GETIMEMENU, (LPARAM)hIMC))
|
||||
goto Quit;
|
||||
|
||||
ret = pView->dwItemCount;
|
||||
|
||||
if (!lpImeMenu)
|
||||
goto Quit;
|
||||
|
||||
for (i = 0; i < ret; ++i)
|
||||
{
|
||||
pGotItem = &(pView->Items[i]);
|
||||
pSetInfo = &((LPIMEMENUITEMINFOW)lpImeMenu)[i];
|
||||
|
||||
*pSetInfo = pGotItem->Info;
|
||||
|
||||
// load bitmaps from bytes
|
||||
if (pSetInfo->hbmpChecked)
|
||||
{
|
||||
pSetInfo->hbmpChecked = Imm32LoadBitmapFromBytes(pGotItem->abChecked);
|
||||
}
|
||||
if (pSetInfo->hbmpUnchecked)
|
||||
{
|
||||
pSetInfo->hbmpUnchecked = Imm32LoadBitmapFromBytes(pGotItem->abUnchecked);
|
||||
}
|
||||
if (pSetInfo->hbmpItem)
|
||||
{
|
||||
pSetInfo->hbmpItem = Imm32LoadBitmapFromBytes(pGotItem->abItem);
|
||||
}
|
||||
}
|
||||
|
||||
Quit:
|
||||
RtlLeaveCriticalSection(&gcsImeDpi);
|
||||
if (pView)
|
||||
UnmapViewOfFile(pView);
|
||||
if (hMapping)
|
||||
CloseHandle(hMapping);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Win: ImmGetImeMenuItemsWorker
|
||||
|
@ -391,7 +567,7 @@ ImmGetImeMenuItemsAW(HIMC hIMC, DWORD dwFlags, DWORD dwType, LPVOID lpImeParentM
|
|||
{
|
||||
if (bTargetIsAnsi)
|
||||
return 0;
|
||||
return Imm32GetImeMenuItemWCrossProcess(hIMC, dwFlags, dwType, lpImeParentMenu,
|
||||
return Imm32GetImeMenuItemWInterProcess(hIMC, dwFlags, dwType, lpImeParentMenu,
|
||||
lpImeMenu, dwSize);
|
||||
}
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
@ stdcall ImmNotifyIME(ptr long long long)
|
||||
@ stub ImmPenAuxInput
|
||||
@ stdcall ImmProcessKey(ptr long long long long)
|
||||
@ stdcall -stub ImmPutImeMenuItemsIntoMappedFile(ptr)
|
||||
@ stdcall ImmPutImeMenuItemsIntoMappedFile(ptr)
|
||||
@ stdcall ImmReSizeIMCC(ptr long)
|
||||
@ stdcall ImmRegisterClient(ptr ptr)
|
||||
@ stdcall ImmRegisterWordA(long str long str)
|
||||
|
|
|
@ -165,3 +165,6 @@ static inline PTHREADINFO FASTCALL Imm32CurrentPti(VOID)
|
|||
NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
|
||||
return NtCurrentTeb()->Win32ThreadInfo;
|
||||
}
|
||||
|
||||
HBITMAP Imm32LoadBitmapFromBytes(const BYTE *pb);
|
||||
BOOL Imm32StoreBitmapToBytes(HBITMAP hbm, LPBYTE pbData, DWORD cbDataMax);
|
||||
|
|
|
@ -50,6 +50,127 @@ BOOL APIENTRY Imm32IsSystemJapaneseOrKorean(VOID)
|
|||
return (wPrimary == LANG_JAPANESE || wPrimary == LANG_KOREAN);
|
||||
}
|
||||
|
||||
typedef struct tagBITMAPCOREINFO256
|
||||
{
|
||||
BITMAPCOREHEADER bmciHeader;
|
||||
RGBTRIPLE bmciColors[256];
|
||||
} BITMAPCOREINFO256, *PBITMAPCOREINFO256;
|
||||
|
||||
HBITMAP Imm32LoadBitmapFromBytes(const BYTE *pb)
|
||||
{
|
||||
HBITMAP hbm = NULL;
|
||||
const BITMAPCOREINFO256 *pbmci;
|
||||
LPVOID pvBits;
|
||||
DWORD ib, cbBytes, cColors;
|
||||
BITMAP bm;
|
||||
|
||||
cbBytes = *(const DWORD *)pb;
|
||||
if (cbBytes == 0)
|
||||
return NULL;
|
||||
|
||||
pb += sizeof(DWORD);
|
||||
ib = sizeof(DWORD);
|
||||
|
||||
pbmci = (const BITMAPCOREINFO256 *)pb;
|
||||
hbm = CreateDIBSection(NULL, (LPBITMAPINFO)pbmci, DIB_RGB_COLORS, &pvBits, NULL, 0);
|
||||
if (!hbm || !GetObject(hbm, sizeof(BITMAP), &bm))
|
||||
return NULL;
|
||||
|
||||
switch (pbmci->bmciHeader.bcBitCount)
|
||||
{
|
||||
case 1: cColors = 2; break;
|
||||
case 4: cColors = 16; break;
|
||||
case 8: cColors = 256; break;
|
||||
case 24: case 32:
|
||||
cColors = 0;
|
||||
break;
|
||||
default:
|
||||
DeleteObject(hbm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ib += sizeof(BITMAPCOREHEADER);
|
||||
pb += sizeof(BITMAPCOREHEADER);
|
||||
|
||||
ib += cColors * sizeof(RGBTRIPLE);
|
||||
pb += cColors * sizeof(RGBTRIPLE);
|
||||
|
||||
ib += bm.bmWidthBytes * bm.bmHeight;
|
||||
if (ib > cbBytes)
|
||||
{
|
||||
DeleteObject(hbm);
|
||||
return NULL;
|
||||
}
|
||||
CopyMemory(pvBits, pb, bm.bmWidthBytes * bm.bmHeight);
|
||||
|
||||
return hbm;
|
||||
}
|
||||
|
||||
BOOL Imm32StoreBitmapToBytes(HBITMAP hbm, LPBYTE pbData, DWORD cbDataMax)
|
||||
{
|
||||
HDC hDC;
|
||||
BITMAP bm;
|
||||
DWORD cbBytes, cColors;
|
||||
BITMAPCOREINFO256 bmci;
|
||||
BOOL ret;
|
||||
LPBYTE pb = pbData;
|
||||
|
||||
*(LPDWORD)pb = 0;
|
||||
|
||||
if (!GetObject(hbm, sizeof(BITMAP), &bm))
|
||||
return FALSE;
|
||||
|
||||
ZeroMemory(&bmci, sizeof(bmci));
|
||||
bmci.bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
|
||||
bmci.bmciHeader.bcWidth = bm.bmWidth;
|
||||
bmci.bmciHeader.bcHeight = bm.bmHeight;
|
||||
bmci.bmciHeader.bcPlanes = 1;
|
||||
bmci.bmciHeader.bcBitCount = bm.bmBitsPixel;
|
||||
|
||||
switch (bm.bmBitsPixel)
|
||||
{
|
||||
case 1: cColors = 2; break;
|
||||
case 4: cColors = 16; break;
|
||||
case 8: cColors = 256; break;
|
||||
case 24: case 32:
|
||||
cColors = 0;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cbBytes = sizeof(DWORD);
|
||||
cbBytes += sizeof(BITMAPCOREHEADER);
|
||||
cbBytes += cColors * sizeof(RGBTRIPLE);
|
||||
cbBytes += bm.bmWidthBytes * bm.bmHeight;
|
||||
if (cbBytes > cbDataMax)
|
||||
return FALSE;
|
||||
|
||||
hDC = CreateCompatibleDC(NULL);
|
||||
|
||||
ret = GetDIBits(hDC, hbm, 0, bm.bmHeight, NULL, (LPBITMAPINFO)&bmci, DIB_RGB_COLORS);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
*(LPDWORD)pb = cbBytes;
|
||||
pb += sizeof(DWORD);
|
||||
|
||||
CopyMemory(pb, &bmci.bmciHeader, sizeof(BITMAPCOREHEADER));
|
||||
pb += sizeof(BITMAPCOREHEADER);
|
||||
|
||||
CopyMemory(pb, &bmci.bmciColors, cColors * sizeof(RGBTRIPLE));
|
||||
pb += cColors * sizeof(RGBTRIPLE);
|
||||
|
||||
ret = GetDIBits(hDC, hbm, 0, bm.bmHeight, pb, (LPBITMAPINFO)&bmci, DIB_RGB_COLORS);
|
||||
if (!ret)
|
||||
*(LPDWORD)pbData = 0;
|
||||
}
|
||||
|
||||
DeleteDC(hDC);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Win: IsAnsiIMC
|
||||
BOOL WINAPI Imm32IsImcAnsi(HIMC hIMC)
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@ extern "C" {
|
|||
#define IMS_IMEACTIVATE 0x17
|
||||
#define IMS_IMEDEACTIVATE 0x18
|
||||
#define IMS_ACTIVATELAYOUT 0x19
|
||||
#define IMS_GETIMEMENU 0x1C
|
||||
|
||||
#define IMMGWL_IMC 0
|
||||
#define IMMGWL_PRIVATE (sizeof(LONG))
|
||||
|
|
|
@ -678,7 +678,7 @@ static LRESULT ImeWnd_OnImeSystem(PIMEUI pimeui, WPARAM wParam, LPARAM lParam)
|
|||
ret = IMM_FN(ImmActivateLayout)((HKL)lParam);
|
||||
break;
|
||||
|
||||
case 0x1C:
|
||||
case IMS_GETIMEMENU:
|
||||
ret = IMM_FN(ImmPutImeMenuItemsIntoMappedFile)((HIMC)lParam);
|
||||
break;
|
||||
|
||||
|
|
Loading…
Reference in a new issue