955 lines
30 KiB
C
955 lines
30 KiB
C
|
/*++
|
||
|
*
|
||
|
* WOW v1.0
|
||
|
*
|
||
|
* Copyright (c) 1991, Microsoft Corporation
|
||
|
*
|
||
|
* WNMAN.C
|
||
|
* WOW32 16-bit Winnls API support (manually-coded thunks)
|
||
|
*
|
||
|
* History:
|
||
|
* Created 19-Feb-1992 by Junichi Okubo (junichio)
|
||
|
* Changed 30-Jun-1992 by Hiroyuki Hanaoka (hiroh)
|
||
|
* Changed 05-Nov-1992 by Kazuyuki Kato (v-kazuyk)
|
||
|
*
|
||
|
--*/
|
||
|
#include "precomp.h"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#ifdef FE_IME
|
||
|
|
||
|
#include "ime.h"
|
||
|
#include "imep.h"
|
||
|
#include "winnls32.h"
|
||
|
#include "wcall16.h" // use GlobalLock16
|
||
|
|
||
|
#include "wownls.h"
|
||
|
#include "wnman.h"
|
||
|
|
||
|
MODNAME(wnman.c);
|
||
|
|
||
|
struct _wow32imedebug {
|
||
|
LPSZ subfunction;
|
||
|
} wow32imedebug[]={
|
||
|
{"undefined IME function"}, //0x00
|
||
|
{"undefined IME function"}, //0x01
|
||
|
{"undefined IME function"}, //0x02
|
||
|
{"IME_GETIMECAPS"}, //0x03
|
||
|
{"IME_SETOPEN"}, //0x04
|
||
|
{"IME_GETOPEN"}, //0x05
|
||
|
{"IME_ENABLEDOSIME"}, //0x06
|
||
|
{"IME_GETVERSION"}, //0x07
|
||
|
{"IME_SETCONVERSIONWINDOW"}, //0x08
|
||
|
{"undefined IME function"}, //0x09
|
||
|
{"undefined IME function"}, //0x0a
|
||
|
{"undefined IME function"}, //0x0b
|
||
|
{"undefined IME function"}, //0x0c
|
||
|
{"undefined IME function"}, //0x0d
|
||
|
{"undefined IME function"}, //0x0e
|
||
|
{"undefined IME function"}, //0x0f
|
||
|
{"IME_SETCONVERSIONMODE, (undefined IME function - KOREA)"}, //0x10
|
||
|
{"IME_GETCONVERSIONMODE, (IME_GET_MODE - KOREA)"}, //0x11
|
||
|
{"IME_SETCONVERSIONFONT, (IME_SET_MODE - KOREA)"}, //0x12
|
||
|
{"IME_SENDVKEY"}, //0x13
|
||
|
{"IME_DESTROYIME"}, //0x14
|
||
|
{"IME_PRIVATE"}, //0x15
|
||
|
{"IME_WINDOWUPDATE"}, //0x16
|
||
|
{"IME_SELECT"}, //0x17
|
||
|
{"IME_ENTERWORDREGISTERMODE"}, //0x18
|
||
|
{"IME_SETCONVERSIONFONTEX"}, //0x19
|
||
|
{"undefined IME function"}, //0x1a
|
||
|
{"undefined IME function"}, //0x1b
|
||
|
{"undefined IME function"}, //0x1c
|
||
|
{"undefined IME function"}, //0x1d
|
||
|
{"undefined IME function"}, //0x1e
|
||
|
{"undefined IME function"}, //0x1f
|
||
|
{"IME_CODECONVERT"}, //0x20
|
||
|
{"IME_CONVERTLIST"}, //0x21
|
||
|
{"undefined IME function"}, //0x22
|
||
|
{"undefined IME function"}, //0x23
|
||
|
{"undefined IME function"}, //0x24
|
||
|
{"undefined IME function"}, //0x25
|
||
|
{"undefined IME function"}, //0x26
|
||
|
{"undefined IME function"}, //0x27
|
||
|
{"undefined IME function"}, //0x28
|
||
|
{"undefined IME function"}, //0x29
|
||
|
{"undefined IME function"}, //0x2a
|
||
|
{"undefined IME function"}, //0x2b
|
||
|
{"undefined IME function"}, //0x2c
|
||
|
{"undefined IME function"}, //0x2d
|
||
|
{"undefined IME function"}, //0x2e
|
||
|
{"undefined IME function"}, //0x2f
|
||
|
{"IME_AUTOMATA"}, //0x30
|
||
|
{"IME_HANJAMODE"}, //0x31
|
||
|
{"undefined IME function"}, //0x32
|
||
|
{"undefined IME function"}, //0x33
|
||
|
{"undefined IME function"}, //0x34
|
||
|
{"undefined IME function"}, //0x35
|
||
|
{"undefined IME function"}, //0x36
|
||
|
{"undefined IME function"}, //0x37
|
||
|
{"undefined IME function"}, //0x38
|
||
|
{"undefined IME function"}, //0x39
|
||
|
{"undefined IME function"}, //0x3a
|
||
|
{"undefined IME function"}, //0x3b
|
||
|
{"undefined IME function"}, //0x3c
|
||
|
{"undefined IME function"}, //0x3d
|
||
|
{"undefined IME function"}, //0x3e
|
||
|
{"undefined IME function"}, //0x3f
|
||
|
{"IME_GETLEVEL"}, //0x40
|
||
|
{"IME_SETLEVEL"}, //0x41
|
||
|
{"IME_GETMNTABLE"} //0x42
|
||
|
};
|
||
|
|
||
|
INT wow32imedebugMax=0x43;
|
||
|
HAND16 hFnt16; // 16 bit Font handle;
|
||
|
|
||
|
#define IME_MOVEIMEWINDOW IME_SETCONVERSIONWINDOW
|
||
|
|
||
|
ULONG FASTCALL WN32SendIMEMessage(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul = 0;
|
||
|
PSENDIMEMESSAGE16 parg16;
|
||
|
IMESTRUCT * imestruct32;
|
||
|
register PIMESTRUCT16 ptag16;
|
||
|
HANDLE hIME32;
|
||
|
INT cb;
|
||
|
VPVOID vp;
|
||
|
HANDLE hlParam1 = NULL; // IME_ENTERWORDREGISTERMODE
|
||
|
HANDLE hlParam2 = NULL;
|
||
|
HANDLE hLFNT32 = NULL; // IMW_SETCONVERSIONFONT(EX)
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(SENDIMEMESSAGE16), parg16);
|
||
|
vp = GlobalLock16(FETCHWORD(parg16->lParam), NULL);
|
||
|
GETMISCPTR(vp, ptag16); // Get IME struct16 ptr
|
||
|
|
||
|
hIME32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMESTRUCT));
|
||
|
imestruct32 = GlobalLock(hIME32);
|
||
|
|
||
|
// check for GlobalLock return as well when checking ptag16
|
||
|
if (!ptag16 || !imestruct32) {
|
||
|
LOGDEBUG(1,(" WINNLS:(Jun)ptag16==NULL!! || imestruct32 == NULL"));
|
||
|
goto eee;
|
||
|
}
|
||
|
|
||
|
switch (ptag16 -> fnc) {
|
||
|
case IME_HANJAMODE:
|
||
|
// Korea specific function
|
||
|
if (GetSystemDefaultLangID() != 0x412)
|
||
|
goto eee;
|
||
|
|
||
|
STOREDWORD(imestruct32->fnc, ptag16->fnc);
|
||
|
STOREDWORD(imestruct32->wParam, 0);
|
||
|
|
||
|
// The 4th word of imestruct32 must contains ptag16->dchSource.
|
||
|
// msime95 will find ptag16->dchSource on the 4th word.
|
||
|
*((LPSTR)(imestruct32) + sizeof(ptag16->fnc) +
|
||
|
sizeof(ptag16->wParam) +
|
||
|
sizeof(ptag16->wCount) )
|
||
|
= (CHAR)ptag16->dchSource;
|
||
|
|
||
|
*((LPSTR)(imestruct32) + ptag16->dchSource)
|
||
|
= *(LPSTR)((LPSTR)(ptag16) + (ptag16)->dchSource);
|
||
|
|
||
|
*((LPSTR)(imestruct32) + ptag16->dchSource + 1)
|
||
|
= *(LPSTR)((LPSTR)(ptag16) + (ptag16)->dchSource + 1);
|
||
|
|
||
|
// Quattro Pro Window use null window handle when it call Hanja conversion.
|
||
|
if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_QPW_FIXINVALIDWINHANDLE)
|
||
|
parg16->hwnd = GETHWND16(GetFocus());
|
||
|
break;
|
||
|
|
||
|
case IME_CONVERTLIST:
|
||
|
case IME_AUTOMATA:
|
||
|
case IME_CODECONVERT:
|
||
|
case IME_SETLEVEL:
|
||
|
case IME_GETLEVEL:
|
||
|
case IME_GETMNTABLE:
|
||
|
// Korea specific function
|
||
|
if (GetSystemDefaultLangID() != 0x412)
|
||
|
goto eee;
|
||
|
goto standard;
|
||
|
|
||
|
case IME_SETCONVERSIONWINDOW: // (IME_MOVECONVERTWINDOW)
|
||
|
// IME_MOVEIMEWINDOW for Korea
|
||
|
if (GetSystemDefaultLangID() != 0x412 &&
|
||
|
CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_AMIPRO_PM4J_IME) {
|
||
|
// Don't pass the MCW_DEFAULT.
|
||
|
// because, Conversion window will be flushed when
|
||
|
// default conversion window and AMIPRO's window have overlap.
|
||
|
//
|
||
|
// Also, for PM4J, when the codebox is moved Pagemaker
|
||
|
// thinks it needs to be displayed at default. Prevent
|
||
|
// endless loop of default screen|window displays
|
||
|
//
|
||
|
if (ptag16->wParam == MCW_DEFAULT) {
|
||
|
ul = FALSE;
|
||
|
goto eee;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
case IME_GETOPEN:
|
||
|
case IME_SETOPEN:
|
||
|
case IME_GETIMECAPS: // (IME_QUERY)
|
||
|
case IME_SETCONVERSIONMODE: // (IME_SET_MODE)
|
||
|
case IME_GETCONVERSIONMODE: // (IME_GET_MODE)
|
||
|
case IME_SENDVKEY: // (IME_SENDKEY)
|
||
|
case IME_DESTROYIME: // (IME_DESTROY)
|
||
|
case IME_WINDOWUPDATE:
|
||
|
case IME_SELECT:
|
||
|
case IME_GETVERSION:
|
||
|
standard:
|
||
|
STOREDWORD(imestruct32->fnc, ptag16->fnc);
|
||
|
STOREDWORD(imestruct32->wParam, ptag16->wParam);
|
||
|
STOREDWORD(imestruct32->wCount, ptag16->wCount);
|
||
|
STOREDWORD(imestruct32->dchSource, ptag16->dchSource);
|
||
|
STOREDWORD(imestruct32->dchDest, ptag16->dchDest);
|
||
|
/*** STOREWORD -> STOREDWORD v-kazyk ***/
|
||
|
STOREDWORD(imestruct32->lParam1, ptag16->lParam1);
|
||
|
STOREDWORD(imestruct32->lParam2, ptag16->lParam2);
|
||
|
STOREDWORD(imestruct32->lParam3, ptag16->lParam3);
|
||
|
break;
|
||
|
|
||
|
case IME_ENTERWORDREGISTERMODE: // (IME_WORDREGISTER)
|
||
|
{
|
||
|
LPBYTE lpMem16;
|
||
|
LPBYTE lpMem32;
|
||
|
|
||
|
STOREDWORD(imestruct32->fnc, ptag16->fnc);
|
||
|
if (ptag16->lParam1) {
|
||
|
vp = GlobalLock16(FETCHWORD(ptag16->lParam1), &cb);
|
||
|
hlParam1 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, cb + 1);
|
||
|
lpMem32 = GlobalLock(hlParam1);
|
||
|
if (!lpMem32) {
|
||
|
goto eee;
|
||
|
}
|
||
|
GETMISCPTR(vp, lpMem16);
|
||
|
RtlCopyMemory(lpMem32, lpMem16, cb);
|
||
|
GlobalUnlock(hlParam1);
|
||
|
GlobalUnlock16(FETCHWORD(ptag16->lParam1));
|
||
|
}
|
||
|
if (ptag16->lParam2) {
|
||
|
vp = GlobalLock16(FETCHWORD(ptag16->lParam2), &cb);
|
||
|
hlParam2 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, cb + 1);
|
||
|
lpMem32 = GlobalLock(hlParam2);
|
||
|
if (!lpMem32) {
|
||
|
goto eee;
|
||
|
}
|
||
|
GETMISCPTR(vp, lpMem16);
|
||
|
RtlCopyMemory(lpMem32, lpMem16, cb);
|
||
|
GlobalUnlock(hlParam2);
|
||
|
GlobalUnlock16(FETCHWORD(ptag16->lParam2));
|
||
|
}
|
||
|
STOREDWORD(imestruct32->lParam1, hlParam1);
|
||
|
STOREDWORD(imestruct32->lParam2, hlParam2);
|
||
|
STOREDWORD(imestruct32->lParam3, ptag16->lParam3);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IME_SETCONVERSIONFONT: // (IME_SET_MODE - Korea)
|
||
|
{
|
||
|
LOGFONT * logfont32;
|
||
|
|
||
|
if (GetSystemDefaultLangID() == 0x412) {
|
||
|
// Hunguel WOW should do anything for IME_SET_MODE function
|
||
|
goto eee;
|
||
|
}
|
||
|
|
||
|
STOREDWORD(imestruct32->fnc, IME_SETCONVERSIONFONTEX);
|
||
|
if ( ptag16->wParam ) {
|
||
|
hLFNT32 = GlobalAlloc( GMEM_SHARE | GMEM_MOVEABLE, sizeof(LOGFONT));
|
||
|
logfont32 = GlobalLock(hLFNT32);
|
||
|
GetObject(HOBJ32(ptag16->wParam), sizeof(LOGFONT), logfont32);
|
||
|
GlobalUnlock(hLFNT32);
|
||
|
}
|
||
|
else {
|
||
|
hLFNT32 = NULL;
|
||
|
}
|
||
|
STOREDWORD(imestruct32->lParam1, hLFNT32);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IME_SETCONVERSIONFONTEX:
|
||
|
{
|
||
|
LOGFONT * logfont32;
|
||
|
|
||
|
STOREDWORD(imestruct32->fnc, IME_SETCONVERSIONFONTEX);
|
||
|
if (!ptag16->lParam1) {
|
||
|
imestruct32->lParam1 = (ULONG)NULL;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
// HANDLE of LOGFONT check
|
||
|
// If lParam1 is Invalid Handle, hLFNT32 is NULL
|
||
|
if (FETCHWORD(ptag16->lParam1) &&
|
||
|
(vp = GlobalLock16(FETCHWORD(ptag16->lParam1), NULL))) {
|
||
|
hLFNT32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(LOGFONT));
|
||
|
logfont32 = GlobalLock(hLFNT32);
|
||
|
// GETMISCPTR(vp, logfont16);
|
||
|
GETLOGFONT16(vp, logfont32);
|
||
|
GlobalUnlock16(FETCHWORD(ptag16->lParam1));
|
||
|
GlobalUnlock(hLFNT32);
|
||
|
}
|
||
|
else {
|
||
|
hLFNT32 = NULL;
|
||
|
}
|
||
|
STOREDWORD(imestruct32->lParam1, hLFNT32);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IME_PRIVATE:
|
||
|
LOGDEBUG(0,(" ERROR:SendIMEMessage IME_PRIVATE NOT IMPLEMENTED\n"));
|
||
|
goto eee;
|
||
|
|
||
|
case IME_ENABLEDOSIME: // (IME_ENABLE)
|
||
|
default:
|
||
|
|
||
|
LOGDEBUG(0,(" ERROR:SendIMEMessage unexpected subfunction\n"));
|
||
|
LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGE %s\n",
|
||
|
wow32imedebug[ptag16->fnc]));
|
||
|
goto eee;
|
||
|
}
|
||
|
|
||
|
LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGE %s\n",
|
||
|
wow32imedebug[ptag16->fnc]));
|
||
|
|
||
|
if (ptag16 -> fnc != IME_SETCONVERSIONWINDOW) {
|
||
|
LOGDEBUG(1,("WINNLS: fnc == %x wParam == %x wCount == %x\n",
|
||
|
imestruct32->fnc, imestruct32->wParam, imestruct32->wCount ));
|
||
|
LOGDEBUG(1,("WINNLS: dchDest == %x dchSource == %x\n",
|
||
|
imestruct32->dchDest, imestruct32->dchSource));
|
||
|
LOGDEBUG(1,("WINNLS: lParam1 == %x lParam2 == %x lParam3 == %x\n",
|
||
|
imestruct32->lParam1, imestruct32->lParam2, imestruct32->lParam3));
|
||
|
LOGDEBUG(1,("WINNLS: hwnd == %x %x\n",
|
||
|
parg16->hwnd,HWND32(parg16->hwnd)));
|
||
|
}
|
||
|
|
||
|
GlobalUnlock(hIME32);
|
||
|
|
||
|
// For win31 compatibility, since win31 didn't check the first
|
||
|
// parm, check it here and fill in a dummy (WOW) hwnd if its bogus
|
||
|
// so that NT doesn't reject the call
|
||
|
|
||
|
ul = SendIMEMessageEx(
|
||
|
((parg16->hwnd) ? HWND32(parg16->hwnd) : (HWND)0xffff0000),
|
||
|
(LPARAM)hIME32);
|
||
|
|
||
|
LOGDEBUG(1,("WINNLS: Ret == %x\n", ul ));
|
||
|
|
||
|
imestruct32 = GlobalLock(hIME32);
|
||
|
|
||
|
LOGDEBUG(1,("WINNLS: wParam == %x\n\n", imestruct32->wParam ));
|
||
|
|
||
|
STOREWORD(ptag16->wParam, ul);
|
||
|
|
||
|
switch (ptag16->fnc) {
|
||
|
case IME_GETOPEN:
|
||
|
STOREWORD(ptag16->wCount, imestruct32->wCount);
|
||
|
break;
|
||
|
|
||
|
case IME_ENTERWORDREGISTERMODE: // (IME_WORDREGISTER)
|
||
|
if (hlParam1)
|
||
|
GlobalFree(hlParam1);
|
||
|
if (hlParam2)
|
||
|
GlobalFree(hlParam2);
|
||
|
break;
|
||
|
|
||
|
case IME_SETCONVERSIONFONT: // (IME_SETFONT)
|
||
|
{
|
||
|
HAND16 hTmp;
|
||
|
hTmp = ptag16->wParam;
|
||
|
ptag16->wParam = hFnt16;
|
||
|
hFnt16 = hTmp;
|
||
|
if ( hLFNT32 )
|
||
|
GlobalFree(hLFNT32);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IME_SETCONVERSIONFONTEX:
|
||
|
if ( hLFNT32 )
|
||
|
GlobalFree(hLFNT32);
|
||
|
break;
|
||
|
|
||
|
case IME_GETVERSION:
|
||
|
// PowerPoint4J must have version returned as 3.1
|
||
|
// Or else it thinks that the ime doesn't support IR_UNDETERMINE
|
||
|
if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_PPT4J_IME_GETVERSION) {
|
||
|
STOREWORD(ptag16->wParam, 0x0A03);
|
||
|
}
|
||
|
// WARNING: For DaytonaJ RC1 only!!!
|
||
|
// Tell Winword6J that the IME doesn't support TrueInline (undetermine msgs)
|
||
|
// So, that WinWord6J doesn't hang up doing the input loop processing of it.
|
||
|
else if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_WORDJ_IME_GETVERSION) {
|
||
|
STOREWORD(ptag16->wParam, 0x0003);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
eee:
|
||
|
GlobalUnlock(hIME32);
|
||
|
GlobalFree(hIME32);
|
||
|
GlobalUnlock16(FETCHWORD(parg16->lParam));
|
||
|
FREEVDMPTR(ptag16);
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
return(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WN32SendIMEMessageEx(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul = 0;
|
||
|
PSENDIMEMESSAGE16 parg16;
|
||
|
IMESTRUCT * imestruct32;
|
||
|
register PIMESTRUCT16 ptag16;
|
||
|
HANDLE hIME32;
|
||
|
INT cb;
|
||
|
VPVOID vp;
|
||
|
HANDLE hlParam1 = NULL; // IME_ENTERWORDREGISTERMODE
|
||
|
HANDLE hlParam2 = NULL;
|
||
|
HANDLE hLFNT32; // IME_SETCONVERSIONFONT(EX)
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(SENDIMEMESSAGE16), parg16);
|
||
|
vp = GlobalLock16(FETCHWORD(parg16->lParam), NULL);
|
||
|
GETMISCPTR(vp, ptag16);
|
||
|
|
||
|
hIME32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMESTRUCT));
|
||
|
imestruct32 = GlobalLock(hIME32);
|
||
|
|
||
|
// if can't lock hIME32 fail gracefully
|
||
|
|
||
|
if (!ptag16 || !imestruct32) {
|
||
|
LOGDEBUG(1,(" WINNLS:(Jun)ptag16==NULL!! or imestruct32 == NULL"));
|
||
|
goto eee;
|
||
|
}
|
||
|
switch (ptag16->fnc) {
|
||
|
case IME_HANJAMODE:
|
||
|
// Korea specific function
|
||
|
if (GetSystemDefaultLangID() != 0x412)
|
||
|
goto eee;
|
||
|
|
||
|
STOREDWORD(imestruct32->fnc, ptag16->fnc);
|
||
|
STOREDWORD(imestruct32->wParam, 0);
|
||
|
|
||
|
// The 4th word of imestruct32 must contains ptag16->dchSource.
|
||
|
// msime95 will find ptag16->dchSource on the 4th word.
|
||
|
*((LPSTR)(imestruct32) + sizeof(ptag16->fnc) +
|
||
|
sizeof(ptag16->wParam) +
|
||
|
sizeof(ptag16->wCount) )
|
||
|
= (CHAR)ptag16->dchSource;
|
||
|
|
||
|
*((LPSTR)(imestruct32) + ptag16->dchSource)
|
||
|
= *(LPSTR)((LPSTR)(ptag16) + (ptag16)->dchSource);
|
||
|
|
||
|
*((LPSTR)(imestruct32) + ptag16->dchSource + 1)
|
||
|
= *(LPSTR)((LPSTR)(ptag16) + (ptag16)->dchSource + 1);
|
||
|
break;
|
||
|
|
||
|
case IME_CONVERTLIST:
|
||
|
case IME_AUTOMATA:
|
||
|
case IME_CODECONVERT:
|
||
|
case IME_SETLEVEL:
|
||
|
case IME_GETLEVEL:
|
||
|
case IME_GETMNTABLE:
|
||
|
// Korea specific function
|
||
|
if (GetSystemDefaultLangID() != 0x412)
|
||
|
goto eee;
|
||
|
goto standard;
|
||
|
|
||
|
case IME_SETCONVERSIONWINDOW: // (IME_MOVECONVERTWINDOW)
|
||
|
// IME_MOVEIMEWINDOW for Korea
|
||
|
if (GetSystemDefaultLangID() != 0x412 &&
|
||
|
CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_AMIPRO_PM4J_IME) {
|
||
|
// Don't pass the MCW_DEFAULT.
|
||
|
// because, Conversion window will be flushed when
|
||
|
// default conversion window and AMIPRO's window have overlap.
|
||
|
//
|
||
|
// Also, for PM4J, when the codebox is moved Pagemaker
|
||
|
// thinks it needs to be displayed at default. Prevent
|
||
|
// endless loop of default screen|window displays
|
||
|
//
|
||
|
if (ptag16->wParam == MCW_DEFAULT) {
|
||
|
ul = FALSE;
|
||
|
goto eee;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
case IME_GETOPEN:
|
||
|
case IME_SETOPEN:
|
||
|
case IME_GETIMECAPS: // (IME_QUERY)
|
||
|
case IME_SETCONVERSIONMODE: // (IME_SET_MODE)
|
||
|
case IME_GETCONVERSIONMODE: // (IME_GET_MODE)
|
||
|
case IME_SENDVKEY: // (IME_SENDKEY)
|
||
|
case IME_DESTROYIME: // (IME_DESTROY)
|
||
|
case IME_WINDOWUPDATE:
|
||
|
case IME_SELECT:
|
||
|
case IME_GETVERSION: // Win3.1
|
||
|
standard:
|
||
|
STOREDWORD(imestruct32->fnc, ptag16->fnc);
|
||
|
STOREDWORD(imestruct32->wParam, ptag16->wParam);
|
||
|
STOREDWORD(imestruct32->wCount, ptag16->wCount);
|
||
|
STOREDWORD(imestruct32->dchSource, ptag16->dchSource);
|
||
|
STOREDWORD(imestruct32->dchDest, ptag16->dchDest);
|
||
|
STOREDWORD(imestruct32->lParam1, ptag16->lParam1);
|
||
|
STOREDWORD(imestruct32->lParam2, ptag16->lParam2);
|
||
|
STOREDWORD(imestruct32->lParam3, ptag16->lParam3);
|
||
|
break;
|
||
|
|
||
|
case IME_ENTERWORDREGISTERMODE: // (IME_WORDREGISTER)
|
||
|
{
|
||
|
LPBYTE lpMem16;
|
||
|
LPBYTE lpMem32;
|
||
|
|
||
|
STOREDWORD(imestruct32->fnc, ptag16->fnc);
|
||
|
if (ptag16->lParam1) {
|
||
|
vp = GlobalLock16(FETCHWORD(ptag16->lParam1), &cb);
|
||
|
hlParam1 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, cb + 1);
|
||
|
lpMem32 = GlobalLock(hlParam1);
|
||
|
|
||
|
if (vp) {
|
||
|
if (lpMem32) {
|
||
|
GETMISCPTR(vp, lpMem16);
|
||
|
RtlCopyMemory(lpMem32, lpMem16, cb);
|
||
|
GlobalUnlock(hlParam1);
|
||
|
}
|
||
|
GlobalUnlock16(FETCHWORD(ptag16->lParam1));
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
if (ptag16->lParam2) {
|
||
|
vp = GlobalLock16(FETCHWORD(ptag16->lParam2), &cb);
|
||
|
hlParam2 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, cb + 1);
|
||
|
lpMem32 = GlobalLock(hlParam2);
|
||
|
|
||
|
if (vp) {
|
||
|
if (lpMem32) {
|
||
|
GETMISCPTR(vp, lpMem16);
|
||
|
RtlCopyMemory(lpMem32, lpMem16, cb);
|
||
|
GlobalUnlock(hlParam2);
|
||
|
}
|
||
|
GlobalUnlock16(FETCHWORD(ptag16->lParam2));
|
||
|
}
|
||
|
|
||
|
}
|
||
|
imestruct32->lParam1 = (LPARAM)hlParam1;
|
||
|
imestruct32->lParam2 = (LPARAM)hlParam2;
|
||
|
STOREDWORD(imestruct32->lParam3, ptag16->lParam3);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IME_SETCONVERSIONFONT: // (IME_SET_MODE - Korea)
|
||
|
{
|
||
|
LOGFONT * logfont32;
|
||
|
|
||
|
if (GetSystemDefaultLangID() == 0x412) {
|
||
|
// Hunguel WOW should do anything for IME_SET_MODE function
|
||
|
goto eee;
|
||
|
}
|
||
|
|
||
|
STOREDWORD(imestruct32->fnc, IME_SETCONVERSIONFONTEX);
|
||
|
if ( ptag16->wParam ) {
|
||
|
hLFNT32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(LOGFONT));
|
||
|
logfont32 = GlobalLock(hLFNT32);
|
||
|
GetObject(HOBJ32(ptag16->wParam), sizeof(LOGFONT), logfont32);
|
||
|
GlobalUnlock(hLFNT32);
|
||
|
}
|
||
|
else {
|
||
|
hLFNT32 = NULL;
|
||
|
}
|
||
|
imestruct32->lParam1 = (LPARAM)hLFNT32;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IME_SETCONVERSIONFONTEX: // Win3.1
|
||
|
{
|
||
|
LOGFONT * logfont32;
|
||
|
|
||
|
STOREDWORD(imestruct32->fnc, IME_SETCONVERSIONFONTEX);
|
||
|
|
||
|
if (!(ptag16->lParam1)) {
|
||
|
imestruct32->lParam1 = (LPARAM)NULL;
|
||
|
break;
|
||
|
}
|
||
|
hLFNT32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(LOGFONT));
|
||
|
logfont32 = GlobalLock(hLFNT32);
|
||
|
|
||
|
if (logfont32) {
|
||
|
vp = GlobalLock16(FETCHWORD(ptag16->lParam1), NULL);
|
||
|
// GETMISCPTR(vp, logfont16);
|
||
|
GETLOGFONT16(vp, logfont32);
|
||
|
GlobalUnlock16(FETCHWORD(ptag16->lParam1));
|
||
|
GlobalUnlock(hLFNT32);
|
||
|
}
|
||
|
|
||
|
imestruct32->lParam1 = (LPARAM)hLFNT32;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case IME_PRIVATE:
|
||
|
LOGDEBUG(0,(" ERROR:SendIMEMessageEx IME_PRIVATE NOT YET IMPLEMENTED\n"));
|
||
|
goto eee;
|
||
|
|
||
|
case IME_ENABLEDOSIME: // (IME_ENABLE)
|
||
|
default:
|
||
|
LOGDEBUG(0,(" ERROR:SendIMEMessageEx unexpected subfunction\n"));
|
||
|
LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGEEX %s\n",
|
||
|
wow32imedebug[ptag16->fnc]));
|
||
|
goto eee;
|
||
|
}
|
||
|
|
||
|
LOGDEBUG(1,(" WINNLS:SENDIMEMESSAGEEX %s\n",
|
||
|
wow32imedebug[ptag16->fnc]));
|
||
|
LOGDEBUG(1,(" IMESTRUCT16 Size = %d\n",
|
||
|
sizeof(IMESTRUCT16)));
|
||
|
LOGDEBUG(1,("WINNLS: IMESTRUCT.fnc == %x wParam == %x\n",
|
||
|
imestruct32->fnc,imestruct32->wParam));
|
||
|
LOGDEBUG(1,("WINNLS: IMESTRUCT.wCount == %x dchSource == %x\n",
|
||
|
imestruct32->wCount,imestruct32->dchSource));
|
||
|
LOGDEBUG(1,("WINNLS: IMESTRUCT.dchDest == %x lParam1 == %x\n",
|
||
|
imestruct32->dchDest,imestruct32->lParam1));
|
||
|
LOGDEBUG(1,("WINNLS: IMESTRUCT.lParam2 == %x lParam3 == %x\n",
|
||
|
imestruct32->lParam2,imestruct32->lParam3));
|
||
|
LOGDEBUG(1,("WINNLS: hwnd == %x %x\n",
|
||
|
parg16->hwnd,HWND32(parg16->hwnd)));
|
||
|
|
||
|
GlobalUnlock(hIME32);
|
||
|
|
||
|
// For win31 compatibility, since win31 didn't check the first
|
||
|
// parm, check it here and fill in a dummy (WOW) hwnd if its bogus
|
||
|
// so that NT doesn't reject the call
|
||
|
|
||
|
ul = SendIMEMessageEx(
|
||
|
((parg16->hwnd) ? HWND32(parg16->hwnd) : (HWND)0xffff0000),
|
||
|
(LPARAM)hIME32);
|
||
|
|
||
|
LOGDEBUG(1,("WINNLS: Ret == %x\n", ul ));
|
||
|
|
||
|
imestruct32=GlobalLock(hIME32);
|
||
|
|
||
|
if ( NULL == imestruct32 ) {
|
||
|
LOGDEBUG(1,("WINNLS: imestruct32 == NULL"));
|
||
|
goto eee;
|
||
|
}
|
||
|
|
||
|
LOGDEBUG(1,("WINNLS: wParam == %x\n\n", imestruct32->wParam ));
|
||
|
|
||
|
STOREWORD(ptag16->wParam, imestruct32->wParam);
|
||
|
|
||
|
switch (ptag16->fnc) {
|
||
|
case IME_GETOPEN:
|
||
|
STOREWORD(ptag16->wCount, imestruct32->wCount);
|
||
|
break;
|
||
|
case IME_ENTERWORDREGISTERMODE: // (IME_WORDREGISTER)
|
||
|
if (hlParam1)
|
||
|
GlobalFree(hlParam1);
|
||
|
if (hlParam2)
|
||
|
GlobalFree(hlParam2);
|
||
|
break;
|
||
|
case IME_SETCONVERSIONFONT: // (IME_SETFONT)
|
||
|
{
|
||
|
HAND16 hTmp;
|
||
|
hTmp = ptag16->wParam;
|
||
|
ul = (hFnt16);
|
||
|
hFnt16 = hTmp;
|
||
|
ul = TRUE;
|
||
|
// kksuszuka #1765 v-hidekk
|
||
|
if(hLFNT32)
|
||
|
GlobalFree(hLFNT32);
|
||
|
}
|
||
|
break;
|
||
|
case IME_SETCONVERSIONFONTEX:
|
||
|
if(ptag16->lParam1)
|
||
|
GlobalFree(hLFNT32);
|
||
|
break;
|
||
|
case IME_GETVERSION:
|
||
|
// PowerPoint4J must have version returned as 3.1
|
||
|
// Or else it thinks that the ime doesn't support IR_UNDETERMINE
|
||
|
if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_PPT4J_IME_GETVERSION) {
|
||
|
STOREWORD(ptag16->wParam, 0x0A03);
|
||
|
}
|
||
|
// WARNING: For DaytonaJ RC1 only!!!
|
||
|
// Tell Winword6J that the IME doesn't support TrueInline (undetermine msgs)
|
||
|
// So, that WinWord6J doesn't hang up doing the input loop processing of it.
|
||
|
else if (CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_WORDJ_IME_GETVERSION) {
|
||
|
STOREWORD(ptag16->wParam, 0x0003);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
eee:
|
||
|
GlobalUnlock(hIME32);
|
||
|
GlobalFree(hIME32);
|
||
|
GlobalUnlock16(FETCHWORD(parg16->lParam));
|
||
|
FREEVDMPTR(ptag16);
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
return(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WN32WINNLSGetIMEHotkey(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul;
|
||
|
register PWINNLSGETIMEHOTKEY16 parg16;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(WINNLSGETIMEHOTKEY16), parg16);
|
||
|
|
||
|
LOGDEBUG(1,(" WINNLS:GetIMEHotkey %x \n",
|
||
|
parg16->hwnd));
|
||
|
|
||
|
ul = GETWORD16(WINNLSGetIMEHotkey(
|
||
|
HWND32(parg16->hwnd)
|
||
|
));
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
RETURN(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WN32WINNLSEnableIME(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul;
|
||
|
register PWINNLSENABLEIME16 parg16;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(WINNLSENABLEIME16), parg16);
|
||
|
|
||
|
// The spec says the first parameter should always be NULL.
|
||
|
// Windows 3.1 ignores the first parameter and lets the call proceed.
|
||
|
// Windows NT ignores the call if the first paramater is non-null
|
||
|
// For compatibility purposes, pass NULL to user32 so that the call
|
||
|
// will proceed as in win3.1
|
||
|
//
|
||
|
|
||
|
ul = GETBOOL16(WINNLSEnableIME( NULL, WORD32(parg16->fEnabled) ));
|
||
|
|
||
|
LOGDEBUG(1,(" WINNLS:EnableIME %x %x %x\n",
|
||
|
parg16->hwnd, parg16->fEnabled, ul ));
|
||
|
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
RETURN(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WN32WINNLSGetEnableStatus(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul;
|
||
|
register PWINNLSGETENABLESTATUS16 parg16;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(WINNLSGETENABLESTATUS16), parg16);
|
||
|
|
||
|
LOGDEBUG(1,(" WINNLS:GetEnableStatus %x \n",
|
||
|
parg16->hwnd));
|
||
|
|
||
|
// Call the user32 with a NULL pwnd for the same reason as
|
||
|
// in WINNLSEnableIME above.
|
||
|
//
|
||
|
ul = GETWORD16(WINNLSGetEnableStatus( NULL ));
|
||
|
|
||
|
FREEARGPTR(parg16);
|
||
|
|
||
|
RETURN(ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WN32IMPQueryIME(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul=0;
|
||
|
PIMPQUERYIME16 parg16;
|
||
|
register PIMEPRO16 pime16;
|
||
|
PIMEPRO pimepro32;
|
||
|
HANDLE hIME32;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(IMPQUERYIME16), parg16);
|
||
|
GETVDMPTR(parg16->lpIMEPro,sizeof(IMEPRO16), pime16);
|
||
|
if(pime16==NULL){
|
||
|
LOGDEBUG(1,(" WINNLS:(Jun)pime16==NULL!!"));
|
||
|
goto fff;
|
||
|
|
||
|
}
|
||
|
LOGDEBUG(1,(" WINNLS:IMPQueryIME called\n"));
|
||
|
hIME32=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMEPRO));
|
||
|
pimepro32=GlobalLock(hIME32);
|
||
|
|
||
|
if (pimepro32 ) {
|
||
|
if (pime16->szName[0])
|
||
|
GETIMEPRO16(pimepro32,pime16);
|
||
|
else
|
||
|
pimepro32->szName[0]=pime16->szName[0];
|
||
|
|
||
|
ul=IMPQueryIME(pimepro32);
|
||
|
|
||
|
SETIMEPRO16(pime16,pimepro32);
|
||
|
|
||
|
GlobalUnlock(hIME32);
|
||
|
}
|
||
|
if ( hIME32 ) {
|
||
|
GlobalFree(hIME32);
|
||
|
}
|
||
|
fff:
|
||
|
FREEVDMPTR(pime16);
|
||
|
FREEARGPTR(parg16);
|
||
|
return (ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WN32IMPGetIME(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul = 0;
|
||
|
PIMPGETIME16 parg16;
|
||
|
register PIMEPRO16 pime16;
|
||
|
PIMEPRO pimepro32;
|
||
|
HANDLE hIME32;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(IMPGETIME16), parg16);
|
||
|
GETVDMPTR(parg16->lpIMEPro,sizeof(IMEPRO16), pime16);
|
||
|
if(pime16==NULL){
|
||
|
LOGDEBUG(1,(" WINNLS:(Jun)pime16==NULL!!"));
|
||
|
goto fff;
|
||
|
|
||
|
}
|
||
|
LOGDEBUG(1,(" WINNLS:IMPGetIME called\n"));
|
||
|
hIME32=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMEPRO));
|
||
|
pimepro32=GlobalLock(hIME32);
|
||
|
|
||
|
if (pimepro32 ) {
|
||
|
// not use app,s handle IMPGetIME(HWND32(parg16->hwnd), pimepro32);
|
||
|
ul=IMPGetIME(NULL, pimepro32);
|
||
|
|
||
|
SETIMEPRO16(pime16, pimepro32);
|
||
|
}
|
||
|
|
||
|
GlobalUnlock(hIME32);
|
||
|
if ( hIME32 ) {
|
||
|
GlobalFree(hIME32);
|
||
|
}
|
||
|
fff:
|
||
|
FREEVDMPTR(pime16);
|
||
|
FREEARGPTR(parg16);
|
||
|
return (ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
ULONG FASTCALL WN32IMPSetIME(PVDMFRAME pFrame)
|
||
|
{
|
||
|
ULONG ul = 0;
|
||
|
PIMPSETIME16 parg16;
|
||
|
register PIMEPRO16 pime16;
|
||
|
PIMEPRO pimepro32;
|
||
|
HANDLE hIME32;
|
||
|
INT i;
|
||
|
|
||
|
GETARGPTR(pFrame, sizeof(IMPSETIME16), parg16);
|
||
|
GETVDMPTR(parg16->lpIMEPro,sizeof(IMEPRO16), pime16);
|
||
|
if(pime16==NULL){
|
||
|
LOGDEBUG(1,(" WINNLS:(Jun)pime16==NULL!!"));
|
||
|
goto fff;
|
||
|
|
||
|
}
|
||
|
LOGDEBUG(1,(" WINNLS:IMPSetIME called\n"));
|
||
|
hIME32=GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMEPRO));
|
||
|
pimepro32=GlobalLock(hIME32);
|
||
|
if (pime16->szName[0]) {
|
||
|
for(i=0; i < (sizeof(pimepro32->szName) /
|
||
|
sizeof(pimepro32->szName[0])); i++)
|
||
|
pimepro32->szName[i]=pime16->szName[i];
|
||
|
}
|
||
|
else
|
||
|
pimepro32->szName[0]=pime16->szName[0];
|
||
|
|
||
|
// not use app,s handle IMPSetIME(HWND32(parg16->hwnd), pimepro32);
|
||
|
ul = IMPSetIME(NULL, pimepro32);
|
||
|
|
||
|
GlobalUnlock(hIME32);
|
||
|
GlobalFree(hIME32);
|
||
|
fff:
|
||
|
FREEVDMPTR(pime16);
|
||
|
FREEARGPTR(parg16);
|
||
|
return (ul);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID GETIMEPRO16(PIMEPRO pimepro32,PIMEPRO16 pime16)
|
||
|
{
|
||
|
INT i;
|
||
|
|
||
|
pimepro32->hWnd = HWND32(pime16->hWnd);
|
||
|
STOREWORD(pimepro32->InstDate.year, pime16->InstDate.year);
|
||
|
STOREWORD(pimepro32->InstDate.month, pime16->InstDate.month);
|
||
|
STOREWORD(pimepro32->InstDate.day, pime16->InstDate.day);
|
||
|
STOREWORD(pimepro32->InstDate.hour, pime16->InstDate.hour);
|
||
|
STOREWORD(pimepro32->InstDate.min, pime16->InstDate.min);
|
||
|
STOREWORD(pimepro32->InstDate.sec, pime16->InstDate.sec);
|
||
|
STOREWORD(pimepro32->wVersion, pime16->wVersion);
|
||
|
|
||
|
for(i=0;i<(sizeof(pimepro32->szDescription)/
|
||
|
sizeof(pimepro32->szDescription[0]));i++)
|
||
|
pimepro32->szDescription[i]=pime16->szDescription[i];
|
||
|
|
||
|
for(i=0;i<(sizeof(pimepro32->szName)/
|
||
|
sizeof(pimepro32->szName[0]));i++)
|
||
|
pimepro32->szName[i]=pime16->szName[i];
|
||
|
|
||
|
for(i=0;i<(sizeof(pimepro32->szOptions)/
|
||
|
sizeof(pimepro32->szOptions[0]));i++)
|
||
|
pimepro32->szOptions[i]=pime16->szOptions[i];
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID SETIMEPRO16(PIMEPRO16 pime16, PIMEPRO pimepro32)
|
||
|
{
|
||
|
INT i;
|
||
|
|
||
|
pime16->hWnd = GETHWND16(pimepro32->hWnd);
|
||
|
STOREWORD(pime16->InstDate.year,pimepro32->InstDate.year);
|
||
|
STOREWORD(pime16->InstDate.month,pimepro32->InstDate.month);
|
||
|
STOREWORD(pime16->InstDate.day,pimepro32->InstDate.day);
|
||
|
STOREWORD(pime16->InstDate.hour,pimepro32->InstDate.hour);
|
||
|
STOREWORD(pime16->InstDate.min,pimepro32->InstDate.min);
|
||
|
STOREWORD(pime16->InstDate.sec,pimepro32->InstDate.sec);
|
||
|
STOREWORD(pime16->wVersion,pimepro32->wVersion);
|
||
|
|
||
|
for(i=0;i<(sizeof(pimepro32->szDescription)/
|
||
|
sizeof(pimepro32->szDescription[0]));i++)
|
||
|
pime16->szDescription[i]=pimepro32->szDescription[i];
|
||
|
|
||
|
for(i=0;i<(sizeof(pimepro32->szName)/
|
||
|
sizeof(pimepro32->szName[0]));i++)
|
||
|
pime16->szName[i]=pimepro32->szName[i];
|
||
|
|
||
|
for(i=0;i<(sizeof(pimepro32->szOptions)/
|
||
|
sizeof(pimepro32->szOptions[0]));i++)
|
||
|
pime16->szOptions[i]=pimepro32->szOptions[i];
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Notify IMM32 wow task exit so that
|
||
|
// it can perform any clean up.
|
||
|
//
|
||
|
VOID WN32WINNLSSImeNotifyTaskExit()
|
||
|
{
|
||
|
#if 0
|
||
|
HANDLE hIME32;
|
||
|
IMESTRUCT * imestruct32;
|
||
|
|
||
|
hIME32 = GlobalAlloc(GMEM_SHARE | GMEM_MOVEABLE, sizeof(IMESTRUCT));
|
||
|
if ( hIME32 == NULL )
|
||
|
return;
|
||
|
|
||
|
if ( (imestruct32 = GlobalLock(hIME32) ) != NULL ) {
|
||
|
imestruct32->fnc = IME_NOTIFYWOWTASKEXIT;
|
||
|
GlobalUnlock(hIME32);
|
||
|
SendIMEMessageEx( NULL, (LPARAM)hIME32 );
|
||
|
}
|
||
|
GlobalFree(hIME32);
|
||
|
#endif
|
||
|
}
|
||
|
#endif // FE_IME
|