Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

578 lines
14 KiB

/*++
Copyright (c) 1985 - 1999, Microsoft Corporation
Module Name:
uiwndhd.cpp
Abstract:
This file implements the IME UI window handler Class.
Author:
Revision History:
Notes:
--*/
#include "private.h"
#include "cime.h"
#include "template.h"
#include "uiwndhd.h"
#include "editses.h"
#include "imeapp.h"
LPCTSTR IMEUIWndHandlerName = TEXT("IMEUIWindowHandler");
CIMEUIWindowHandler::CIMEUIWindowHandler(
HWND hwnd
)
{
IMTLS *ptls;
m_imeuiextra.hImeUIWnd = hwnd;
if (ptls = IMTLS_GetOrAlloc())
{
ptls->prvUIWndMsg.hWnd = hwnd;
ptls->prvUIWndMsg.uMsgOnLayoutChange = RegisterWindowMessageA( TEXT("PrivateUIWndMsg OnLayoutChange") );
ptls->prvUIWndMsg.uMsgOnClearDocFeedBuffer = RegisterWindowMessageA( TEXT("PrivateUIWndMsg OnClearDocFeedBuffer") );
}
}
LRESULT
CIMEUIWindowHandler::ImeUIWndProcWorker(
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL fUnicode
)
{
LONG lRet = 0L;
switch (uMsg) {
case WM_CREATE:
return UIWndCreateHandler((LPCREATESTRUCT)lParam);
case WM_DESTROY:
/*
* We are destroying the IME UI window,
* destroy any related window that it owns.
*/
UIWndDestroyHandler();
return 0L;
case WM_NCDESTROY:
UIWndFinalDestroyHandler();
return 0L;
case WM_IME_NOTIFY:
return ImeUINotifyHandler(uMsg, wParam, lParam, fUnicode);
case WM_IME_SELECT:
return ImeUISelectHandler(uMsg, wParam, lParam, fUnicode);
default:
if (IsMsImeMessage(uMsg))
return ImeUIMsImeHandler(uMsg, wParam, lParam, fUnicode);
else if (IsPrivateMessage(uMsg))
return ImeUIPrivateHandler(uMsg, wParam, lParam, fUnicode);
else
return fUnicode ? DefWindowProcW(m_imeuiextra.hImeUIWnd, uMsg, wParam, lParam)
: DefWindowProcA(m_imeuiextra.hImeUIWnd, uMsg, wParam, lParam);
}
return lRet;
}
LRESULT
CIMEUIWindowHandler::UIWndCreateHandler(
LPCREATESTRUCT lpcs
)
{
return 0L;
}
VOID
CIMEUIWindowHandler::UIWndDestroyHandler(
)
{
}
VOID
CIMEUIWindowHandler::UIWndFinalDestroyHandler(
)
{
SetProp(m_imeuiextra.hImeUIWnd, IMEUIWndHandlerName, NULL);
delete this;
}
LRESULT
CIMEUIWindowHandler::ImeUINotifyHandler(
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL fUnicode
)
{
IMCLock imc((HIMC)GetWindowLongPtr(m_imeuiextra.hImeUIWnd, IMMGWLP_IMC));
if (imc.Invalid())
return 0L;
CAImeContext* _pAImeContext = imc->m_pAImeContext;
if (_pAImeContext == NULL)
return 0L;
ImmIfIME* const _pImmIfIME = _pAImeContext->GetImmIfIME();
if (_pImmIfIME == NULL)
return 0L;
switch (wParam) {
case IMN_SETOPENSTATUS:
//
// we can track this in SetOpenStatus().
// Don't have to sync when IMM32 is called.
//
// _pImmIfIME->OnSetOpenStatus(imc);
break;
case IMN_SETSTATUSWINDOWPOS:
case IMN_OPENSTATUSWINDOW:
case IMN_CLOSESTATUSWINDOW:
break;
case IMN_SETCONVERSIONMODE:
case IMN_SETSENTENCEMODE:
//
// we can track this in SetConversionMode().
// Don't have to sync when IMM32 is called.
//
// _pImmIfIME->OnSetConversionSentenceMode(imc);
break;
case IMN_SETCANDIDATEPOS:
case IMN_CHANGECANDIDATE:
_pImmIfIME->OnSetCandidatePos(imc);
break;
case IMN_OPENCANDIDATE:
_pAImeContext->m_fOpenCandidateWindow = TRUE;
break;
case IMN_CLOSECANDIDATE:
_pAImeContext->m_fOpenCandidateWindow = FALSE;
{
/*
* A-Synchronize call ImmIfIME::ClearDocFeedBuffer
* because this method had a protected.
*/
IMTLS *ptls;
if (ptls = IMTLS_GetOrAlloc())
{
PostMessage(ptls->prvUIWndMsg.hWnd,
ptls->prvUIWndMsg.uMsgOnClearDocFeedBuffer, (WPARAM)(HIMC)imc, 0);
}
}
break;
case IMN_SETCOMPOSITIONFONT:
case IMN_SETCOMPOSITIONWINDOW:
case IMN_GUIDELINE:
break;
case WM_IME_STARTCOMPOSITION:
_pAImeContext->InquireIMECharPosition(imc, NULL);
break;
case WM_IME_ENDCOMPOSITION:
_pAImeContext->ResetIMECharPosition(imc);
break;
}
return 0L;
}
LRESULT
CIMEUIWindowHandler::ImeUIMsImeHandler(
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL fUnicode
)
{
IMTLS *ptls;
if (uMsg == WM_MSIME_MOUSE) {
return ImeUIMsImeMouseHandler(uMsg, wParam, lParam, fUnicode);
}
else if (uMsg == WM_MSIME_MODEBIAS)
{
return ImeUIMsImeModeBiasHandler(wParam, lParam);
}
else if (uMsg == WM_MSIME_RECONVERTREQUEST)
{
if (wParam == FID_RECONVERT_VERSION)
{
// they're asking for version # so return something
return 1L;
}
ptls = IMTLS_GetOrAlloc();
if (ptls && ptls->pAImm)
{
HIMC himc;
HWND hwnd = (HWND)lParam;
if (S_OK == ptls->pAImm->GetContext(hwnd, &himc))
{
IMCLock imc((HIMC)himc);
if (!imc.Invalid())
{
CAImeContext* _pAImeContext = imc->m_pAImeContext;
if (_pAImeContext == NULL)
return 0L;
_pAImeContext->SetupReconvertString(WM_MSIME_RECONVERT);
_pAImeContext->EndReconvertString();
return 1L;
}
}
}
}
else if (uMsg == WM_MSIME_SERVICE)
{
ptls = IMTLS_GetOrAlloc();
if (ptls != NULL)
{
LANGID langid;
ptls->pAImeProfile->GetLangId(&langid);
if (PRIMARYLANGID(langid) == LANG_KOREAN)
return 0L;
}
return 1L; // Win32 Layer support WM_MSIME_xxxx message.
}
return 0L;
}
LRESULT
CIMEUIWindowHandler::ImeUIMsImeMouseHandler(
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL fUnicode
)
/*++
Method:
WM_MSIME_MOUSE
Routine Description:
Mouse Operation on Composition String
Arguments:
wParam - Mouse operation code.
LOBYTE(LOWORD(wParam))
IMEMOUSE_VERSION
IMEMOUSE_NONE
IMEMOUSE_LDOWN
IMEMOUSE_RDOWN
IMEMOUSE_MDOWN
IMEMOUSE_WUP
IMEMOUSE_WDOWN
HIBYTE(LOWORD(wParam))
Mouse Position
HIWORD(wParam)
Clicked position
lParam - Input Context handle (HIMC).
Return Value:
Returns 1 if IME handled this message.
IMEMOUSERET_NOTHANDLED if IME did not handled this message.
--*/
{
ULONG dwBtnStatus;
// special case: version check
if (LOBYTE(LOWORD(wParam)) == IMEMOUSE_VERSION)
return 1; // we support version 1.0
IMCLock imc((HIMC)lParam);
if (imc.Invalid())
return IMEMOUSERET_NOTHANDLED;
CAImeContext* _pAImeContext = imc->m_pAImeContext;
if (_pAImeContext == NULL)
return IMEMOUSERET_NOTHANDLED;
ULONG uEdge = HIWORD(wParam);
ULONG uQuadrant = HIBYTE(LOWORD(wParam));
ULONG dwBtnStatusIme = LOBYTE(LOWORD(wParam));
//
// need to xlate dwBtnStatus from WM_MSIME_MOUSE flags to WM_MOUSE flags
//
dwBtnStatus = 0;
if (dwBtnStatusIme & IMEMOUSE_LDOWN)
{
dwBtnStatus |= MK_LBUTTON;
}
if (dwBtnStatusIme & IMEMOUSE_MDOWN)
{
dwBtnStatus |= MK_MBUTTON;
}
if (dwBtnStatusIme & IMEMOUSE_RDOWN)
{
dwBtnStatus |= MK_RBUTTON;
}
// mouse wheel needs to be xlated from IMEMOUSE_WUP/IMEMOUSE_WDOWN to WHEEL_DELTA units
if (dwBtnStatusIme & IMEMOUSE_WUP)
{
dwBtnStatus |= (WHEEL_DELTA << 16);
}
else if (dwBtnStatusIme & IMEMOUSE_WDOWN)
{
dwBtnStatus |= (((unsigned long)(-WHEEL_DELTA)) << 16);
}
return _pAImeContext->MsImeMouseHandler(uEdge, uQuadrant, dwBtnStatus, (HIMC)lParam);
}
/*++
Method:
CIMEUIWindowHandler::ImeUIMsImeModeBiasHandler
Routine Description:
Handles WM_MSIME_MODEBIAS messages sent to the ui window.
Arguments:
wParam - [in] operation: get version, get mode, set mode
lParam - [in] for set mode, the new bias
otherwise ignored
Return Value:
If wParam is MODEBIAS_GETVERSION, returns version number of interface.
If wParam is MODEBIAS_SETVALUE, returns non-zero value if succeeded. Returns 0 if fail.
If wParam is MODEBIAS_GETVALUE, returns current bias mode.
--*/
LRESULT CIMEUIWindowHandler::ImeUIMsImeModeBiasHandler(WPARAM wParam, LPARAM lParam)
{
if (wParam == MODEBIAS_GETVERSION)
return 1; // version 1
IMCLock imc((HIMC)GetWindowLongPtr(m_imeuiextra.hImeUIWnd, IMMGWLP_IMC));
if (imc.Invalid())
return 0;
CAImeContext* _pAImeContext = imc->m_pAImeContext;
switch (wParam)
{
case MODEBIAS_GETVALUE:
return _pAImeContext ? _pAImeContext->lModeBias : 0L;
case MODEBIAS_SETVALUE:
// check lParam
if (lParam != MODEBIASMODE_DEFAULT &&
lParam != MODEBIASMODE_FILENAME &&
lParam != MODEBIASMODE_DIGIT)
{
Assert(0); // bogus mode bias!
return 0; // failure
}
// set the new value
if (_pAImeContext)
{
_pAImeContext->lModeBias = lParam;
// let cicero know the mode bias has changed
Interface_Attach<ITfContextOwnerServices> iccb = _pAImeContext->GetInputContextOwnerSink();
iccb->OnAttributeChange(GUID_PROP_MODEBIAS);
}
return 1; // success
}
Assert(0); // should never get here; bogus wParam
return 0;
}
LRESULT
CIMEUIWindowHandler::ImeUIPrivateHandler(
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL fUnicode
)
/*++
Method:
CIMEUIWindowHandler::ImeUIPrivateHandler
Routine Description:
Handles WM_PRIVATE_xxx messages sent to the ui window.
Arguments:
wParam - [in] HIMC : input context handle
lParam - [in] N/A
Return Value:
--*/
{
IMTLS *ptls = IMTLS_GetOrAlloc();
if (ptls == NULL)
return E_FAIL;
if (uMsg == ptls->prvUIWndMsg.uMsgOnLayoutChange) {
IMCLock imc((HIMC)wParam);
if (imc.Invalid())
return E_FAIL;
CAImeContext* _pAImeContext = imc->m_pAImeContext;
if (_pAImeContext == NULL)
return E_FAIL;
Interface_Attach<ITfContextOwnerServices> iccb = _pAImeContext->GetInputContextOwnerSink();
iccb->AddRef();
/*
* Repositioning candidate window
*/
iccb->OnLayoutChange();
iccb->Release();
}
else if (uMsg == ptls->prvUIWndMsg.uMsgOnClearDocFeedBuffer) {
IMCLock imc((HIMC)wParam);
if (imc.Invalid())
return E_FAIL;
CAImeContext* _pAImeContext = imc->m_pAImeContext;
if (_pAImeContext == NULL)
return E_FAIL;
ImmIfIME* const _pImmIfIME = _pAImeContext->GetImmIfIME();
if (_pImmIfIME == NULL)
return E_FAIL;
//
// Clear DocFeed buffer
// Find GUID_PROP_MSIMTF_READONLY property and SetText(NULL).
//
_pImmIfIME->ClearDocFeedBuffer(_pAImeContext->GetInputContext(), imc); // TF_ES_SYNC
}
return S_OK;
}
extern HINSTANCE hIMM; // temporary: do not call IMM32 for now
BOOL WINAPI RawImmEnumInputContext(DWORD idThread, IMCENUMPROC lpfn, LPARAM lParam);
LRESULT
CIMEUIWindowHandler::ImeUISelectHandler(
UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL fUnicode
)
{
if ((! wParam) && (! IsOnNT()) )
{
//
// Unselect Cicero keyboard layout.
//
// We needs to call postponed lock so release all queueing request for edit session here.
// Especially, ESCB_UPDATECOMPOSITIONSTRING should handle before switch to Legacy IME,
// because this edit session possible to rewrite hIMC->hCompStr buffer.
// Some Legacy IME have dependency of size and each offset with hCompStr.
//
// IsOnNT is ImmIfIME::SelectEx()
//
hIMM = GetSystemModuleHandle("imm32.dll");
if (hIMM != NULL) {
RawImmEnumInputContext(0, // Current thread
EnumUnSelectCallback, // enumerate callback function
NULL); // lParam
}
}
return 0L;
}
/* static */
BOOL
CIMEUIWindowHandler::EnumUnSelectCallback(
HIMC hIMC,
LPARAM lParam
)
{
IMCLock imc(hIMC);
if (imc.Invalid())
return TRUE;
CAImeContext* _pAImeContext = imc->m_pAImeContext;
if (_pAImeContext == NULL)
return TRUE;
ImmIfIME* const _pImmIfIME = _pAImeContext->GetImmIfIME();
if (_pImmIfIME == NULL)
return TRUE;
Interface_Attach<ITfThreadMgr_P> tim(_pImmIfIME->GetThreadManagerInternal());
if (tim.Valid())
{
Interface_Attach<ITfContext> ic(_pAImeContext->GetInputContext());
if (ic.Valid())
{
tim->RequestPostponedLock(ic.GetPtr());
}
}
return TRUE;
}
CIMEUIWindowHandler*
GetImeUIWndHandler(
HWND hwnd
)
{
CIMEUIWindowHandler* pimeui = static_cast<CIMEUIWindowHandler*>(GetProp(hwnd, IMEUIWndHandlerName));
if (pimeui == NULL) {
pimeui = new CIMEUIWindowHandler(hwnd);
SetProp(hwnd, IMEUIWndHandlerName, pimeui);
}
return pimeui;
}