00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
#include "precomp.h"
00013
#pragma hdrstop
00014
00015
#include <intlshar.h>
00016
00017 #define LATE_CREATEUI 1
00018
00019 CONST WCHAR
szIndicDLL[] =
L"indicdll.dll";
00020
00021 FARPROC
gpfnGetIMEMenuItemData =
NULL;
00022
BOOL IMEIndicatorGetMenuIDData(PUINT puMenuID, PDWORD pdwData);
00023
00024
00025
00026
00027 LONG
ImeWndCreateHandler(
PIMEUI, LPCREATESTRUCT);
00028
void ImeWndDestroyHandler(
PIMEUI);
00029 LRESULT
ImeSystemHandler(
PIMEUI, UINT, WPARAM, LPARAM);
00030 LONG
ImeSelectHandler(
PIMEUI, UINT, WPARAM, LPARAM);
00031 LRESULT
ImeControlHandler(
PIMEUI, UINT, WPARAM, LPARAM, BOOL);
00032 LRESULT
ImeSetContextHandler(
PIMEUI, UINT, WPARAM, LPARAM);
00033 LRESULT
ImeNotifyHandler(
PIMEUI, UINT, WPARAM, LPARAM);
00034 HWND
CreateIMEUI(
PIMEUI, HKL);
00035
VOID DestroyIMEUI(
PIMEUI);
00036 LRESULT
SendMessageToUI(
PIMEUI, UINT, WPARAM, LPARAM, BOOL);
00037
VOID SendOpenStatusNotify(
PIMEUI, HWND, BOOL);
00038
VOID ImeSetImc(
PIMEUI, HIMC);
00039
VOID FocusSetIMCContext(HWND, BOOL);
00040
BOOL ImeBroadCastMsg(
PIMEUI, UINT, WPARAM, LPARAM);
00041
VOID ImeMarkUsedContext(HWND, HIMC);
00042
BOOL ImeIsUsableContext(HWND, HIMC);
00043
BOOL GetIMEShowStatus(
void);
00044 LRESULT
ImeCopyDataHandler(WPARAM, LPARAM);
00045
00046
00047
00048
00049 #define GETHKL(pimeui) (pimeui->hKL)
00050 #define SETHKL(pimeui, hkl) (pimeui->hKL=(hkl))
00051 #define GETIMC(pimeui) (pimeui->hIMC)
00052 #define SETIMC(pimeui, himc) (ImeSetImc(pimeui, himc))
00053 #define GETUI(pimeui) (pimeui->hwndUI)
00054 #define SETUI(pimeui, hwndui) (pimeui->hwndUI=(hwndui))
00055
00056 LOOKASIDE ImeUILookaside;
00057
00058
00059
00060
00061
00062
00063
00064
00065 _inline
void NtUserBroadcastImeShowStatusChange(HWND hwndDefIme, BOOL fShow)
00066 {
00067
NtUserCallHwndParamLock(hwndDefIme, fShow, SFI_XXXBROADCASTIMESHOWSTATUSCHANGE);
00068 }
00069
00070 _inline
void NtUserCheckImeShowStatusInThread(HWND hwndDefIme)
00071 {
00072
NtUserCallHwndLock(hwndDefIme, SFI_XXXCHECKIMESHOWSTATUSINTHREAD);
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 LRESULT
APIENTRY ImeWndProcWorker(
00084
PWND pwnd,
00085 UINT message,
00086 WPARAM wParam,
00087 LPARAM lParam,
00088 DWORD fAnsi)
00089 {
00090 HWND hwnd =
HWq(pwnd);
00091
PIMEUI pimeui;
00092
static BOOL fInit =
TRUE;
00093
00094
CheckLock(pwnd);
00095
00096
VALIDATECLASSANDSIZE(pwnd,
FNID_IME);
00097
INITCONTROLLOOKASIDE(&
ImeUILookaside,
IMEUI, spwnd, 8);
00098
00099
00100
00101
00102
00103
if (!
FWINDOWMSG(message,
FNID_IME))
00104
return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi);
00105
00106
00107
00108
00109
00110
00111 pimeui = ((
PIMEWND)pwnd)->pimeui;
00112
00113
if (pimeui ==
NULL) {
00114
00115
00116
00117 RIPMSG0(RIP_WARNING,
"ImeWndProcWorker: pimeui == NULL\n");
00118
return 0
L;
00119 }
00120
00121
00122
00123
00124 UserAssert(pimeui->
nCntInIMEProc >= 0);
00125
00126
if (pimeui->
nCntInIMEProc > 0) {
00127 TAGMSG5(DBGTAG_IMM,
"ImeWndProcWorker: Recursive for pwnd=%08p, msg=%08x, wp=%08x, lp=%08x, fAnsi=%d\n",
00128 pwnd, message, wParam, lParam, fAnsi);
00129
switch (message) {
00130
case WM_IME_SYSTEM:
00131
switch (wParam) {
00132
case IMS_ISACTIVATED:
00133
case IMS_SETOPENSTATUS:
00134
00135
case IMS_SETSOFTKBDONOFF:
00136
00137
00138
00139
00140
break;
00141
00142
default:
00143
return 0
L;
00144 }
00145
break;
00146
00147
case WM_IME_STARTCOMPOSITION:
00148
case WM_IME_ENDCOMPOSITION:
00149
case WM_IME_COMPOSITION:
00150
case WM_IME_SETCONTEXT:
00151
case WM_IME_NOTIFY:
00152
case WM_IME_CONTROL:
00153
case WM_IME_COMPOSITIONFULL:
00154
case WM_IME_SELECT:
00155
case WM_IME_CHAR:
00156
case WM_IME_REQUEST:
00157
return 0
L;
00158
00159
default:
00160
return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi);
00161 }
00162 }
00163
00164
if (
TestWF(pwnd,
WFINDESTROY) ||
TestWF(pwnd,
WFDESTROYED)) {
00165
switch (message) {
00166
case WM_DESTROY:
00167
case WM_NCDESTROY:
00168
case WM_FINALDESTROY:
00169
break;
00170
default:
00171 RIPMSG1(RIP_WARNING,
"ImeWndProcWorker: message %x is sent to destroyed window.", message);
00172
return 0
L;
00173 }
00174 }
00175
00176
switch (message) {
00177
case WM_ERASEBKGND:
00178
return (LONG)
TRUE;
00179
00180
case WM_PAINT:
00181
break;
00182
00183
case WM_CREATE:
00184
00185
return ImeWndCreateHandler(pimeui, (LPCREATESTRUCT)lParam);
00186
00187
case WM_DESTROY:
00188
00189
00190
00191
00192
ImeWndDestroyHandler(pimeui);
00193
break;
00194
00195
case WM_NCDESTROY:
00196
case WM_FINALDESTROY:
00197
if (pimeui) {
00198
Unlock(&pimeui->
spwnd);
00199
FreeLookasideEntry(&
ImeUILookaside, pimeui);
00200 }
00201
NtUserSetWindowFNID(hwnd,
FNID_CLEANEDUP_BIT);
00202
goto CallDWP;
00203
00204
case WM_IME_SYSTEM:
00205 UserAssert(pimeui->
spwnd == pwnd);
00206
return ImeSystemHandler(pimeui, message, wParam, lParam);
00207
00208
case WM_IME_SELECT:
00209
return ImeSelectHandler(pimeui, message, wParam, lParam);
00210
00211
case WM_IME_CONTROL:
00212
return ImeControlHandler(pimeui, message, wParam, lParam, fAnsi);
00213
00214
case WM_IME_SETCONTEXT:
00215
return ImeSetContextHandler(pimeui, message, wParam, lParam);
00216
00217
case WM_IME_NOTIFY:
00218
return ImeNotifyHandler(pimeui, message, wParam, lParam);
00219
00220
case WM_IME_REQUEST:
00221
return 0;
00222
00223
case WM_IME_COMPOSITION:
00224
case WM_IME_ENDCOMPOSITION:
00225
case WM_IME_STARTCOMPOSITION:
00226
return SendMessageToUI(pimeui, message, wParam, lParam, fAnsi);
00227
00228
case WM_COPYDATA:
00229
return ImeCopyDataHandler(wParam, lParam);
00230
00231
default:
00232 CallDWP:
00233
return DefWindowProcWorker(pwnd, message, wParam, lParam, fAnsi);
00234 }
00235
00236
return 0
L;
00237 }
00238
00239
00240 LRESULT WINAPI
ImeWndProcA(
00241 HWND hwnd,
00242 UINT message,
00243 WPARAM wParam,
00244 LPARAM lParam)
00245 {
00246
PWND pwnd;
00247
00248
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL) {
00249
return (0
L);
00250 }
00251
00252
return ImeWndProcWorker(pwnd, message, wParam, lParam,
TRUE);
00253 }
00254
00255
00256 LRESULT WINAPI
ImeWndProcW(
00257 HWND hwnd,
00258 UINT message,
00259 WPARAM wParam,
00260 LPARAM lParam)
00261 {
00262
PWND pwnd;
00263
00264
if ((pwnd =
ValidateHwnd(hwnd)) ==
NULL) {
00265
return (0
L);
00266 }
00267
00268
return ImeWndProcWorker(pwnd, message, wParam, lParam,
FALSE);
00269 }
00270
00271
00272 LONG
ImeWndCreateHandler(
00273
PIMEUI pimeui,
00274 LPCREATESTRUCT lpcs)
00275 {
00276
PWND pwndParent;
00277 HIMC hImc;
00278
PWND pwndIme = pimeui->
spwnd;
00279
#if _DBG
00280
static DWORD dwFirstWinlogonThreadId;
00281
#endif
00282
extern BOOL gfLogonProcess;
00283
00284
#if _DBG
00285
00286
00287
00288
if (
gfLogonProcess) {
00289 UserAssert(dwFirstWinLogonThreadId == 0);
00290 dwFirstWinlogonThreadId = GetCurrentThreadId();
00291 }
00292
#endif
00293
00294
if (!
TestWF(pwndIme,
WFPOPUP) || !
TestWF(pwndIme,
WFDISABLED)) {
00295 RIPMSG0(RIP_WARNING,
"IME window should have WS_POPUP and WS_DISABLE!!");
00296
return -1
L;
00297 }
00298
00299
00300
00301
00302
00303
if ((pwndParent =
ValidateHwndNoRip(lpcs->hwndParent)) !=
NULL) {
00304 hImc = pwndParent->
hImc;
00305
if (hImc !=
NULL_HIMC &&
ImeIsUsableContext(
HWq(pwndIme), hImc)) {
00306
00307
00308
00309
SETIMC(pimeui, hImc);
00310 }
00311
else {
00312
SETIMC(pimeui,
NULL_HIMC);
00313 }
00314 }
00315
else {
00316
SETIMC(pimeui,
NULL_HIMC);
00317 }
00318
00319
00320
00321
00322
00323 pimeui->
fShowStatus = 0;
00324 pimeui->
nCntInIMEProc = 0;
00325 pimeui->
fActivate = 0;
00326 pimeui->
fDestroy = 0;
00327 pimeui->
hwndIMC =
NULL;
00328 pimeui->
hKL =
THREAD_HKL();
00329 pimeui->
fCtrlShowStatus =
TRUE;
00330
00331
00332
00333
00334
fpImmLoadIME(pimeui->
hKL);
00335
00336
#ifdef LATE_CREATEUI
00337
SETUI(pimeui,
NULL);
00338
#else
00339
SETUI(pimeui,
CreateIMEUI(pimeui, pimeui->
hKL));
00340
#endif
00341
00342
return 0
L;
00343 }
00344
00345 void ImeWndDestroyHandler(
00346
PIMEUI pimeui)
00347 {
00348
DestroyIMEUI(pimeui);
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 void ImeRunHelp(LPWSTR wszHelpFile)
00362 {
00363
static const WCHAR wszHelpFileExt[] =
L".HLP";
00364
UINT cchLen = wcslen(wszHelpFile);
00365
00366
if (cchLen > 4 && _wcsicmp(wszHelpFile + cchLen - 4, wszHelpFileExt) == 0) {
00367
#ifdef FYI
00368
WinHelpW(
NULL, wszHelpFile, HELP_CONTENTS, 0);
00369
#else
00370
WinHelpW(
NULL, wszHelpFile, HELP_FINDER, 0);
00371
#endif
00372
}
else {
00373
00374
00375
00376
00377
static const WCHAR wszHH[] =
L"hh.exe ";
00378 WCHAR wszCmdLine[
MAX_PATH * 2];
00379 LPWSTR lpwszCmdLine = wszCmdLine;
00380
DWORD idProcess;
00381 STARTUPINFO StartupInfo;
00382 PROCESS_INFORMATION ProcessInformation;
00383
UINT i;
00384
00385 i = GetSystemWindowsDirectoryW(wszCmdLine,
MAX_PATH);
00386
if (i > 0 && i <
MAX_PATH - cchLen - (
sizeof L'\\' +
sizeof wszHH) /
sizeof(WCHAR)) {
00387 lpwszCmdLine += i;
00388
if (lpwszCmdLine[-1] !=
L'\\') {
00389 *lpwszCmdLine++ =
L'\\';
00390 }
00391 }
00392 wcscpy(lpwszCmdLine, wszHH);
00393 wcscat(lpwszCmdLine, wszHelpFile);
00394
00395
00396
00397
00398 RtlZeroMemory(&StartupInfo,
sizeof(StartupInfo));
00399 StartupInfo.cb =
sizeof(StartupInfo);
00400 StartupInfo.wShowWindow = SW_SHOW;
00401 StartupInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;
00402
00403 TAGMSG1(DBGTAG_IMM,
"Invoking help with '%S'", wszCmdLine);
00404
00405 idProcess = (
DWORD)CreateProcessW(
NULL, wszCmdLine,
00406
NULL,
NULL,
FALSE, NORMAL_PRIORITY_CLASS,
NULL,
NULL, &StartupInfo,
00407 &ProcessInformation);
00408
00409
if (idProcess) {
00410
WaitForInputIdle(ProcessInformation.hProcess, 10000);
00411
NtClose(ProcessInformation.hProcess);
00412
NtClose(ProcessInformation.hThread);
00413 }
00414 }
00415 }
00416
00417 LRESULT
ImeSystemHandler(
00418
PIMEUI pimeui,
00419 UINT message,
00420 WPARAM wParam,
00421 LPARAM lParam)
00422 {
00423 PINPUTCONTEXT pInputContext;
00424 HIMC hImc =
GETIMC(pimeui);
00425 LRESULT dwRet = 0
L;
00426
00427 UNREFERENCED_PARAMETER(message);
00428
00429
switch (wParam) {
00430
00431
case IMS_SETOPENCLOSE:
00432
if (hImc !=
NULL_HIMC)
00433
fpImmSetOpenStatus(hImc, (
BOOL)lParam);
00434
break;
00435
00436
#ifdef LATER
00437
case IMS_WINDOWPOS:
00438
if (hImc !=
NULL_HIMC) {
00439
INT i;
00440
BOOL f31Hidden =
FALSE:
00441
00442
if ((pInputContext =
fpImmLockIMC(hImc)) !=
NULL) {
00443 f31Hidden = (pInputContext & F31COMPAT_MCWHIDDEN) ?
TRUE :
FALSE;
00444
fpImmUnlockIMC(hImc);
00445 }
00446
00447
if (
IsWindow(pimeui->
hwndIMC)) {
00448
if (!f31Hidden) {
00449 }
00450 }
00451 }
00452
#endif
00453
00454
case IMS_ACTIVATECONTEXT:
00455
FocusSetIMCContext((HWND)(lParam),
TRUE);
00456
break;
00457
00458
case IMS_DEACTIVATECONTEXT:
00459
FocusSetIMCContext((HWND)(lParam),
FALSE);
00460
break;
00461
00462
case IMS_UNLOADTHREADLAYOUT:
00463
return (LONG)(
fpImmFreeLayout((
DWORD)lParam));
00464
00465
case IMS_ACTIVATETHREADLAYOUT:
00466
return (LONG)(
fpImmActivateLayout((HKL)lParam));
00467
00468
case IMS_SETCANDIDATEPOS:
00469
if ( (pInputContext =
fpImmLockIMC( hImc )) !=
NULL ) {
00470 LPCANDIDATEFORM lpcaf;
00471
DWORD dwIndex = (
DWORD)lParam;
00472
00473 lpcaf = &(pInputContext->cfCandForm[dwIndex]);
00474
fpImmSetCandidateWindow( hImc, lpcaf );
00475
fpImmUnlockIMC( hImc );
00476 }
00477
break;
00478
00479
case IMS_SETCOMPOSITIONWINDOW:
00480
if ( (pInputContext =
fpImmLockIMC( hImc )) !=
NULL ) {
00481 LPCOMPOSITIONFORM lpcof;
00482
00483 lpcof = &(pInputContext->cfCompForm);
00484 pInputContext->fdw31Compat |= F31COMPAT_CALLFROMWINNLS;
00485
fpImmSetCompositionWindow( hImc, lpcof);
00486 }
00487
break;
00488
00489
case IMS_SETCOMPOSITIONFONT:
00490
if ( (pInputContext =
fpImmLockIMC( hImc )) !=
NULL ) {
00491 LPLOGFONT lplf;
00492
00493 lplf = &(pInputContext->lfFont.W);
00494
fpImmSetCompositionFont( hImc, lplf );
00495 }
00496
break;
00497
00498
case IMS_CONFIGUREIME:
00499
fpImmConfigureIMEW( (HKL)lParam, pimeui->
hwndIMC, IME_CONFIG_GENERAL,
NULL);
00500
break;
00501
00502
case IMS_CHANGE_SHOWSTAT:
00503
00504
00505
if (
GetIMEShowStatus() == !lParam) {
00506
#if 1
00507
NtUserBroadcastImeShowStatusChange(
HW(pimeui->
spwnd), !!lParam);
00508
#else
00509
SystemParametersInfo(SPI_SETSHOWIMEUI, lParam,
NULL,
FALSE);
00510
#endif
00511
}
00512
break;
00513
00514
case IMS_GETCONVERSIONMODE:
00515 {
00516
DWORD dwConv = 0;
00517
DWORD dwTemp;
00518
00519
fpImmGetConversionStatus(hImc, &dwConv, &dwTemp);
00520
return (dwConv);
00521
break;
00522 }
00523
00524
case IMS_SETSOFTKBDONOFF:
00525
fpImmEnumInputContext(0,
SyncSoftKbdState, lParam);
00526
break;
00527
00528
case IMS_GETIMEMENU:
00529
00530
00531
00532
return fpImmPutImeMenuItemsIntoMappedFile((HIMC)lParam);
00533
00534
case IMS_IMEHELP:
00535 dwRet = IME_ESC_GETHELPFILENAME;
00536 dwRet =
fpImmEscapeW(pimeui->
hKL, pimeui->
hIMC, IME_ESC_QUERY_SUPPORT, (
LPVOID)&dwRet);
00537
if (lParam) {
00538
00539 WCHAR wszHelpFile[
MAX_PATH];
00540
00541
if (dwRet) {
00542
if (
fpImmEscapeW(pimeui->
hKL, pimeui->
hIMC, IME_ESC_GETHELPFILENAME,
00543 (
LPVOID)wszHelpFile)) {
00544
ImeRunHelp(wszHelpFile);
00545 }
00546 }
00547 }
00548
return dwRet;
00549
00550
case IMS_GETCONTEXT:
00551 dwRet = (ULONG_PTR)
fpImmGetContext((HWND)lParam);
00552
return dwRet;
00553
00554
case IMS_ENDIMEMENU:
00555
00556
if (
IsWindow((HWND)lParam)) {
00557 HIMC hImc;
00558
UINT uID;
00559
DWORD dwData;
00560
00561 hImc =
fpImmGetContext((HWND)lParam);
00562
00563
if (hImc !=
NULL) {
00564
00565
00566
00567
if (
IMEIndicatorGetMenuIDData(&uID, &dwData)) {
00568
fpImmNotifyIME(hImc, NI_IMEMENUSELECTED, uID, dwData);
00569 }
00570
fpImmReleaseContext((HWND)lParam, hImc);
00571 }
00572 }
00573
break;
00574
00575
case IMS_SENDNOTIFICATION:
00576
case IMS_FINALIZE_COMPSTR:
00577 dwRet =
fpImmSystemHandler(hImc, wParam, lParam);
00578
break;
00579
00580
default:
00581
break;
00582 }
00583
00584
return dwRet;
00585 }
00586
00587
00588 LONG
ImeSelectHandler(
00589
PIMEUI pimeui,
00590 UINT message,
00591 WPARAM wParam,
00592 LPARAM lParam)
00593 {
00594 HWND hwndUI;
00595
00596
00597
00598
00599
if (pimeui->
fDefault)
00600
ImeBroadCastMsg(pimeui, message, wParam, lParam);
00601
00602
00603
00604
00605
if ((
BOOL)wParam ==
TRUE) {
00606 UserAssert(!
IsWindow(
GETUI(pimeui)));
00607
00608
SETHKL(pimeui, (HKL)lParam);
00609
00610
#ifdef LATE_CREATEUI
00611
if (!pimeui->
fActivate)
00612
return 0
L;
00613
#endif
00614
00615 hwndUI =
CreateIMEUI(pimeui, (HKL)lParam);
00616
00617
SETUI(pimeui, hwndUI);
00618
00619
if (hwndUI !=
NULL) {
00620
SetWindowLongPtr(hwndUI, IMMGWLP_IMC, (LONG_PTR)
GETIMC(pimeui));
00621
SendMessageToUI(pimeui, message, wParam, lParam,
FALSE);
00622 }
00623
00624
if (
GetIMEShowStatus() && pimeui->
fCtrlShowStatus) {
00625
if (!pimeui->
fShowStatus && pimeui->
fActivate &&
00626
IsWindow(pimeui->
hwndIMC)) {
00627
00628
00629
00630
00631
SendOpenStatusNotify(pimeui, pimeui->
hwndIMC,
TRUE);
00632 }
00633 }
00634 }
00635
else {
00636
00637
if (pimeui->
fShowStatus && pimeui->
fActivate &&
00638
IsWindow(pimeui->
hwndIMC)) {
00639
00640
00641
00642
00643
SendOpenStatusNotify(pimeui, pimeui->
hwndIMC,
FALSE);
00644 }
00645
00646
SendMessageToUI(pimeui, message, wParam, lParam,
FALSE);
00647
00648
DestroyIMEUI(pimeui);
00649
00650
SETHKL(pimeui, (HKL)
NULL);
00651 }
00652
00653
return 0
L;
00654 }
00655
00656
00657 LRESULT
ImeControlHandler(
00658
PIMEUI pimeui,
00659 UINT message,
00660 WPARAM wParam,
00661 LPARAM lParam,
00662 BOOL fAnsi)
00663 {
00664 HIMC hImc;
00665
DWORD dwConversion, dwSentence;
00666
00667
00668
00669
00670
if ((hImc =
GETIMC(pimeui)) ==
NULL_HIMC)
00671
return 0
L;
00672
00673
switch (wParam) {
00674
00675
case IMC_OPENSTATUSWINDOW:
00676
if (
GetIMEShowStatus() && !pimeui->
fShowStatus) {
00677 pimeui->
fShowStatus =
TRUE;
00678
SendMessageToUI(pimeui, WM_IME_NOTIFY,
00679 IMN_OPENSTATUSWINDOW, 0
L,
FALSE);
00680 }
00681 pimeui->
fCtrlShowStatus =
TRUE;
00682
break;
00683
00684
case IMC_CLOSESTATUSWINDOW:
00685
if (
GetIMEShowStatus() && pimeui->
fShowStatus) {
00686 pimeui->
fShowStatus =
FALSE;
00687
SendMessageToUI(pimeui, WM_IME_NOTIFY,
00688 IMN_CLOSESTATUSWINDOW, 0
L,
FALSE);
00689 }
00690 pimeui->
fCtrlShowStatus =
FALSE;
00691
break;
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
case IMC_SETCOMPOSITIONFONT:
00704
if (fAnsi) {
00705
if (!
fpImmSetCompositionFontA(hImc, (LPLOGFONTA)lParam))
00706
return 1
L;
00707 }
00708
else {
00709
if (!
fpImmSetCompositionFontW(hImc, (LPLOGFONTW)lParam))
00710
return 1
L;
00711 }
00712
break;
00713
00714
case IMC_SETCONVERSIONMODE:
00715
if (!
fpImmGetConversionStatus(hImc, &dwConversion, &dwSentence) ||
00716 !
fpImmSetConversionStatus(hImc, (
DWORD)lParam, dwSentence))
00717
return 1
L;
00718
break;
00719
00720
case IMC_SETSENTENCEMODE:
00721
if (!
fpImmGetConversionStatus(hImc, &dwConversion, &dwSentence) ||
00722 !
fpImmSetConversionStatus(hImc, dwConversion, (
DWORD)lParam))
00723
return 1
L;
00724
break;
00725
00726
case IMC_SETOPENSTATUS:
00727
if (!
fpImmSetOpenStatus(hImc, (
BOOL)lParam))
00728
return 1
L;
00729
break;
00730
00731
case IMC_GETCONVERSIONMODE:
00732
if (!
fpImmGetConversionStatus(hImc,&dwConversion, &dwSentence))
00733
return 1
L;
00734
00735
return (LONG)dwConversion;
00736
00737
case IMC_GETSENTENCEMODE:
00738
if (!
fpImmGetConversionStatus(hImc,&dwConversion, &dwSentence))
00739
return 1
L;
00740
00741
return (LONG)dwSentence;
00742
00743
case IMC_GETOPENSTATUS:
00744
return (LONG)
fpImmGetOpenStatus(hImc);
00745
00746
case IMC_GETCOMPOSITIONFONT:
00747
if (fAnsi) {
00748
if (!
fpImmGetCompositionFontA(hImc, (LPLOGFONTA)lParam))
00749
return 1
L;
00750 }
00751
else {
00752
if (!
fpImmGetCompositionFontW(hImc, (LPLOGFONTW)lParam))
00753
return 1
L;
00754 }
00755
break;
00756
00757
case IMC_SETCOMPOSITIONWINDOW:
00758
if (!
fpImmSetCompositionWindow(hImc, (LPCOMPOSITIONFORM)lParam))
00759
return 1
L;
00760
break;
00761
00762
case IMC_SETSTATUSWINDOWPOS:
00763 {
00764 POINT ppt;
00765
00766 ppt.x = (LONG)((LPPOINTS)&lParam)->x;
00767 ppt.y = (LONG)((LPPOINTS)&lParam)->y;
00768
00769
if (!
fpImmSetStatusWindowPos(hImc, &ppt))
00770
return 1
L;
00771 }
00772
break;
00773
00774
case IMC_SETCANDIDATEPOS:
00775
if (!
fpImmSetCandidateWindow(hImc, (LPCANDIDATEFORM)lParam))
00776
return 1;
00777
break;
00778
00779
00780
00781
00782
case IMC_GETCANDIDATEPOS:
00783
case IMC_GETSTATUSWINDOWPOS:
00784
case IMC_GETCOMPOSITIONWINDOW:
00785
case IMC_GETSOFTKBDPOS:
00786
case IMC_SETSOFTKBDPOS:
00787
return SendMessageToUI(pimeui, message, wParam, lParam, fAnsi);
00788
00789
default:
00790
break;
00791 }
00792
00793
return 0
L;
00794 }
00795
00796
00797
00798 LRESULT
ImeSetContextHandler(
00799
PIMEUI pimeui,
00800 UINT message,
00801 WPARAM wParam,
00802 LPARAM lParam)
00803 {
00804 HWND hwndPrevIMC, hwndFocus;
00805 HIMC hFocusImc;
00806 LRESULT lRet;
00807
00808 pimeui->
fActivate = (
BOOL)wParam ? 1 : 0;
00809 hwndPrevIMC = pimeui->
hwndIMC;
00810
00811
if (wParam) {
00812
00813
00814
00815
#ifdef LATE_CREATEUI
00816
if (!
GETUI(pimeui))
00817
SETUI(pimeui,
CreateIMEUI(pimeui,
GETHKL(pimeui)));
00818
#endif
00819
00820
00821
00822
00823
if (
gfConIme ==
UNKNOWN_CONIME) {
00824
gfConIme = (
DWORD)
NtUserGetThreadState(UserThreadStateIsConImeThread);
00825
if (
gfConIme) {
00826 RIPMSG0(RIP_VERBOSE,
"ImmSetContextHandler: This thread is console IME.\n");
00827 UserAssert(pimeui);
00828
00829 pimeui->
fCtrlShowStatus =
FALSE;
00830 }
00831 }
00832
00833
if (
gfConIme) {
00834
00835
00836
00837
PWND pwndOwner;
00838
00839 UserAssert(pimeui->
spwnd);
00840 pwndOwner =
REBASEPWND(pimeui->
spwnd, spwndOwner);
00841
if (pwndOwner !=
NULL) {
00842
00843
00844
00845
SETIMC(pimeui, pwndOwner->
hImc);
00846
00847
00848
00849
if (
GETUI(pimeui) !=
NULL)
00850
SetWindowLongPtr(
GETUI(pimeui), IMMGWLP_IMC, (LONG_PTR)pwndOwner->
hImc);
00851 }
00852
00853 hwndFocus =
NtUserQueryWindow(
HW(pimeui->
spwnd), WindowFocusWindow);
00854 hFocusImc = pwndOwner->
hImc;
00855 RIPMSG2(RIP_VERBOSE,
"CONSOLE IME: hwndFocus = %x, hFocusImc = %x", hwndFocus, hFocusImc);
00856
00857
return SendMessageToUI(pimeui, message, wParam, lParam,
FALSE);
00858 }
00859
else {
00860 hwndFocus =
NtUserQueryWindow(
HW(pimeui->
spwnd), WindowFocusWindow);
00861 hFocusImc =
fpImmGetContext(hwndFocus);
00862 }
00863
00864
00865
00866
00867
if (hFocusImc !=
NULL_HIMC &&
00868 !
ImeIsUsableContext(
HW(pimeui->
spwnd), hFocusImc)) {
00869
SETIMC(pimeui,
NULL_HIMC);
00870
return 0
L;
00871 }
00872
00873
SETIMC(pimeui, hFocusImc);
00874
00875
00876
00877
00878
if (
GETUI(pimeui) !=
NULL)
00879
SetWindowLongPtr(
GETUI(pimeui), IMMGWLP_IMC, (LONG_PTR)hFocusImc);
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
if (hFocusImc !=
NULL_HIMC) {
00890 PINPUTCONTEXT pInputContext;
00891
00892
00893
00894
00895
if ((pInputContext =
fpImmLockIMC(hFocusImc)) !=
NULL) {
00896
00897
if (hwndFocus != pInputContext->hWnd) {
00898
00899
00900
00901
00902
return 0
L;
00903 }
00904 }
00905
else
00906
return 0
L;
00907
00908
if ((pInputContext->fdw31Compat & F31COMPAT_ECSETCFS) &&
00909 hwndPrevIMC != hwndFocus) {
00910 COMPOSITIONFORM cf;
00911
00912
00913
00914
00915 RtlZeroMemory(&cf,
sizeof(cf));
00916
fpImmSetCompositionWindow(hFocusImc, &cf);
00917 pInputContext->fdw31Compat &= ~F31COMPAT_ECSETCFS;
00918 }
00919
00920
fpImmUnlockIMC(hFocusImc);
00921
00922
if (
NtUserSetImeOwnerWindow(
HW(pimeui->
spwnd), hwndFocus))
00923 pimeui->
hwndIMC = hwndFocus;
00924
00925 }
00926
else {
00927
00928
00929
00930 pimeui->
hwndIMC = hwndFocus;
00931
00932
NtUserSetImeOwnerWindow(
HW(pimeui->
spwnd),
NULL);
00933
00934 }
00935 }
00936
00937 lRet =
SendMessageToUI(pimeui, message, wParam, lParam,
FALSE);
00938
00939
if (pimeui->
spwnd ==
NULL) {
00940
00941
00942 RIPMSG0(RIP_WARNING,
"ImmSetContextHandler: pimeui->spwnd is NULL after SendMessageToUI.");
00943
return 0
L;
00944 }
00945
00946
if (pimeui->
fCtrlShowStatus &&
GetIMEShowStatus()) {
00947
PWND pwndFocus, pwndIMC, pwndPrevIMC;
00948 HWND hwndActive;
00949
00950 hwndFocus =
NtUserQueryWindow(
HWq(pimeui->
spwnd), WindowFocusWindow);
00951 pwndFocus =
ValidateHwndNoRip(hwndFocus);
00952
00953
if ((
BOOL)wParam ==
TRUE) {
00954 HWND hwndIme;
00955
00956
00957
00958
00959
00960
00961
00962 UserAssert(pimeui->
spwnd);
00963
if (pwndFocus !=
NULL &&
GETPTI(pimeui->
spwnd) ==
GETPTI(pwndFocus)) {
00964
00965
if (!pimeui->
fShowStatus) {
00966
00967
00968
00969
if (
ValidateHwndNoRip(pimeui->
hwndIMC)) {
00970
SendOpenStatusNotify(pimeui, pimeui->
hwndIMC,
TRUE);
00971 }
00972 }
00973
else if ((pwndIMC =
ValidateHwndNoRip(pimeui->
hwndIMC)) !=
NULL &&
00974 (pwndPrevIMC =
ValidateHwndNoRip(hwndPrevIMC)) !=
NULL &&
00975
GetTopLevelWindow(pwndIMC) !=
GetTopLevelWindow(pwndPrevIMC)) {
00976
00977
00978
00979
SendOpenStatusNotify(pimeui, hwndPrevIMC,
FALSE);
00980
SendOpenStatusNotify(pimeui, pimeui->
hwndIMC,
TRUE);
00981 }
00982 }
00983
00984
00985
00986
00987 hwndIme =
HW(pimeui->
spwnd);
00988
if (hwndIme) {
00989
NtUserCheckImeShowStatusInThread(hwndIme);
00990 }
00991 }
00992
else {
00993
00994
00995
00996
00997
00998
00999
01000 hwndActive =
NtUserQueryWindow(
HW(pimeui->
spwnd), WindowActiveWindow);
01001 UserAssert(pimeui->
spwnd);
01002
if (pwndFocus ==
NULL ||
GETPTI(pimeui->
spwnd) !=
GETPTI(pwndFocus) ||
01003 hwndActive ==
NULL) {
01004
01005
if (
IsWindow(hwndPrevIMC))
01006
SendOpenStatusNotify(pimeui, hwndPrevIMC,
FALSE);
01007
else {
01008 pimeui->
fShowStatus =
FALSE;
01009
SendMessageToUI(pimeui, WM_IME_NOTIFY,
01010 IMN_CLOSESTATUSWINDOW, 0
L,
FALSE);
01011 }
01012 }
01013 }
01014 }
01015
01016
return lRet;
01017 }
01018
01019
01020 LRESULT
ImeNotifyHandler(
01021
PIMEUI pimeui,
01022 UINT message,
01023 WPARAM wParam,
01024 LPARAM lParam)
01025 {
01026 HWND hwndUI;
01027 LRESULT lRet = 0
L;
01028 HIMC hImc;
01029 PINPUTCONTEXT pInputContext;
01030
01031
switch (wParam) {
01032
case IMN_PRIVATE:
01033 hwndUI =
GETUI(pimeui);
01034
if (
IsWindow(hwndUI))
01035 lRet =
SendMessage(hwndUI, message, wParam, lParam);
01036
break;
01037
01038
case IMN_SETCONVERSIONMODE:
01039
case IMN_SETOPENSTATUS:
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050 hImc =
GETIMC(pimeui);
01051
if ((pInputContext =
fpImmLockIMC(hImc)) !=
NULL) {
01052
if (
IsWindow(pimeui->
hwndIMC) ) {
01053
NtUserNotifyIMEStatus( pimeui->
hwndIMC,
01054 (
DWORD)pInputContext->fOpen,
01055 pInputContext->fdwConversion );
01056 }
01057
else if (
gfConIme ==
TRUE) {
01058
01059
01060
01061
if (pimeui->
spwnd) {
01062
PWND pwndOwner =
REBASEPWND(pimeui->
spwnd, spwndOwner);
01063
01064
if (pwndOwner !=
NULL) {
01065
NtUserNotifyIMEStatus(
HWq(pwndOwner),
01066 (
DWORD)pInputContext->fOpen,
01067 pInputContext->fdwConversion);
01068 }
01069 }
01070 }
01071
fpImmUnlockIMC(hImc);
01072 }
01073
01074
default:
01075 TAGMSG4(DBGTAG_IMM,
"ImeNotifyHandler: sending to pimeui->ui=%p, msg=%x, wParam=%x, lParam=%x\n",
GETUI(pimeui), message, wParam, lParam);
01076 lRet =
SendMessageToUI(pimeui, message, wParam, lParam,
FALSE);
01077 }
01078
01079
return lRet;
01080 }
01081
01082
01083 HWND
CreateIMEUI(
01084
PIMEUI pimeui,
01085 HKL hKL)
01086 {
01087
PWND pwndIme = pimeui->
spwnd;
01088 HWND hwndUI;
01089
IMEINFOEX iiex;
01090
PIMEDPI pimedpi;
01091 WNDCLASS wndcls;
01092
01093
if (!
fpImmGetImeInfoEx(&iiex,
ImeInfoExKeyboardLayout, &hKL))
01094
return (HWND)
NULL;
01095
01096
if ((pimedpi =
fpImmLockImeDpi(hKL)) ==
NULL) {
01097 RIPMSG1(RIP_WARNING,
"CreateIMEUI: ImmLockImeDpi(%lx) failed.", hKL);
01098
return (HWND)
NULL;
01099 }
01100
01101
if (!GetClassInfoW(pimedpi->
hInst, iiex.
wszUIClass, &wndcls)) {
01102 RIPMSG1(RIP_WARNING,
"CreateIMEUI: GetClassInfoW(%ws) failed\n", iiex.
wszUIClass);
01103
fpImmUnlockImeDpi(pimedpi);
01104
return (HWND)
NULL;
01105 }
01106
01107
01108
if ((wndcls.style & CS_IME) == 0) {
01109 RIPMSG1(RIP_ERROR,
"CreateIMEUI: the Window Class (%S) does not have CS_IME flag on !!!\n",
01110 wndcls.lpszClassName);
01111 }
01112
01113
if (iiex.
ImeInfo.fdwProperty & IME_PROP_UNICODE) {
01114
01115
01116
01117 hwndUI = CreateWindowExW(0
L,
01118 iiex.
wszUIClass,
01119 iiex.
wszUIClass,
01120 WS_POPUP|WS_DISABLED,
01121 0, 0, 0, 0,
01122
HWq(pwndIme), 0, wndcls.hInstance,
NULL);
01123 }
01124
else {
01125
01126
01127
01128
01129 LPSTR pszClass;
01130
int i;
01131 i = WCSToMB(iiex.
wszUIClass, -1, &pszClass, -1,
TRUE);
01132
if (i == 0) {
01133 RIPMSG1(RIP_WARNING,
"CreateIMEUI: failed in W->A conversion (%S)", iiex.
wszUIClass);
01134
return (HWND)
NULL;
01135 }
01136 pszClass[i] =
'\0';
01137
01138 hwndUI = CreateWindowExA(0
L,
01139 pszClass,
01140 pszClass,
01141 WS_POPUP|WS_DISABLED,
01142 0, 0, 0, 0,
01143
HWq(pwndIme), 0, wndcls.hInstance,
NULL);
01144
01145
UserLocalFree(pszClass);
01146 }
01147
01148
if (hwndUI)
01149
NtUserSetWindowLongPtr(hwndUI, IMMGWLP_IMC, (LONG_PTR)
GETIMC(pimeui),
FALSE);
01150
01151
fpImmUnlockImeDpi(pimedpi);
01152
01153
return hwndUI;
01154 }
01155
01156
01157 VOID DestroyIMEUI(
01158
PIMEUI pimeui)
01159 {
01160
01161
01162
01163
01164 HWND hwndUI =
GETUI(pimeui);
01165
01166
if (
IsWindow(hwndUI)) {
01167 pimeui->
fDestroy =
TRUE;
01168
01169
01170
01171
01172
NtUserDestroyWindow(hwndUI);
01173 }
01174 pimeui->
fDestroy =
FALSE;
01175
01176
01177
01178
01179
01180 pimeui->
fShowStatus =
FALSE;
01181
01182
SETUI(pimeui,
NULL);
01183
01184
return;
01185 }
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195 LRESULT
SendMessageToUI(
01196
PIMEUI pimeui,
01197 UINT message,
01198 WPARAM wParam,
01199 LPARAM lParam,
01200 BOOL fAnsi)
01201 {
01202
PWND pwndUI;
01203 LRESULT lRet;
01204
01205 TAGMSG1(DBGTAG_IMM,
"Sending to UI msg[%04X]\n", message);
01206
01207 pwndUI =
ValidateHwndNoRip(
GETUI(pimeui));
01208
01209
if (pwndUI ==
NULL || pimeui->
spwnd ==
NULL)
01210
return 0
L;
01211
01212
if (
TestWF(pimeui->
spwnd,
WFINDESTROY) ||
TestWF(pimeui->
spwnd,
WFDESTROYED) ||
01213
TestWF(pwndUI,
WFINDESTROY) ||
TestWF(pwndUI,
WFDESTROYED)) {
01214
return 0
L;
01215 }
01216
01217 InterlockedIncrement(&pimeui->
nCntInIMEProc);
01218
01219 lRet =
SendMessageWorker(pwndUI, message, wParam, lParam, fAnsi);
01220
01221 InterlockedDecrement(&pimeui->
nCntInIMEProc);
01222
01223
return lRet;
01224 }
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234 VOID SendOpenStatusNotify(
01235
PIMEUI pimeui,
01236 HWND hwndApp,
01237 BOOL fOpen)
01238 {
01239 WPARAM wParam = fOpen ? IMN_OPENSTATUSWINDOW : IMN_CLOSESTATUSWINDOW;
01240
01241 pimeui->
fShowStatus = fOpen;
01242
01243
01244
if (
GetClientInfo()->dwExpWinVer >=
VER40) {
01245 TAGMSG2(DBGTAG_IMM,
"SendOpenStatusNotify: sending to hwnd=%lx, wParam=%d\n", hwndApp, wParam);
01246
SendMessage(hwndApp, WM_IME_NOTIFY, wParam, 0
L);
01247 }
01248
else {
01249 TAGMSG2(DBGTAG_IMM,
"SendOpenStatusNotify:sending to imeui->UI=%p, wParam=%d\n",
GETUI(pimeui), wParam);
01250
SendMessageToUI(pimeui, WM_IME_NOTIFY, wParam, 0
L,
FALSE);
01251 }
01252
01253
return;
01254 }
01255
01256
01257 VOID ImeSetImc(
01258
PIMEUI pimeui,
01259 HIMC hImc)
01260 {
01261 HWND hImeWnd =
HW(pimeui->
spwnd);
01262 HIMC hOldImc =
GETIMC(pimeui);
01263
01264
01265
01266
01267
if (hImc == hOldImc)
01268
return;
01269
01270
01271
01272
01273
if (hOldImc !=
NULL_HIMC)
01274
ImeMarkUsedContext(
NULL, hOldImc);
01275
01276
01277
01278
01279 pimeui->
hIMC = hImc;
01280
01281
01282
01283
01284
if (hImc !=
NULL_HIMC)
01285
ImeMarkUsedContext(hImeWnd, hImc);
01286 }
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296 VOID FocusSetIMCContext(
01297 HWND hWnd,
01298 BOOL fActivate)
01299 {
01300 HIMC hImc;
01301
01302
if (
IsWindow(
hWnd)) {
01303 hImc =
fpImmGetContext(
hWnd);
01304
fpImmSetActiveContext(
hWnd, hImc, fActivate);
01305
fpImmReleaseContext(
hWnd, hImc);
01306 }
01307
else {
01308
fpImmSetActiveContext(
NULL,
NULL_HIMC, fActivate);
01309 }
01310
01311
return;
01312 }
01313
01314
01315 BOOL ImeBroadCastMsg(
01316
PIMEUI pimeui,
01317 UINT message,
01318 WPARAM wParam,
01319 LPARAM lParam)
01320 {
01321 UNREFERENCED_PARAMETER(pimeui);
01322 UNREFERENCED_PARAMETER(message);
01323 UNREFERENCED_PARAMETER(wParam);
01324 UNREFERENCED_PARAMETER(lParam);
01325
01326
return TRUE;
01327 }
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339 VOID ImeMarkUsedContext(
01340 HWND hImeWnd,
01341 HIMC hImc)
01342 {
01343
PIMC pImc;
01344
01345 pImc =
HMValidateHandle((HANDLE)hImc,
TYPE_INPUTCONTEXT);
01346
if (pImc ==
NULL) {
01347 RIPMSG1(RIP_WARNING,
"ImeMarkUsedContext: Invalid hImc (=%lx).", hImc);
01348
return;
01349 }
01350
01351 UserAssert(
ValidateHwndNoRip(pImc->
hImeWnd) ==
NULL || hImeWnd ==
NULL );
01352
01353
01354
01355
01356
if (pImc->
hImeWnd == hImeWnd)
01357
return;
01358
01359
NtUserUpdateInputContext(hImc,
UpdateInUseImeWindow, (ULONG_PTR)hImeWnd);
01360
01361
return;
01362 }
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379 BOOL ImeIsUsableContext(
01380 HWND hImeWnd,
01381 HIMC hImc)
01382 {
01383
PIMC pImc;
01384
01385 UserAssert(hImeWnd !=
NULL);
01386
01387 pImc =
HMValidateHandle((HANDLE)hImc,
TYPE_INPUTCONTEXT);
01388
if (pImc ==
NULL) {
01389 RIPMSG1(RIP_WARNING,
"ImeIsUsableContext: Invalid hImc (=%lx).", hImc);
01390
return FALSE;
01391 }
01392
01393
if ( pImc->
hImeWnd ==
NULL ||
01394 pImc->
hImeWnd == hImeWnd ||
01395
ValidateHwndNoRip(pImc->
hImeWnd) ==
NULL )
01396 {
01397
return TRUE;
01398 }
01399
01400
01401
return FALSE;
01402 }
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413 BOOL GetIMEShowStatus(
void)
01414 {
01415
return (
BOOL)
NtUserCallNoParam(SFI__GETIMESHOWSTATUS);
01416 }
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427 BOOL IMEIndicatorGetMenuIDData(PUINT puMenuID, PDWORD pdwData)
01428 {
01429 HANDLE hinstIndic;
01430
01431 hinstIndic = GetModuleHandle(
szIndicDLL);
01432
if (hinstIndic ==
NULL) {
01433
gpfnGetIMEMenuItemData =
NULL;
01434
return FALSE;
01435 }
01436
01437
if (!
gpfnGetIMEMenuItemData) {
01438
gpfnGetIMEMenuItemData = GetProcAddress(hinstIndic, (LPSTR)ORD_GETIMEMENUITEMDATA);
01439 }
01440
if (!
gpfnGetIMEMenuItemData)
01441
return FALSE;
01442
01443 (*(FPGETIMEMENUITEMDATA)
gpfnGetIMEMenuItemData)(puMenuID, pdwData);
01444
return TRUE;
01445 }
01446
01447
01448 BOOL SyncSoftKbdState(
01449 HIMC hImc,
01450 LPARAM lParam)
01451 {
01452
DWORD fdwConversion, fdwSentence, fdwNewConversion;
01453
01454
fpImmGetConversionStatus(hImc, &fdwConversion, &fdwSentence);
01455
01456
if (lParam) {
01457 fdwNewConversion = fdwConversion | IME_CMODE_SOFTKBD;
01458 }
else {
01459 fdwNewConversion = fdwConversion & ~IME_CMODE_SOFTKBD;
01460 }
01461
01462
if (fdwNewConversion != fdwConversion) {
01463
fpImmSetConversionStatus(hImc, fdwNewConversion, fdwSentence);
01464 }
01465
01466
return TRUE;
01467 }
01468
01469
01470
01471
01472
01473
01474
01475
01476 LRESULT
ImeCopyDataHandler(
01477 WPARAM wParam,
01478 LPARAM lParam)
01479 {
01480 HINSTANCE hInstImm;
01481
BOOL (WINAPI* fpImmPenAuxInput)(HWND,
LPVOID);
01482
01483 hInstImm = GetModuleHandleW(
L"IMM32.DLL");
01484
if (hInstImm ==
NULL) {
01485
return FALSE;
01486 }
01487
01488 fpImmPenAuxInput = (
LPVOID)GetProcAddress(hInstImm,
"ImmPenAuxInput");
01489
if (fpImmPenAuxInput ==
NULL) {
01490
return FALSE;
01491 }
01492
01493
return fpImmPenAuxInput((HWND)wParam, (
LPVOID)lParam);
01494 }