📄 imeui.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include <imm.h>
#include <sipapi.h>
#include "uipriv.h"
//#include "imemsg.hpp"
#define IMN_PRIVATE_NONIME_TOGGLE_ON 0x000A
#define IMN_PRIVATE_NONIME_TOGGLE_OFF 0x000B
#define IMN_PRIVATE_SETACTIVECONTEXT 0x000C
extern LRESULT PASCAL SetStatusWindowPos(HWND hStatusWnd);
extern HWND PASCAL GetStatusWnd(HWND hUIWnd);
/**********************************************************************/
/* OnUICreate() */
/**********************************************************************/
static __inline
LRESULT OnUICreate(HWND hUIWnd, LPCREATESTRUCT lpCS)
{
LPUIPRIV lpUIPriv;
lpUIPriv = (LPUIPRIV)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(UIPRIV));
if (!lpUIPriv) { return -1L; }
memset(lpUIPriv, 0, sizeof(UIPRIV));
#ifdef WPC
// This is because Rapier. Rapier SIP just send the notify messages to
// top level and visible window while the SIP is showed or hided.
// So ImeUI has to set to TOPMOST and VISIBLE.
// Move to ChangeImeUIStyle(). We can't change the IME UI window style
// at this meanwhile. GWE will active IME UI window if UI's style is
// visible and it's real visible.
// This is in winceos\coreos\winmgr\wmbase\wmbase.cpp - line 705.
// We have to set UI's style late.
// *** Important ***
// Set IME UI as visible caused a lot of problems. We have to turn it off.
// So let composition window handle WM_SETTINGCHANGE.
#endif // WPC
lpUIPriv->dwUIMoveOffset = WINDOW_NOT_DRAG;
lpUIPriv->bOpenStatus = TRUE;
SetWindowLong(hUIWnd, IMMGWL_PRIVATE, (LONG)lpUIPriv);
lpUIPriv->hInst = lpCS->hInstance;
return 0L;
}
/**********************************************************************/
/* OnUIDestroy() */
/**********************************************************************/
static __inline
LRESULT OnUIDestroy(HWND hUIWnd)
{
LPUIPRIV lpUIPriv;
lpUIPriv = (LPUIPRIV)GetWindowLong(hUIWnd, IMMGWL_PRIVATE);
if (lpUIPriv->hStatusWnd) {
DestroyWindow(lpUIPriv->hStatusWnd);
lpUIPriv->hStatusWnd = NULL;
}
// composition window need to be destroyed
if (lpUIPriv->hCompWnd) {
DestroyWindow(lpUIPriv->hCompWnd);
lpUIPriv->hCompWnd = NULL;
}
// candidate window need to be destroyed
if (lpUIPriv->hCandWnd) {
DestroyWindow(lpUIPriv->hCandWnd);
lpUIPriv->hCandWnd = NULL;
}
HeapFree(GetProcessHeap(), 0, (LPVOID)lpUIPriv);
SetWindowLong(hUIWnd, IMMGWL_PRIVATE, (LONG)0);
return 0L;
}
/**********************************************************************/
/* ShowUI() : show the sub windows */
/**********************************************************************/
void ShowUI(HWND hUIWnd, int nShowCmd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPUIPRIV lpUIPriv;
if (nShowCmd == SW_HIDE) {
} else if ( !(hIMC = (HIMC)GetWindowLong(hUIWnd, IMMGWL_IMC)) ) {
nShowCmd = SW_HIDE;
} else if (!(lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC))) {
nShowCmd = SW_HIDE;
} else {
}
if (nShowCmd == SW_HIDE) {
if (!g_sImeUIG.bNoStatus)
ShowStatus(hUIWnd, nShowCmd);
ShowComp(hUIWnd, nShowCmd);
ShowCand(hUIWnd, nShowCmd);
return;
}
lpUIPriv = (LPUIPRIV)GetWindowLong(hUIWnd, IMMGWL_PRIVATE);
if (lpUIPriv->bOpenStatus && nShowCmd == SW_HIDE)
return;
if (!lpUIPriv->bOpenStatus && nShowCmd != SW_HIDE)
return;
if (lpUIPriv->hStatusWnd && !g_sImeUIG.bNoStatus)
{
if (IsWindowVisible(lpUIPriv->hStatusWnd))
{
// some time the WM_ERASEBKGND is eaten by the app
InvalidateRect(lpUIPriv->hStatusWnd, NULL, TRUE);
}
SendMessage(lpUIPriv->hStatusWnd, WM_IME_NOTIFY, IMN_OPENSTATUSWINDOW, 0);
if (!IsWindowVisible(lpUIPriv->hStatusWnd))
{
ShowStatus(hUIWnd, SW_SHOWNOACTIVATE);
}
}
if ((lpUIPriv->fdwSetContext & ISC_SHOWUICOMPOSITIONWINDOW) &&
(lpUIPriv->fdwUIFlags & UI_COMP_ALREADY_START)) {
if (lpUIPriv->hCompWnd) {
if (IsWindowVisible(lpUIPriv->hCompWnd)) {
// some time the WM_ERASEBKGND is eaten by the app
InvalidateRect(lpUIPriv->hCompWnd, NULL, TRUE);
}
SendMessage(lpUIPriv->hCompWnd, WM_IME_NOTIFY, IMN_SETCOMPOSITIONWINDOW, 0);
if (!IsWindowVisible(lpUIPriv->hCompWnd)) {
ShowComp(hUIWnd, SW_SHOWNOACTIVATE);
}
} else {
lpUIPriv->fdwSetContext |= ISC_SHOWUICOMPOSITIONWINDOW;
StartComp(hUIWnd);
}
} else if (!IsWindowVisible(lpUIPriv->hCompWnd)) {
} else {
ShowComp(hUIWnd, SW_HIDE);
}
if ((lpUIPriv->fdwSetContext & ISC_SHOWUICANDIDATEWINDOW) &&
(lpUIPriv->fdwUIFlags & UI_CAND_ALREADY_OPEN)) {
if (lpUIPriv->hCandWnd) {
if (IsWindowVisible(lpUIPriv->hCandWnd)) {
// some time the WM_ERASEBKGND is eaten by the app
InvalidateRect(lpUIPriv->hCandWnd, NULL, TRUE);
}
SendMessage(lpUIPriv->hCandWnd, WM_IME_NOTIFY, IMN_SETCANDIDATEPOS, 0x0001);
if (!IsWindowVisible(lpUIPriv->hCandWnd)) {
ShowCand(hUIWnd, SW_SHOWNOACTIVATE);
}
} else {
lpUIPriv->fdwSetContext |= ISC_SHOWUICANDIDATEWINDOW;
OpenCand(hUIWnd);
}
} else if (!IsWindowVisible(lpUIPriv->hCandWnd)) {
} else {
ShowCand(hUIWnd, SW_HIDE);
}
// we switch to this hIMC
lpUIPriv->hCacheIMC = hIMC;
if ( lpIMC ) {
ImmUnlockIMC(hIMC);
}
return;
}
/**********************************************************************/
/* ShowGuideLine */
/**********************************************************************/
void ShowGuideLine(HWND hUIWnd)
{
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
LPGUIDELINE lpGuideLine;
hIMC = (HIMC)GetWindowLong(hUIWnd, IMMGWL_IMC);
if (!hIMC) { return; }
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC) { return; }
lpGuideLine = (LPGUIDELINE)ImmLockIMCC(lpIMC->hGuideLine);
if (!lpGuideLine) {
} else if (lpGuideLine->dwLevel == GL_LEVEL_ERROR) {
MessageBeep((UINT)-1);
MessageBeep((UINT)-1);
} else if (lpGuideLine->dwLevel == GL_LEVEL_WARNING) {
MessageBeep((UINT)-1);
} else {
}
ImmUnlockIMCC(lpIMC->hGuideLine);
ImmUnlockIMC(hIMC);
return;
}
/**********************************************************************/
/* OnUINotify() */
/**********************************************************************/
static __inline
LRESULT OnUINotify(HWND hUIWnd, WPARAM wParam, LPARAM lParam)
{
LPUIPRIV lpUIPriv;
lpUIPriv = (LPUIPRIV)GetWindowLong(hUIWnd, IMMGWL_PRIVATE);
if (!lpUIPriv) {
return -1L;
}
switch (wParam) {
case IMN_OPENSTATUSWINDOW:
if (!g_sImeUIG.bNoStatus)
OpenStatus(hUIWnd);
break;
case IMN_CLOSESTATUSWINDOW:
break;
case IMN_SETSTATUSWINDOWPOS:
if (!g_sImeUIG.bNoStatus)
SetStatusWindowPos(lpUIPriv->hStatusWnd);
break;
case IMN_OPENCANDIDATE:
OpenCand(hUIWnd);
break;
case IMN_CHANGECANDIDATE:
ChangeCand(hUIWnd);
break;
case IMN_CLOSECANDIDATE:
CloseCand(hUIWnd);
break;
case IMN_SETSENTENCEMODE:
break;
case IMN_SETOPENSTATUS:
if (!g_sImeUIG.bNoStatus) {
HIMC hIMC;
LPINPUTCONTEXT lpIMC;
hIMC = (HIMC)GetWindowLong(hUIWnd, IMMGWL_IMC);
if (!hIMC)
break;
lpIMC = (LPINPUTCONTEXT)ImmLockIMC(hIMC);
if (!lpIMC)
break;
if (ImmGetOpenStatus(hIMC)) {
lpUIPriv->bOpenStatus = TRUE;
ShowUI(hUIWnd, SW_SHOWNOACTIVATE);
}
else {
lpUIPriv->bOpenStatus = FALSE;
ShowUI(hUIWnd, SW_HIDE);
}
ImmUnlockIMC(hIMC);
InvalidateRect(lpUIPriv->hStatusWnd, NULL, NULL);
}
break;
case IMN_SETCONVERSIONMODE:
if (!g_sImeUIG.bNoStatus) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -