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.
501 lines
12 KiB
501 lines
12 KiB
/*++
|
|
|
|
Copyright (c) 2001, Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dimmex.cpp
|
|
|
|
Abstract:
|
|
|
|
This file implements the CActiveIMMAppEx Class.
|
|
|
|
Author:
|
|
|
|
Revision History:
|
|
|
|
Notes:
|
|
|
|
--*/
|
|
|
|
#include "private.h"
|
|
#include "msctfp.h"
|
|
#include "dimmex.h"
|
|
#include "list.h"
|
|
#include "atom.h"
|
|
#include "globals.h"
|
|
#include "tls.h"
|
|
#include "apcompat.h"
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CGuidMapList
|
|
// Allocated by Global data object !!
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CGuidMapList *g_pGuidMapList = NULL;
|
|
|
|
BOOL InitFilterList()
|
|
{
|
|
BOOL bRet;
|
|
EnterCriticalSection(g_cs);
|
|
|
|
if (!g_pGuidMapList)
|
|
g_pGuidMapList = new CGuidMapList;
|
|
|
|
bRet = g_pGuidMapList ? TRUE : FALSE;
|
|
LeaveCriticalSection(g_cs);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void UninitFilterList()
|
|
{
|
|
//
|
|
// this function is called in DllMain(). Don't need to be protected by
|
|
// g_cs.
|
|
//
|
|
// EnterCriticalSection(g_cs);
|
|
|
|
if (g_pGuidMapList)
|
|
delete g_pGuidMapList;
|
|
|
|
g_pGuidMapList = NULL;
|
|
|
|
// LeaveCriticalSection(g_cs);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// CAtomObject
|
|
// Allocated by Global data object !!
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
CAtomObject *g_pAimmAtomObject = NULL;
|
|
|
|
BOOL InitAimmAtom()
|
|
{
|
|
BOOL bRet;
|
|
EnterCriticalSection(g_cs);
|
|
|
|
if (! FindAtom(TF_ENABLE_PROCESS_ATOM)) {
|
|
//
|
|
// This process is not WinWord XP nor Cicero aware application
|
|
//
|
|
bRet = FALSE;
|
|
}
|
|
else {
|
|
if (!g_pAimmAtomObject) {
|
|
g_pAimmAtomObject = new CAtomObject();
|
|
if (g_pAimmAtomObject) {
|
|
if (g_pAimmAtomObject->_InitAtom(AIMM12_PROCESS_ATOM) != S_OK) {
|
|
delete g_pAimmAtomObject;
|
|
g_pAimmAtomObject = NULL;
|
|
}
|
|
}
|
|
}
|
|
bRet = g_pAimmAtomObject ? TRUE : FALSE;
|
|
}
|
|
|
|
LeaveCriticalSection(g_cs);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
void UninitAimmAtom()
|
|
{
|
|
//
|
|
// this function is called in DllMain(). Don't need to be protected by
|
|
// g_cs.
|
|
//
|
|
// EnterCriticalSection(g_cs);
|
|
|
|
if (g_pAimmAtomObject)
|
|
delete g_pAimmAtomObject;
|
|
|
|
g_pAimmAtomObject = NULL;
|
|
|
|
// LeaveCriticalSection(g_cs);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Activate
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
STDAPI CComActiveIMMApp::Activate(BOOL fRestoreLayout)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TLS* ptls = TLS::GetTLS();
|
|
if (ptls == NULL)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
if (! InitAimmAtom()) {
|
|
if (! FindAtom(AIMM12_PROCESS_ATOM))
|
|
AddAtom(AIMM12_PROCESS_ATOM);
|
|
}
|
|
else {
|
|
g_pAimmAtomObject->_Activate(); // Activate AIMM12 atom
|
|
}
|
|
|
|
int cnt = ptls->IncrementAIMMRefCnt();
|
|
|
|
#ifndef KACF_DISABLECICERO
|
|
#define KACF_DISABLECICERO 0x00000100 // If set. Cicero support for the current process
|
|
// is disabled.
|
|
#endif
|
|
|
|
if (! IsOldAImm() && ! IsCUAS_ON() && ! APPCOMPATFLAG(KACF_DISABLECICERO) && cnt == 1)
|
|
{
|
|
hr = imm32prev::CtfAImmActivate(&m_hModCtfIme);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Deactivate
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CComActiveIMMApp::Deactivate()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
TLS* ptls = TLS::GetTLS();
|
|
if (ptls == NULL)
|
|
{
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
if (InitAimmAtom()) {
|
|
g_pAimmAtomObject->_Deactivate(); // Deactivate AIMM12 atom
|
|
}
|
|
|
|
int cnt = ptls->DecrementAIMMRefCnt();
|
|
|
|
if (! IsOldAImm() && ! IsCUAS_ON() && ! APPCOMPATFLAG(KACF_DISABLECICERO) && cnt == 0)
|
|
{
|
|
hr = imm32prev::CtfAImmDeactivate(m_hModCtfIme);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// FilterClientWindows
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CComActiveIMMApp::FilterClientWindows(ATOM *aaWindowClasses, UINT uSize)
|
|
{
|
|
return FilterClientWindowsGUIDMap(aaWindowClasses, uSize, NULL);
|
|
}
|
|
|
|
STDAPI CComActiveIMMApp::FilterClientWindowsGUIDMap(ATOM *aaWindowClasses, UINT uSize, BOOL *aaGuidMap)
|
|
{
|
|
if (!InitFilterList())
|
|
return E_OUTOFMEMORY;
|
|
|
|
return g_pGuidMapList->_Update(aaWindowClasses, uSize, aaGuidMap);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// FilterClientWindowsEx
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CComActiveIMMApp::FilterClientWindowsEx(HWND hWnd, BOOL fGuidMap)
|
|
{
|
|
if (!InitFilterList())
|
|
return E_OUTOFMEMORY;
|
|
|
|
return g_pGuidMapList->_Update(hWnd, fGuidMap);
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// UnfilterClientWindowsEx
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CComActiveIMMApp::UnfilterClientWindowsEx(HWND hWnd)
|
|
{
|
|
if (!InitFilterList())
|
|
return E_OUTOFMEMORY;
|
|
|
|
return g_pGuidMapList->_Remove(hWnd);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetGuidAtom
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CComActiveIMMApp::GetGuidAtom(HIMC hImc, BYTE bAttr, TfGuidAtom *pGuidAtom)
|
|
{
|
|
return imm32prev::CtfImmGetGuidAtom(hImc, bAttr, pGuidAtom);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetCodePageA
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CComActiveIMMApp::GetCodePageA(HKL hKL, UINT *puCodePage)
|
|
{
|
|
if (puCodePage == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
TraceMsg(TF_FUNC, "CComActiveIMMApp::GetCodePageA");
|
|
|
|
*puCodePage = imm32prev::GetKeyboardLayoutCP(hKL);
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetLangId
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CComActiveIMMApp::GetLangId(HKL hKL, LANGID *plid)
|
|
{
|
|
if (plid == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
TraceMsg(TF_FUNC, "CComActiveIMMApp::GetLangId");
|
|
|
|
*plid = LOWORD(HandleToUlong(hKL));
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// QueryService
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CComActiveIMMApp::QueryService(
|
|
REFGUID guidService,
|
|
REFIID riid,
|
|
void **ppv
|
|
)
|
|
{
|
|
ITfThreadMgr *ptim = NULL;
|
|
ITfDocumentMgr *pdim = NULL;
|
|
ITfContext *pic = NULL;
|
|
HRESULT hr = E_NOINTERFACE;
|
|
|
|
if (ppv == NULL) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
*ppv = NULL;
|
|
|
|
if (!IsEqualGUID(guidService, GUID_SERVICE_TF))
|
|
return E_INVALIDARG;
|
|
|
|
if (FAILED(TF_CreateThreadMgr(&ptim)))
|
|
return E_FAIL;
|
|
|
|
if (!ptim)
|
|
return E_FAIL;
|
|
|
|
if (IsEqualIID(riid, IID_ITfThreadMgr)) {
|
|
*ppv = SAFECAST(ptim, ITfThreadMgr*);
|
|
ptim->AddRef();
|
|
hr = S_OK;
|
|
}
|
|
else {
|
|
|
|
if (FAILED(ptim->GetFocus(&pdim)))
|
|
pdim = NULL;
|
|
|
|
if (IsEqualIID(riid, IID_ITfDocumentMgr)) {
|
|
if (pdim) {
|
|
*ppv = SAFECAST(pdim, ITfDocumentMgr*);
|
|
pdim->AddRef();
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
else if (IsEqualIID(riid, IID_ITfContext)) {
|
|
if (pdim) {
|
|
if (SUCCEEDED(pdim->GetTop(&pic)) && pic) {
|
|
*ppv = SAFECAST(pic, ITfContext*);
|
|
pic->AddRef();
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ptim)
|
|
ptim->Release();
|
|
|
|
if (pdim)
|
|
pdim->Release();
|
|
|
|
if (pic)
|
|
pic->Release();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// SetThreadCompartmentValue
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CComActiveIMMApp::SetThreadCompartmentValue(
|
|
REFGUID rguid,
|
|
VARIANT *pvar
|
|
)
|
|
{
|
|
if (pvar == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
ITfThreadMgr *ptim = NULL;
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (FAILED(TF_CreateThreadMgr(&ptim)))
|
|
return hr;
|
|
|
|
if (ptim)
|
|
{
|
|
ITfCompartment *pComp;
|
|
if (SUCCEEDED(GetCompartment((IUnknown *)ptim, rguid, &pComp)))
|
|
{
|
|
//
|
|
// Hack to get App Client Id.
|
|
//
|
|
TfClientId tid;
|
|
ptim->Activate(&tid);
|
|
ptim->Deactivate();
|
|
|
|
hr = pComp->SetValue(tid, pvar);
|
|
pComp->Release();
|
|
}
|
|
ptim->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// GetThreadCompartmentValue
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CComActiveIMMApp::GetThreadCompartmentValue(
|
|
REFGUID rguid,
|
|
VARIANT *pvar
|
|
)
|
|
{
|
|
if (pvar == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
HRESULT hr = E_FAIL;
|
|
ITfThreadMgr *ptim = NULL;
|
|
|
|
if (FAILED(TF_CreateThreadMgr(&ptim)))
|
|
return hr;
|
|
|
|
QuickVariantInit(pvar);
|
|
|
|
if (ptim)
|
|
{
|
|
ITfCompartment *pComp;
|
|
if (SUCCEEDED(GetCompartment((IUnknown *)ptim, rguid, &pComp)))
|
|
{
|
|
hr = pComp->GetValue(pvar);
|
|
pComp->Release();
|
|
}
|
|
ptim->Release();
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// OnDefWindowProc
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
STDAPI CComActiveIMMApp::OnDefWindowProc(
|
|
HWND hWnd,
|
|
UINT Msg,
|
|
WPARAM wParam,
|
|
LPARAM lParam,
|
|
LRESULT *plResult
|
|
)
|
|
{
|
|
*plResult = 0;
|
|
|
|
BOOL fUnicode = IsWindowUnicode(hWnd);
|
|
HRESULT hr = S_FALSE; // returns S_FALSE, DefWindowProc should be called.
|
|
|
|
//
|
|
// RE4.0 won't call DefWindowProc even returns S_FALSE.
|
|
// This code recover some IME message as same old AIMM code (dimm\aime_wnd.cpp)
|
|
//
|
|
switch (Msg)
|
|
{
|
|
case WM_IME_KEYDOWN:
|
|
case WM_IME_KEYUP:
|
|
case WM_IME_CHAR:
|
|
case WM_IME_COMPOSITION:
|
|
case WM_IME_STARTCOMPOSITION:
|
|
case WM_IME_ENDCOMPOSITION:
|
|
case WM_IME_NOTIFY:
|
|
case WM_IME_SETCONTEXT:
|
|
if (fUnicode)
|
|
{
|
|
*plResult = ::DefWindowProcW(hWnd, Msg, wParam, lParam);
|
|
}
|
|
else
|
|
{
|
|
*plResult = ::DefWindowProcA(hWnd, Msg, wParam, lParam);
|
|
}
|
|
hr = S_OK;
|
|
break;
|
|
|
|
case WM_IME_REQUEST:
|
|
switch (wParam)
|
|
{
|
|
case IMR_QUERYCHARPOSITION:
|
|
if (fUnicode)
|
|
{
|
|
*plResult = ::DefWindowProcW(hWnd, Msg, wParam, lParam);
|
|
}
|
|
else
|
|
{
|
|
*plResult = ::DefWindowProcA(hWnd, Msg, wParam, lParam);
|
|
}
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|