First commit.

This commit is contained in:
fanlumaster committed 2023-10-12 23:53:17 +08:00
commit 7b83802bb2
103 files changed
+19016

No files matched your search

+6
View File
@@ -0,0 +1,6 @@
---
BasedOnStyle: Microsoft
IndentWidth: 4
# 不要给头文件排序
SortIncludes: false
+2
View File
@@ -0,0 +1,2 @@
CompileFlags:
Add: [-Wno-microsoft-goto, -Wno-unused-value] # 忽略某些警告
+1
View File
@@ -0,0 +1 @@
build/
+118
View File
@@ -0,0 +1,118 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
#include "SampleIME.h"
#include "CompositionProcessorEngine.h"
BOOL CSampleIME::VerifySampleIMECLSID(_In_ REFCLSID clsid)
{
if (IsEqualCLSID(clsid, Global::SampleIMECLSID))
{
return TRUE;
}
return FALSE;
}
//+---------------------------------------------------------------------------
//
// ITfActiveLanguageProfileNotifySink::OnActivated
//
// Sink called by the framework when changes activate language profile.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnActivated(_In_ REFCLSID clsid, _In_ REFGUID guidProfile, _In_ BOOL isActivated)
{
guidProfile;
if (FALSE == VerifySampleIMECLSID(clsid))
{
return S_OK;
}
if (isActivated)
{
_AddTextProcessorEngine();
}
if (nullptr == _pCompositionProcessorEngine)
{
return S_OK;
}
if (isActivated)
{
_pCompositionProcessorEngine->ShowAllLanguageBarIcons();
_pCompositionProcessorEngine->ConversionModeCompartmentUpdated(_pThreadMgr);
}
else
{
_DeleteCandidateList(FALSE, nullptr);
_pCompositionProcessorEngine->HideAllLanguageBarIcons();
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _InitActiveLanguageProfileNotifySink
//
// Advise a active language profile notify sink.
//----------------------------------------------------------------------------
BOOL CSampleIME::_InitActiveLanguageProfileNotifySink()
{
ITfSource *pSource = nullptr;
BOOL ret = FALSE;
if (_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) != S_OK)
{
return ret;
}
if (pSource->AdviseSink(IID_ITfActiveLanguageProfileNotifySink, (ITfActiveLanguageProfileNotifySink *)this,
&_activeLanguageProfileNotifySinkCookie) != S_OK)
{
_activeLanguageProfileNotifySinkCookie = TF_INVALID_COOKIE;
goto Exit;
}
ret = TRUE;
Exit:
pSource->Release();
return ret;
}
//+---------------------------------------------------------------------------
//
// _UninitActiveLanguageProfileNotifySink
//
// Unadvise a active language profile notify sink. Assumes we have advised one already.
//----------------------------------------------------------------------------
void CSampleIME::_UninitActiveLanguageProfileNotifySink()
{
ITfSource *pSource = nullptr;
if (_activeLanguageProfileNotifySinkCookie == TF_INVALID_COOKIE)
{
return; // never Advised
}
if (_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource) == S_OK)
{
pSource->UnadviseSink(_activeLanguageProfileNotifySinkCookie);
pSource->Release();
}
_activeLanguageProfileNotifySinkCookie = TF_INVALID_COOKIE;
}
+118
View File
@@ -0,0 +1,118 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "BaseDictionaryEngine.h"
#include "Globals.h"
//+---------------------------------------------------------------------------
// ctor
//----------------------------------------------------------------------------
CBaseDictionaryEngine::CBaseDictionaryEngine(LCID locale, _In_ CFile *pDictionaryFile)
{
_locale = locale;
_pDictionaryFile = pDictionaryFile;
}
//+---------------------------------------------------------------------------
// dtor
//----------------------------------------------------------------------------
CBaseDictionaryEngine::~CBaseDictionaryEngine()
{
}
//+---------------------------------------------------------------------------
// SortListItemByFindKeyCode
//----------------------------------------------------------------------------
VOID CBaseDictionaryEngine::SortListItemByFindKeyCode(_Inout_ CSampleImeArray<CCandidateListItem> *pItemList)
{
MergeSortByFindKeyCode(pItemList, 0, pItemList->Count() - 1);
}
//+---------------------------------------------------------------------------
// MergeSortByFindKeyCode
//
// Mergesort the array of element in CCandidateListItem::_FindKeyCode
//
//----------------------------------------------------------------------------
VOID CBaseDictionaryEngine::MergeSortByFindKeyCode(_Inout_ CSampleImeArray<CCandidateListItem> *pItemList, int leftRange, int rightRange)
{
int candidateCount = CalculateCandidateCount(leftRange, rightRange);
if (candidateCount > 2)
{
int mid = leftRange + (candidateCount / 2);
MergeSortByFindKeyCode(pItemList, leftRange, mid);
MergeSortByFindKeyCode(pItemList, mid, rightRange);
CSampleImeArray<CCandidateListItem> ListItemTemp;
int leftRangeTemp = 0;
int midTemp = 0;
for (leftRangeTemp = leftRange, midTemp = mid; leftRangeTemp != mid || midTemp != rightRange;)
{
CStringRange* psrgLeftTemp = nullptr;
CStringRange* psrgMidTemp = nullptr;
psrgLeftTemp = &pItemList->GetAt(leftRangeTemp)->_FindKeyCode;
psrgMidTemp = &pItemList->GetAt(midTemp)->_FindKeyCode;
CCandidateListItem* pLI = nullptr;
pLI = ListItemTemp.Append();
if (pLI)
{
if (leftRangeTemp == mid)
{
*pLI = *pItemList->GetAt(midTemp++);
}
else if (midTemp == rightRange || CStringRange::Compare(_locale, psrgLeftTemp, psrgMidTemp) != CSTR_GREATER_THAN)
{
*pLI = *pItemList->GetAt(leftRangeTemp++);
}
else
{
*pLI = *pItemList->GetAt(midTemp++);
}
}
}
leftRangeTemp = leftRange;
for (UINT count = 0; count < ListItemTemp.Count(); count++)
{
*pItemList->GetAt(leftRangeTemp++) = *ListItemTemp.GetAt(count);
}
}
else if (candidateCount == 2)
{
CStringRange *psrgLeft = nullptr;
CStringRange *psrgLeftNext = nullptr;
psrgLeft = &pItemList->GetAt(leftRange )->_FindKeyCode;
psrgLeftNext = &pItemList->GetAt(leftRange+1)->_FindKeyCode;
if (CStringRange::Compare(_locale, psrgLeft, psrgLeftNext) == CSTR_GREATER_THAN)
{
CCandidateListItem ListItem;
ListItem = *pItemList->GetAt(leftRange);
*pItemList->GetAt(leftRange ) = *pItemList->GetAt(leftRange+1);
*pItemList->GetAt(leftRange+1) = ListItem;
}
}
}
int CBaseDictionaryEngine::CalculateCandidateCount(int leftRange, int rightRange)
{
assert(leftRange >= 0);
assert(rightRange >= 0);
return (rightRange - leftRange + 1);
}
+41
View File
@@ -0,0 +1,41 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "File.h"
#include "SampleIMEBaseStructure.h"
class CBaseDictionaryEngine
{
public:
CBaseDictionaryEngine(LCID locale, _In_ CFile *pDictionaryFile);
virtual ~CBaseDictionaryEngine();
virtual VOID CollectWord(_In_ CStringRange *psrgKeyCode, _Out_ CSampleImeArray<CStringRange> *pasrgWordString)
{
psrgKeyCode;
pasrgWordString = nullptr;
}
virtual VOID CollectWord(_In_ CStringRange *psrgKeyCode, _Out_ CSampleImeArray<CCandidateListItem> *pItemList)
{
psrgKeyCode;
pItemList = nullptr;
}
virtual VOID SortListItemByFindKeyCode(_Inout_ CSampleImeArray<CCandidateListItem> *pItemList);
protected:
CFile* _pDictionaryFile;
LCID _locale;
private:
VOID MergeSortByFindKeyCode(_Inout_ CSampleImeArray<CCandidateListItem> *pItemList, int leftRange, int rightRange);
int CalculateCandidateCount(int leftRange, int rightRange);
};
+662
View File
@@ -0,0 +1,662 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
#include "BaseWindow.h"
#define idTimer_UIObject 39772
//+---------------------------------------------------------------------------
//
// CBaseWindow::ctor
//
//----------------------------------------------------------------------------
CBaseWindow::CBaseWindow()
{
_wndHandle = nullptr;
_pParentWnd = nullptr;
_pUIWnd = nullptr;
_pTimerUIObj = nullptr;
_pUIObjCapture = nullptr;
_enableVirtualWnd = TRUE;
_visibleVirtualWnd = TRUE;
_RectOfVirtualWnd.left = 0;
_RectOfVirtualWnd.top = 0;
_RectOfVirtualWnd.right = 0;
_RectOfVirtualWnd.bottom = 0;
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::dtor
//
//----------------------------------------------------------------------------
CBaseWindow::~CBaseWindow()
{
_SetThis(_wndHandle, nullptr);
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_InitWindowClass
//
//----------------------------------------------------------------------------
/* static */
BOOL CBaseWindow::_InitWindowClass(_In_ LPCWSTR lpwszClassName, _Out_ ATOM *patom)
{
WNDCLASS wc;
wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW | CS_IME;
wc.lpfnWndProc = CBaseWindow::_WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = Global::dllInstanceHandle;
wc.hIcon = nullptr;
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
wc.lpszMenuName = nullptr;
wc.lpszClassName = lpwszClassName;
*patom = RegisterClass(&wc);
return (*patom != 0);
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_UninitClass
//
//----------------------------------------------------------------------------
/* static */
void CBaseWindow::_UninitWindowClass(ATOM atom)
{
if (atom != 0)
{
UnregisterClass((LPCTSTR)atom, Global::dllInstanceHandle);
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_Create
//
//----------------------------------------------------------------------------
BOOL CBaseWindow::_Create(ATOM atom, DWORD dwExStyle, DWORD dwStyle, _In_opt_ CBaseWindow *pParentWnd, int wndWidth, int wndHeight, _In_opt_ HWND parentWndHandle)
{
_pParentWnd = pParentWnd;
if (atom != 0)
{
// create real window
_wndHandle = CreateWindowEx(dwExStyle,
(LPCTSTR)atom,
NULL,
dwStyle,
0, 0,
wndWidth, wndHeight,
_pParentWnd ? _pParentWnd->_GetWnd() : parentWndHandle, // parentWndHandle
NULL,
Global::dllInstanceHandle,
this); // lpParam
if (!_wndHandle)
{
return FALSE;
}
}
return TRUE;
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_Destroy
//
//----------------------------------------------------------------------------
void CBaseWindow::_Destroy()
{
if (_wndHandle != nullptr)
{
DestroyWindow(_wndHandle);
_wndHandle = nullptr;
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_Move
//
//----------------------------------------------------------------------------
void CBaseWindow::_Move(int x, int y)
{
if (_wndHandle != nullptr)
{
SetWindowPos(_wndHandle, 0, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
}
else
{
int dx = x - _RectOfVirtualWnd.left;
int dy = y - _RectOfVirtualWnd.top;
_RectOfVirtualWnd.left += dx;
_RectOfVirtualWnd.top += dy;
_RectOfVirtualWnd.right += dx;
_RectOfVirtualWnd.bottom += dy;
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_Resize
//
//----------------------------------------------------------------------------
void CBaseWindow::_Resize(int x, int y, int cx, int cy)
{
if (_wndHandle != nullptr)
{
MoveWindow(_wndHandle, x, y, cx, cy, TRUE);
}
else
{
_RectOfVirtualWnd.left = x;
_RectOfVirtualWnd.top = y;
_RectOfVirtualWnd.right = x + cx;
_RectOfVirtualWnd.bottom = y + cy;
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_Show
//
//----------------------------------------------------------------------------
void CBaseWindow::_Show(BOOL isShowWnd)
{
if (_wndHandle != nullptr)
{
if (isShowWnd)
{
ShowWindow(_wndHandle, SW_SHOWNA);
}
else
{
ShowWindow(_wndHandle, SW_HIDE);
}
}
else
{
_visibleVirtualWnd = isShowWnd;
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_IsWindowVisible
//
//----------------------------------------------------------------------------
BOOL CBaseWindow::_IsWindowVisible()
{
if (_wndHandle != nullptr)
{
return IsWindowVisible(_wndHandle);
}
else
{
return _visibleVirtualWnd;
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_Enable
//
//----------------------------------------------------------------------------
void CBaseWindow::_Enable(BOOL enableWindowReceiveInput)
{
if (_wndHandle != nullptr)
{
EnableWindow(_wndHandle, enableWindowReceiveInput);
}
else
{
_enableVirtualWnd = enableWindowReceiveInput;
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_IsEnabled
//
//----------------------------------------------------------------------------
BOOL CBaseWindow::_IsEnabled()
{
if (_wndHandle != nullptr)
{
return IsWindowEnabled(_wndHandle);
}
else
{
return _enableVirtualWnd;
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_InvalidateRect
//
//----------------------------------------------------------------------------
void CBaseWindow::_InvalidateRect()
{
if (_wndHandle != nullptr)
{
InvalidateRect(_wndHandle, NULL, TRUE);
}
else
{
CBaseWindow *pobj = _pParentWnd;
while (pobj != nullptr)
{
if (pobj->_wndHandle)
{
InvalidateRect(pobj->_wndHandle, &_RectOfVirtualWnd, TRUE);
break;
}
pobj = pobj->_pParentWnd;
}
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_GetWindowRect
//
//----------------------------------------------------------------------------
BOOL CBaseWindow::_GetWindowRect(_Inout_ LPRECT lpRect)
{
if (_wndHandle != nullptr)
{
return GetWindowRect(_wndHandle, lpRect);
}
else
{
*lpRect = _RectOfVirtualWnd;
return TRUE;
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_GetClientRect
//
//----------------------------------------------------------------------------
BOOL CBaseWindow::_GetClientRect(_Inout_ LPRECT lpRect)
{
if (_wndHandle != nullptr)
{
return GetClientRect(_wndHandle, lpRect);
}
else
{
*lpRect = _RectOfVirtualWnd;
return TRUE;
}
}
//+---------------------------------------------------------------------------
//
// _GetWindowExtent
//
//----------------------------------------------------------------------------
HRESULT CBaseWindow::_GetWindowExtent(_In_ const RECT *prcTextExtent, _In_opt_ RECT *prcCandidateExtent, _Inout_ POINT *pptCandidate)
{
RECT rcWorkArea = {0, 0, 0, 0};
// Get work area
GetWorkAreaFromPoint(*(LPPOINT)&prcTextExtent->left, &rcWorkArea);
// Calc candidate window extent
if (prcCandidateExtent)
{
CalcFitPointAroundTextExtent(prcTextExtent, &rcWorkArea, prcCandidateExtent, pptCandidate);
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// CalcFitPointAroundTextExtent
//
//----------------------------------------------------------------------------
void CBaseWindow::CalcFitPointAroundTextExtent(_In_ const RECT *prcTextExtent, _In_ const RECT *prcWorkArea, _In_ const RECT *prcWindow, _Out_ POINT *ppt)
{
RECT rcTargetWindow[2];
DWORD dwFlags[2];
// set rcTargetWindow[0] which rectangle attached on bottom side of text extent
rcTargetWindow[0] = *prcWindow;
OffsetRect(&rcTargetWindow[0], prcTextExtent->left, prcTextExtent->bottom);
// set rcTargetWindow[1] which rectangle attached on top side of text extent
rcTargetWindow[1] = *prcWindow;
OffsetRect(&rcTargetWindow[1], prcTextExtent->left, prcTextExtent->top - (prcWindow->bottom - prcWindow->top));
//
// check target rectangle fit in workarea
//
for (DWORD i = 0; i < ARRAYSIZE(rcTargetWindow); i++)
{
dwFlags[i] = RectInRect(prcWorkArea, &rcTargetWindow[i]);
// generally, rcTargetWindow[0] or rcTargetWindow[1] have neither of these flags
// but in the case where window is just complete way off the screen e.g. user
// starts input, then drag window way off screen, both of these will be true
if ((dwFlags[i] & RECT_OVER_TOP) || (dwFlags[i] & RECT_OVER_BOTTOM))
{
continue;
}
if (dwFlags[i] == RECT_INSIDE)
{
*ppt = *(POINT*)&rcTargetWindow[i].left;
return;
}
else if ((dwFlags[i] & RECT_OVER_LEFT) != 0)
{
ppt->x = 0;
ppt->y = rcTargetWindow[i].top;
return;
}
else if ((dwFlags[i] & RECT_OVER_RIGHT) != 0)
{
ppt->x = prcWorkArea->right - (prcWindow->right - prcWindow->left);
ppt->y = rcTargetWindow[i].top;
return;
}
}
// if both rcTargetWindow have RECT_OVER_TOP or RECT_OVER_BOTTOM,
// then "dock" the window to top or bottom of working area.
if ((dwFlags[0] & RECT_OVER_TOP) != 0)
{
ppt->y = 0;
}
else
{
ppt->y = prcWorkArea->bottom - (prcWindow->bottom - prcWindow->top);
}
// dock to left/right edge if RECT_OVER_LEFT or RECT_OVER_RIGHT.
// else just stay where we are
if ((dwFlags[0] & RECT_OVER_LEFT) != 0)
{
ppt->x = 0;
}
else if ((dwFlags[0] & RECT_OVER_RIGHT) != 0)
{
ppt->x = prcWorkArea->right - (prcWindow->right - prcWindow->left);
}
else
{
ppt->x = prcTextExtent->left;
}
return;
}
//+---------------------------------------------------------------------------
//
// RectInRect
//
//----------------------------------------------------------------------------
DWORD CBaseWindow::RectInRect(_In_ const RECT *prcLimit, _In_ const RECT *prcTarget)
{
DWORD dwFlags = 0;
// Check if prcTarget is entirely inside prcLimit
if (prcLimit->left <= prcTarget->left && prcTarget->right <= prcLimit->right &&
prcLimit->top <= prcTarget->top && prcTarget->bottom <= prcLimit->bottom)
{
return RECT_INSIDE;
}
// Check horizontal range. Target can be
// - wider than the limit (assert here since it should never happen)
// - entirely outside the limit (RECT_OVERLEFT or RECT_OVERRIGHT)
// - partially inside the limit (RECT_OVERLEFT or RECT_OVERRIGHT)
if (prcTarget->left < prcLimit->left && prcTarget->right > prcLimit->right)
{
assert(FALSE);
dwFlags |= RECT_TOO_WIDE;
}
else if (prcTarget->left < prcLimit->left)
{
dwFlags |= RECT_OVER_LEFT;
}
else if (prcTarget->right > prcLimit->right)
{
dwFlags |= RECT_OVER_RIGHT;
}
// Check vertical range. Target can be
// - taller than the limit (assert here since it should never happen)
// - entirely outside the limit (RECT_OVERTOP or RECT_OVERBOTTOM)
// - partially inside the limit (RECT_OVERTOP or RECT_OVERBOTTOM)
if (prcTarget->top < prcLimit->top && prcTarget->bottom > prcLimit->bottom)
{
assert(FALSE);
dwFlags |= RECT_TOO_TALL;
}
else if (prcTarget->top < prcLimit->top)
{
dwFlags |= RECT_OVER_TOP;
}
else if (prcTarget->bottom > prcLimit->bottom)
{
dwFlags |= RECT_OVER_BOTTOM;
}
return dwFlags;
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_NotifyCommand
//
//----------------------------------------------------------------------------
LRESULT CBaseWindow::_NotifyCommand(UINT uMsg, DWORD dwSB, int nPos)
{
CBaseWindow* pUIWnd = _GetUIWnd();
if (pUIWnd && pUIWnd->_GetWnd())
{
WPARAM wParam = MAKEWPARAM(dwSB, nPos);
if (pUIWnd->_GetWnd())
{
return SendMessage(pUIWnd->_GetWnd(), uMsg, wParam, (LPARAM)0);
}
}
return 0;
}
//+---------------------------------------------------------------------------
//
// _SetCaptureObject
//
//----------------------------------------------------------------------------
void CBaseWindow::_SetCaptureObject(_In_opt_ CBaseWindow *pUIObj)
{
CBaseWindow* pUIWnd = _GetTopmostUIWnd();
if (nullptr == pUIWnd)
{
return;
}
pUIWnd->_pUIObjCapture = pUIObj;
if (pUIObj != nullptr)
{
SetCapture(pUIWnd->_GetWnd());
}
else
{
ReleaseCapture();
}
}
//+---------------------------------------------------------------------------
//
// _SetTimerObject
//
//----------------------------------------------------------------------------
void CBaseWindow::_SetTimerObject(_In_opt_ CBaseWindow *pUIObj, UINT uElapse)
{
CBaseWindow* pUIWnd = _GetTopmostUIWnd();
if (nullptr == pUIWnd)
{
return;
}
pUIWnd->_pTimerUIObj = pUIObj;
if (pUIObj != nullptr)
{
SetTimer(pUIWnd->_GetWnd(), idTimer_UIObject, uElapse, NULL);
}
else
{
KillTimer(pUIWnd->_GetWnd(), idTimer_UIObject);
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::_WindowProc
//
// CBaseWindow window proc.
//----------------------------------------------------------------------------
/* static */
LRESULT CALLBACK CBaseWindow::_WindowProc(_In_ HWND wndHandle, UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
if (uMsg == WM_CREATE)
{
_SetThis(wndHandle, ((CREATESTRUCT*)lParam)->lpCreateParams);
}
CBaseWindow* pv = _GetThis(wndHandle);
if (!pv)
{
return DefWindowProc(wndHandle, uMsg, wParam, lParam);
}
if (uMsg == WM_TIMER)
{
switch (wParam)
{
case idTimer_UIObject:
if (pv->_GetTimerObject() != nullptr)
{
pv->_GetTimerObject()->_OnTimer();
}
break;
}
return 0;
}
else
{
return pv->_WindowProcCallback(wndHandle, uMsg, wParam, lParam);
}
}
//+---------------------------------------------------------------------------
//
// CBaseWindow::GetWorkAreaFromPoint
//
//----------------------------------------------------------------------------
void CBaseWindow::GetWorkAreaFromPoint(_In_ const POINT& ptPoint, _Out_ LPRECT lprcWorkArea)
{
if (lprcWorkArea == nullptr)
{
return;
}
lprcWorkArea->left = 0;
lprcWorkArea->top = 0;
lprcWorkArea->right = 0;
lprcWorkArea->bottom = 0;
HMONITOR hMonitor = MonitorFromPoint(ptPoint, MONITOR_DEFAULTTONEAREST);
if (hMonitor)
{
MONITORINFO MonitorInfo = {0};
MonitorInfo.cbSize = sizeof(MONITORINFO);
if (GetMonitorInfo(hMonitor, &MonitorInfo))
{
*lprcWorkArea = MonitorInfo.rcWork;
return;
}
}
SystemParametersInfo(SPI_GETWORKAREA, 0, lprcWorkArea, 0);
return;
}
BOOL CBaseWindow::_IsTimer()
{
CBaseWindow* pobj = _GetTopmostUIWnd();
if (pobj != nullptr)
{
return (pobj->_pTimerUIObj != nullptr);
}
return FALSE;
}
BOOL CBaseWindow::_IsCapture()
{
CBaseWindow* pobj = _GetTopmostUIWnd();
if (pobj != nullptr)
{
return (pobj->_pUIObjCapture != nullptr);
}
return FALSE;
}
CBaseWindow* CBaseWindow::_GetTopmostUIWnd()
{
CBaseWindow* pobj = this;
while (pobj->_pParentWnd != nullptr)
{
pobj = pobj->_pParentWnd;
}
return pobj->_pUIWnd;
}
+160
View File
@@ -0,0 +1,160 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#define RECT_INSIDE (0x0001)
#define RECT_OVER_LEFT (0x0002)
#define RECT_OVER_TOP (0x0004)
#define RECT_OVER_RIGHT (0x0008)
#define RECT_OVER_BOTTOM (0x0010)
#define RECT_TOO_WIDE (0x0020)
#define RECT_TOO_TALL (0x0040)
#define RECT_ERROR (0x0080)
class CStringRange;
//+---------------------------------------------------------------------------
//
// CBaseWindow
//
//----------------------------------------------------------------------------
class CBaseWindow
{
public:
CBaseWindow();
virtual ~CBaseWindow();
static BOOL _InitWindowClass(_In_ LPCWSTR lpwszClassName, _Out_ ATOM *patom);
static void _UninitWindowClass(ATOM atom);
virtual BOOL _Create(ATOM atom, DWORD dwExStyle, DWORD dwStyle, _In_opt_ CBaseWindow *pParentWnd = nullptr, int wndWidth = 0, int wndHeight = 0, _In_opt_ HWND parentWndHandle = nullptr);
virtual void _Destroy();
virtual void _Move(int x, int y);
virtual void _Resize(int x, int y, int cx, int cy);
virtual void _Show(BOOL isShowWnd);
virtual BOOL _IsWindowVisible();
virtual void _Enable(BOOL enableWindowReceiveInput);
virtual BOOL _IsEnabled();
virtual void _InvalidateRect();
virtual BOOL _GetWindowRect(_Inout_ LPRECT lpRect);
virtual BOOL _GetClientRect(_Inout_ LPRECT lpRect);
virtual LRESULT CALLBACK _WindowProcCallback(_In_ HWND wndHandle, UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam) = 0;
virtual void _OnPaint(_In_ HDC dcHandle, _In_ PAINTSTRUCT *pps) { dcHandle; pps; }
virtual void _OnLButtonDown(POINT pt) { pt; }
virtual void _OnLButtonUp(POINT pt) { pt; }
virtual void _OnMouseMove(POINT pt) { pt; }
virtual void _OnTimer() { }
CBaseWindow* _GetTopmostUIWnd();
HRESULT _GetWindowExtent(_In_ const RECT *prcTextExtent, _In_opt_ RECT *prcCandidateExtent, _Inout_ POINT *pptCandidate);
HWND _GetWnd()
{
return _wndHandle;
}
CBaseWindow *_GetParent()
{
return _pParentWnd;
}
void _SetUIWnd(_In_ CBaseWindow *pUIWnd)
{
_pUIWnd = pUIWnd;
}
CBaseWindow* _GetUIWnd()
{
return _pUIWnd;
}
CBaseWindow *_GetCaptureObject()
{
return _pUIObjCapture;
}
CBaseWindow *_GetTimerObject()
{
return _pTimerUIObj;
}
UINT _GetScrollDelay()
{
return (GetDoubleClickTime() * 4 / 5);
}
UINT _GetScrollSpeed()
{
return (_GetScrollDelay() / 8);
}
protected:
LRESULT _NotifyCommand(UINT uMsg, DWORD dwSB, int nPos);
void _StartCapture()
{
_SetCaptureObject(this);
}
void _EndCapture()
{
_SetCaptureObject(nullptr);
}
BOOL _IsCapture();
void _StartTimer(UINT uElapse)
{
_SetTimerObject(this, uElapse);
}
void _EndTimer()
{
_SetTimerObject(nullptr);
}
BOOL _IsTimer();
private:
void _SetCaptureObject(_In_opt_ CBaseWindow *pUIObj);
void _SetTimerObject(_In_opt_ CBaseWindow *pUIObj, UINT uElapse = 0);
void GetWorkAreaFromPoint(_In_ const POINT& ptPoint, _Out_ LPRECT lprcWorkArea);
void CalcFitPointAroundTextExtent(_In_ const RECT *prcTextExtent, _In_ const RECT *prcWorkArea, _In_ const RECT *prcWindow, _Out_ POINT *ppt);
DWORD RectInRect(_In_ const RECT *prcLimit, _In_ const RECT *prcTarget);
static LRESULT CALLBACK _WindowProc(_In_ HWND wndHandle, UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam);
static CBaseWindow *_GetThis(_In_ HWND wndHandle)
{
return (CBaseWindow *)GetWindowLongPtr(wndHandle, GWLP_USERDATA);
}
static void _SetThis(_In_ HWND wndHandle, _In_opt_ void *lpv)
{
SetWindowLongPtr(wndHandle, GWLP_USERDATA, (LONG_PTR)lpv);
}
private:
HWND _wndHandle;
CBaseWindow *_pParentWnd;
CBaseWindow *_pUIWnd;
CBaseWindow *_pTimerUIObj;
CBaseWindow *_pUIObjCapture;
BOOL _enableVirtualWnd;
BOOL _visibleVirtualWnd;
RECT _RectOfVirtualWnd;
};
+90
View File
@@ -0,0 +1,90 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "BaseWindow.h"
#include "ButtonWindow.h"
//+---------------------------------------------------------------------------
//
// CButtonWindow
//
//----------------------------------------------------------------------------
CButtonWindow::CButtonWindow()
{
typeOfControl = 0;
}
//+---------------------------------------------------------------------------
//
// ~CButtonWindow
//
//----------------------------------------------------------------------------
CButtonWindow::~CButtonWindow()
{
}
//+---------------------------------------------------------------------------
//
// _OnPaint
//
//----------------------------------------------------------------------------
void CButtonWindow::_OnPaint(_In_ HDC dcHandle, _In_ PAINTSTRUCT *pps)
{
dcHandle;
pps;
}
//+---------------------------------------------------------------------------
//
// _OnLButtonDown
//
//----------------------------------------------------------------------------
void CButtonWindow::_OnLButtonDown(POINT pt)
{
pt;
typeOfControl = DFCS_PUSHED;
_StartCapture();
}
//+---------------------------------------------------------------------------
//
// _WindowProcCallback
//
//----------------------------------------------------------------------------
LRESULT CALLBACK CButtonWindow::_WindowProcCallback(_In_ HWND wndHandle, UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
wndHandle;
uMsg;
wParam;
lParam;
return 0;
}
//+---------------------------------------------------------------------------
//
// _OnLButtonUp
//
//----------------------------------------------------------------------------
void CButtonWindow::_OnLButtonUp(POINT pt)
{
pt;
if (_IsCapture())
{
_EndCapture();
}
typeOfControl = 0;
}
+27
View File
@@ -0,0 +1,27 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "BaseWindow.h"
class CButtonWindow : public CBaseWindow
{
public:
CButtonWindow();
virtual ~CButtonWindow();
LRESULT CALLBACK _WindowProcCallback(_In_ HWND wndHandle, UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam);
virtual void _OnPaint(_In_ HDC dcHandle, _In_ PAINTSTRUCT *pps);
virtual void _OnLButtonDown(POINT pt);
virtual void _OnLButtonUp(POINT pt);
protected:
UINT typeOfControl; // DFCS_PUSHED, DFCS_INACTIVE or others for DrawFrameControl
};
+85
View File
@@ -0,0 +1,85 @@
"./ActiveLanguageProfileNotifySink.cpp"
"./BaseDictionaryEngine.cpp"
"./BaseDictionaryEngine.h"
"./BaseWindow.cpp"
"./BaseWindow.h"
"./ButtonWindow.cpp"
"./ButtonWindow.h"
"./CandidateListUIPresenter.cpp"
"./CandidateListUIPresenter.h"
"./CandidateWindow.cpp"
"./CandidateWindow.h"
"./Compartment.cpp"
"./Compartment.h"
"./Composition.cpp"
"./CompositionProcessorEngine.cpp"
"./CompositionProcessorEngine.h"
"./Define.h"
"./DictionaryParser.cpp"
"./DictionaryParser.h"
"./DictionarySearch.cpp"
"./DictionarySearch.h"
"./DisplayAttribute.cpp"
"./DisplayAttributeInfo.cpp"
"./DisplayAttributeInfo.h"
"./DisplayAttributeProvider.cpp"
"./DisplayString.h"
"./DllMain.cpp"
"./EditSession.cpp"
"./EditSession.h"
"./EndComposition.cpp"
"./EnumDisplayAttributeInfo.cpp"
"./EnumDisplayAttributeInfo.h"
"./EnumTfCandidates.cpp"
"./EnumTfCandidates.h"
"./File.cpp"
"./File.h"
"./FileMapping.cpp"
"./FileMapping.h"
"./FunctionProviderSink.cpp"
"./GetTextExtentEditSession.cpp"
"./GetTextExtentEditSession.h"
"./Globals.cpp"
"./Globals.h"
"./KeyEventSink.cpp"
"./KeyHandler.cpp"
"./KeyHandlerEditSession.cpp"
"./KeyHandlerEditSession.h"
"./KeyStateCategory.cpp"
"./KeyStateCategory.h"
"./LanguageBar.cpp"
"./LanguageBar.h"
"./Private.h"
"./Register.cpp"
"./RegKey.cpp"
"./RegKey.h"
"./resource.h"
"./SampleIME.cpp"
"./SampleIME.def"
"./SampleIME.h"
"./SampleIME.rc"
"./SampleIMEBaseStructure.cpp"
"./SampleIMEBaseStructure.h"
"./SampleIMEStructureArray.h"
"./ScrollBarWindow.cpp"
"./ScrollBarWindow.h"
"./SearchCandidateProvider.cpp"
"./SearchCandidateProvider.h"
"./Server.cpp"
"./ShadowWindow.cpp"
"./ShadowWindow.h"
"./StartComposition.cpp"
"./stdafx.h"
"./TableDictionaryEngine.cpp"
"./TableDictionaryEngine.h"
"./TextEditSink.cpp"
"./TfInputProcessorProfile.cpp"
"./TfInputProcessorProfile.h"
"./TfTextLayoutSink.cpp"
"./TfTextLayoutSink.h"
"./ThreadFocusSink.cpp"
"./ThreadMgrEventSink.cpp"
"./TipCandidateList.cpp"
"./TipCandidateList.h"
"./TipCandidateString.cpp"
"./TipCandidateString.h"
+98
View File
@@ -0,0 +1,98 @@
cmake_minimum_required(VERSION 3.25.0)
project(fanytsfime)
# http://www.utf8everywhere.org/
add_definitions(
/D_UNICODE=1
/DUNICODE=1
)
add_library(SampleIME SHARED
"./ActiveLanguageProfileNotifySink.cpp"
"./BaseDictionaryEngine.cpp"
"./BaseDictionaryEngine.h"
"./BaseWindow.cpp"
"./BaseWindow.h"
"./ButtonWindow.cpp"
"./ButtonWindow.h"
"./CandidateListUIPresenter.cpp"
"./CandidateListUIPresenter.h"
"./CandidateWindow.cpp"
"./CandidateWindow.h"
"./Compartment.cpp"
"./Compartment.h"
"./Composition.cpp"
"./CompositionProcessorEngine.cpp"
"./CompositionProcessorEngine.h"
"./Define.h"
"./DictionaryParser.cpp"
"./DictionaryParser.h"
"./DictionarySearch.cpp"
"./DictionarySearch.h"
"./DisplayAttribute.cpp"
"./DisplayAttributeInfo.cpp"
"./DisplayAttributeInfo.h"
"./DisplayAttributeProvider.cpp"
"./DisplayString.h"
"./DllMain.cpp"
"./EditSession.cpp"
"./EditSession.h"
"./EndComposition.cpp"
"./EnumDisplayAttributeInfo.cpp"
"./EnumDisplayAttributeInfo.h"
"./EnumTfCandidates.cpp"
"./EnumTfCandidates.h"
"./File.cpp"
"./File.h"
"./FileMapping.cpp"
"./FileMapping.h"
"./FunctionProviderSink.cpp"
"./GetTextExtentEditSession.cpp"
"./GetTextExtentEditSession.h"
"./Globals.cpp"
"./Globals.h"
"./KeyEventSink.cpp"
"./KeyHandler.cpp"
"./KeyHandlerEditSession.cpp"
"./KeyHandlerEditSession.h"
"./KeyStateCategory.cpp"
"./KeyStateCategory.h"
"./LanguageBar.cpp"
"./LanguageBar.h"
"./Private.h"
"./Register.cpp"
"./RegKey.cpp"
"./RegKey.h"
"./resource.h"
"./SampleIME.cpp"
"./SampleIME.def"
"./SampleIME.h"
"./SampleIME.rc"
"./SampleIMEBaseStructure.cpp"
"./SampleIMEBaseStructure.h"
"./SampleIMEStructureArray.h"
"./ScrollBarWindow.cpp"
"./ScrollBarWindow.h"
"./SearchCandidateProvider.cpp"
"./SearchCandidateProvider.h"
"./Server.cpp"
"./ShadowWindow.cpp"
"./ShadowWindow.h"
"./StartComposition.cpp"
"./stdafx.h"
"./TableDictionaryEngine.cpp"
"./TableDictionaryEngine.h"
"./TextEditSink.cpp"
"./TfInputProcessorProfile.cpp"
"./TfInputProcessorProfile.h"
"./TfTextLayoutSink.cpp"
"./TfTextLayoutSink.h"
"./ThreadFocusSink.cpp"
"./ThreadMgrEventSink.cpp"
"./TipCandidateList.cpp"
"./TipCandidateList.h"
"./TipCandidateString.cpp"
"./TipCandidateString.h"
)
File diff suppressed because it is too large. Load diff
+139
View File
@@ -0,0 +1,139 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "KeyHandlerEditSession.h"
#include "CandidateWindow.h"
#include "TfTextLayoutSink.h"
#include "SampleIME.h"
#include "SampleIMEBaseStructure.h"
class CReadingLine;
//+---------------------------------------------------------------------------
//
// CCandidateListUIPresenter
//
// ITfCandidateListUIElement / ITfIntegratableCandidateListUIElement is used for
// UILess mode support
// ITfCandidateListUIElementBehavior sends the Selection behavior message to
// 3rd party IME.
//----------------------------------------------------------------------------
class CCandidateListUIPresenter : public CTfTextLayoutSink,
public ITfCandidateListUIElementBehavior,
public ITfIntegratableCandidateListUIElement
{
public:
CCandidateListUIPresenter(_In_ CSampleIME *pTextService, ATOM atom,
KEYSTROKE_CATEGORY Category,
_In_ CCandidateRange *pIndexRange,
BOOL hideWindow);
virtual ~CCandidateListUIPresenter();
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// ITfUIElement
STDMETHODIMP GetDescription(BSTR *pbstr);
STDMETHODIMP GetGUID(GUID *pguid);
STDMETHODIMP Show(BOOL showCandidateWindow);
STDMETHODIMP IsShown(BOOL *pIsShow);
// ITfCandidateListUIElement
STDMETHODIMP GetUpdatedFlags(DWORD *pdwFlags);
STDMETHODIMP GetDocumentMgr(ITfDocumentMgr **ppdim);
STDMETHODIMP GetCount(UINT *pCandidateCount);
STDMETHODIMP GetSelection(UINT *pSelectedCandidateIndex);
STDMETHODIMP GetString(UINT uIndex, BSTR *pbstr);
STDMETHODIMP GetPageIndex(UINT *pIndex, UINT uSize, UINT *puPageCnt);
STDMETHODIMP SetPageIndex(UINT *pIndex, UINT uPageCnt);
STDMETHODIMP GetCurrentPage(UINT *puPage);
// ITfCandidateListUIElementBehavior methods
STDMETHODIMP SetSelection(UINT nIndex);
STDMETHODIMP Finalize(void);
STDMETHODIMP Abort(void);
// ITfIntegratableCandidateListUIElement
STDMETHODIMP SetIntegrationStyle(GUID guidIntegrationStyle);
STDMETHODIMP GetSelectionStyle(_Out_ TfIntegratableCandidateListSelectionStyle *ptfSelectionStyle);
STDMETHODIMP OnKeyDown(_In_ WPARAM wParam, _In_ LPARAM lParam, _Out_ BOOL *pIsEaten);
STDMETHODIMP ShowCandidateNumbers(_Out_ BOOL *pIsShow);
STDMETHODIMP FinalizeExactCompositionString();
virtual HRESULT _StartCandidateList(TfClientId tfClientId, _In_ ITfDocumentMgr *pDocumentMgr, _In_ ITfContext *pContextDocument, TfEditCookie ec, _In_ ITfRange *pRangeComposition, UINT wndWidth);
void _EndCandidateList();
void _SetText(_In_ CSampleImeArray<CCandidateListItem> *pCandidateList, BOOL isAddFindKeyCode);
void _ClearList();
VOID _SetTextColor(COLORREF crColor, COLORREF crBkColor);
VOID _SetFillColor(HBRUSH hBrush);
DWORD_PTR _GetSelectedCandidateString(_Outptr_result_maybenull_ const WCHAR **ppwchCandidateString);
BOOL _SetSelectionInPage(int nPos) { return _pCandidateWnd->_SetSelectionInPage(nPos); }
BOOL _MoveSelection(_In_ int offSet);
BOOL _SetSelection(_In_ int selectedIndex);
BOOL _MovePage(_In_ int offSet);
void _MoveWindowToTextExt();
// CTfTextLayoutSink
virtual VOID _LayoutChangeNotification(_In_ RECT *lpRect);
virtual VOID _LayoutDestroyNotification();
// Event for ITfThreadFocusSink
virtual HRESULT OnSetThreadFocus();
virtual HRESULT OnKillThreadFocus();
void RemoveSpecificCandidateFromList(_In_ LCID Locale, _Inout_ CSampleImeArray<CCandidateListItem> &candidateList, _In_ CStringRange &srgCandidateString);
void AdviseUIChangedByArrowKey(_In_ KEYSTROKE_FUNCTION arrowKey);
private:
virtual HRESULT CALLBACK _CandidateChangeNotification(_In_ enum CANDWND_ACTION action);
static HRESULT _CandWndCallback(_In_ void *pv, _In_ enum CANDWND_ACTION action);
friend COLORREF _AdjustTextColor(_In_ COLORREF crColor, _In_ COLORREF crBkColor);
HRESULT _UpdateUIElement();
HRESULT ToShowCandidateWindow();
HRESULT ToHideCandidateWindow();
HRESULT BeginUIElement();
HRESULT EndUIElement();
HRESULT MakeCandidateWindow(_In_ ITfContext *pContextDocument, _In_ UINT wndWidth);
void DisposeCandidateWindow();
void AddCandidateToCandidateListUI(_In_ CSampleImeArray<CCandidateListItem> *pCandidateList, BOOL isAddFindKeyCode);
void SetPageIndexWithScrollInfo(_In_ CSampleImeArray<CCandidateListItem> *pCandidateList);
protected:
CCandidateWindow *_pCandidateWnd;
BOOL _isShowMode;
BOOL _hideWindow;
private:
HWND _parentWndHandle;
ATOM _atom;
CCandidateRange* _pIndexRange;
KEYSTROKE_CATEGORY _Category;
DWORD _updatedFlags;
DWORD _uiElementId;
CSampleIME* _pTextService;
LONG _refCount;
};
+1438
View File
File diff suppressed because it is too large. Load diff
+118
View File
@@ -0,0 +1,118 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "private.h"
#include "BaseWindow.h"
#include "ShadowWindow.h"
#include "ScrollBarWindow.h"
#include "SampleIMEBaseStructure.h"
enum CANDWND_ACTION
{
CAND_ITEM_SELECT
};
typedef HRESULT (*CANDWNDCALLBACK)(void *pv, enum CANDWND_ACTION action);
class CCandidateWindow : public CBaseWindow
{
public:
CCandidateWindow(_In_ CANDWNDCALLBACK pfnCallback, _In_ void *pv, _In_ CCandidateRange *pIndexRange, _In_ BOOL isStoreAppMode);
virtual ~CCandidateWindow();
BOOL _Create(ATOM atom, _In_ UINT wndWidth, _In_opt_ HWND parentWndHandle);
void _Move(int x, int y);
void _Show(BOOL isShowWnd);
VOID _SetTextColor(_In_ COLORREF crColor, _In_ COLORREF crBkColor);
VOID _SetFillColor(_In_ HBRUSH hBrush);
LRESULT CALLBACK _WindowProcCallback(_In_ HWND wndHandle, UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam);
void _OnPaint(_In_ HDC dcHandle, _In_ PAINTSTRUCT *pps);
void _OnLButtonDown(POINT pt);
void _OnLButtonUp(POINT pt);
void _OnMouseMove(POINT pt);
void _OnVScroll(DWORD dwSB, _In_ DWORD nPos);
void _AddString(_Inout_ CCandidateListItem *pCandidateItem, _In_ BOOL isAddFindKeyCode);
void _ClearList();
UINT _GetCount()
{
return _candidateList.Count();
}
UINT _GetSelection()
{
return _currentSelection;
}
void _SetScrollInfo(_In_ int nMax, _In_ int nPage);
DWORD _GetCandidateString(_In_ int iIndex, _Outptr_result_maybenull_z_ const WCHAR **ppwchCandidateString);
DWORD _GetSelectedCandidateString(_Outptr_result_maybenull_ const WCHAR **ppwchCandidateString);
BOOL _MoveSelection(_In_ int offSet, _In_ BOOL isNotify);
BOOL _SetSelection(_In_ int iPage, _In_ BOOL isNotify);
void _SetSelection(_In_ int nIndex);
BOOL _MovePage(_In_ int offSet, _In_ BOOL isNotify);
BOOL _SetSelectionInPage(int nPos);
HRESULT _GetPageIndex(UINT *pIndex, _In_ UINT uSize, _Inout_ UINT *puPageCnt);
HRESULT _SetPageIndex(UINT *pIndex, _In_ UINT uPageCnt);
HRESULT _GetCurrentPage(_Inout_ UINT *pCurrentPage);
HRESULT _GetCurrentPage(_Inout_ int *pCurrentPage);
private:
void _HandleMouseMsg(_In_ UINT mouseMsg, _In_ POINT point);
void _DrawList(_In_ HDC dcHandle, _In_ UINT iIndex, _In_ RECT *prc);
void _DrawBorder(_In_ HWND wndHandle, _In_ int cx);
BOOL _SetSelectionOffset(_In_ int offSet);
BOOL _AdjustPageIndexForSelection();
HRESULT _CurrentPageHasEmptyItems(_Inout_ BOOL *pfHasEmptyItems);
// LightDismiss feature support, it will fire messages lightdismiss-related to the light dismiss layout.
void _FireMessageToLightDismiss(_In_ HWND wndHandle, _In_ WINDOWPOS *pWndPos);
BOOL _CreateMainWindow(ATOM atom, _In_opt_ HWND parentWndHandle);
BOOL _CreateBackGroundShadowWindow();
BOOL _CreateVScrollWindow();
HRESULT _AdjustPageIndex(_Inout_ UINT & currentPage, _Inout_ UINT & currentPageIndex);
void _ResizeWindow();
void _DeleteShadowWnd();
void _DeleteVScrollBarWnd();
friend COLORREF _AdjustTextColor(_In_ COLORREF crColor, _In_ COLORREF crBkColor);
private:
UINT _currentSelection;
CSampleImeArray<CCandidateListItem> _candidateList;
CSampleImeArray<UINT> _PageIndex;
COLORREF _crTextColor;
COLORREF _crBkColor;
HBRUSH _brshBkColor;
TEXTMETRIC _TextMetric;
int _cyRow;
int _cxTitle;
UINT _wndWidth;
CCandidateRange* _pIndexRange;
CANDWNDCALLBACK _pfnCallback;
void* _pObj;
CShadowWindow* _pShadowWnd;
CScrollBarWindow* _pVScrollBarWnd;
BOOL _dontAdjustOnEmptyItemPage;
BOOL _isStoreAppMode;
};
+343
View File
@@ -0,0 +1,343 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Compartment.h"
#include "Globals.h"
//////////////////////////////////////////////////////////////////////
//
// CCompartment
//
//////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
// ctor
//----------------------------------------------------------------------------
CCompartment::CCompartment(_In_ IUnknown* punk, TfClientId tfClientId, _In_ REFGUID guidCompartment)
{
_guidCompartment = guidCompartment;
_punk = punk;
_punk->AddRef();
_tfClientId = tfClientId;
}
//+---------------------------------------------------------------------------
// dtor
//----------------------------------------------------------------------------
CCompartment::~CCompartment()
{
_punk->Release();
}
//+---------------------------------------------------------------------------
// _GetCompartment
//----------------------------------------------------------------------------
HRESULT CCompartment::_GetCompartment(_Outptr_ ITfCompartment **ppCompartment)
{
HRESULT hr = S_OK;
ITfCompartmentMgr* pCompartmentMgr = nullptr;
hr = _punk->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompartmentMgr);
if (SUCCEEDED(hr))
{
hr = pCompartmentMgr->GetCompartment(_guidCompartment, ppCompartment);
pCompartmentMgr->Release();
}
return hr;
}
//+---------------------------------------------------------------------------
// _GetCompartmentBOOL
//----------------------------------------------------------------------------
HRESULT CCompartment::_GetCompartmentBOOL(_Out_ BOOL &flag)
{
HRESULT hr = S_OK;
ITfCompartment* pCompartment = nullptr;
flag = FALSE;
if ((hr = _GetCompartment(&pCompartment)) == S_OK)
{
VARIANT var;
if ((hr = pCompartment->GetValue(&var)) == S_OK)
{
if (var.vt == VT_I4) // Even VT_EMPTY, GetValue() can succeed
{
flag = (BOOL)var.lVal;
}
else
{
hr = S_FALSE;
}
}
pCompartment->Release();
}
return hr;
}
//+---------------------------------------------------------------------------
// _SetCompartmentBOOL
//----------------------------------------------------------------------------
HRESULT CCompartment::_SetCompartmentBOOL(_In_ BOOL flag)
{
HRESULT hr = S_OK;
ITfCompartment* pCompartment = nullptr;
hr = _GetCompartment(&pCompartment);
if (SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_I4;
var.lVal = flag;
hr = pCompartment->SetValue(_tfClientId, &var);
pCompartment->Release();
}
return hr;
}
//+---------------------------------------------------------------------------
// _GetCompartmentDWORD
//----------------------------------------------------------------------------
HRESULT CCompartment::_GetCompartmentDWORD(_Out_ DWORD &dw)
{
HRESULT hr = S_OK;
ITfCompartment* pCompartment = nullptr;
dw = 0;
hr = _GetCompartment(&pCompartment);
if (SUCCEEDED(hr))
{
VARIANT var;
if ((hr = pCompartment->GetValue(&var)) == S_OK)
{
if (var.vt == VT_I4) // Even VT_EMPTY, GetValue() can succeed
{
dw = (DWORD)var.lVal;
}
else
{
hr = S_FALSE;
}
}
pCompartment->Release();
}
return hr;
}
//+---------------------------------------------------------------------------
// _SetCompartmentDWORD
//----------------------------------------------------------------------------
HRESULT CCompartment::_SetCompartmentDWORD(_In_ DWORD dw)
{
HRESULT hr = S_OK;
ITfCompartment* pCompartment = nullptr;
hr = _GetCompartment(&pCompartment);
if (SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_I4;
var.lVal = dw;
hr = pCompartment->SetValue(_tfClientId, &var);
pCompartment->Release();
}
return hr;
}
//+---------------------------------------------------------------------------
//
// _ClearCompartment
//
//----------------------------------------------------------------------------
HRESULT CCompartment::_ClearCompartment()
{
if (IsEqualGUID(_guidCompartment, GUID_COMPARTMENT_KEYBOARD_OPENCLOSE))
{
return S_FALSE;
}
HRESULT hr = S_OK;
ITfCompartmentMgr* pCompartmentMgr = nullptr;
if ((hr = _punk->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompartmentMgr)) == S_OK)
{
hr = pCompartmentMgr->ClearCompartment(_tfClientId, _guidCompartment);
pCompartmentMgr->Release();
}
return hr;
}
//////////////////////////////////////////////////////////////////////
//
// CCompartmentEventSink
//
//////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
// ctor
//----------------------------------------------------------------------------
CCompartmentEventSink::CCompartmentEventSink(_In_ CESCALLBACK pfnCallback, _In_ void *pv)
{
_pfnCallback = pfnCallback;
_pv = pv;
_refCount = 1;
}
//+---------------------------------------------------------------------------
// dtor
//----------------------------------------------------------------------------
CCompartmentEventSink::~CCompartmentEventSink()
{
}
//+---------------------------------------------------------------------------
//
// QueryInterface
//
//----------------------------------------------------------------------------
STDAPI CCompartmentEventSink::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
return E_INVALIDARG;
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_ITfCompartmentEventSink))
{
*ppvObj = (CCompartmentEventSink *)this;
}
if (*ppvObj)
{
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//+---------------------------------------------------------------------------
//
// AddRef
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CCompartmentEventSink::AddRef()
{
return ++_refCount;
}
//+---------------------------------------------------------------------------
//
// Release
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CCompartmentEventSink::Release()
{
LONG cr = --_refCount;
assert(_refCount >= 0);
if (_refCount == 0)
{
delete this;
}
return cr;
}
//+---------------------------------------------------------------------------
//
// OnChange
//
//----------------------------------------------------------------------------
STDAPI CCompartmentEventSink::OnChange(_In_ REFGUID guidCompartment)
{
return _pfnCallback(_pv, guidCompartment);
}
//+---------------------------------------------------------------------------
//
// _Advise
//
//----------------------------------------------------------------------------
HRESULT CCompartmentEventSink::_Advise(_In_ IUnknown *punk, _In_ REFGUID guidCompartment)
{
HRESULT hr = S_OK;
ITfCompartmentMgr* pCompartmentMgr = nullptr;
ITfSource* pSource = nullptr;
hr = punk->QueryInterface(IID_ITfCompartmentMgr, (void **)&pCompartmentMgr);
if (FAILED(hr))
{
return hr;
}
hr = pCompartmentMgr->GetCompartment(guidCompartment, &_pCompartment);
if (SUCCEEDED(hr))
{
hr = _pCompartment->QueryInterface(IID_ITfSource, (void **)&pSource);
if (SUCCEEDED(hr))
{
hr = pSource->AdviseSink(IID_ITfCompartmentEventSink, this, &_dwCookie);
pSource->Release();
}
}
pCompartmentMgr->Release();
return hr;
}
//+---------------------------------------------------------------------------
//
// _Unadvise
//
//----------------------------------------------------------------------------
HRESULT CCompartmentEventSink::_Unadvise()
{
HRESULT hr = S_OK;
ITfSource* pSource = nullptr;
hr = _pCompartment->QueryInterface(IID_ITfSource, (void **)&pSource);
if (SUCCEEDED(hr))
{
hr = pSource->UnadviseSink(_dwCookie);
pSource->Release();
}
_pCompartment->Release();
_pCompartment = nullptr;
_dwCookie = 0;
return hr;
}
+61
View File
@@ -0,0 +1,61 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
class CCompartment
{
public:
CCompartment(_In_ IUnknown *punk, TfClientId tfClientId, _In_ REFGUID guidCompartment);
~CCompartment();
HRESULT _GetCompartment(_Outptr_ ITfCompartment **ppCompartment);
HRESULT _GetCompartmentBOOL(_Out_ BOOL &flag);
HRESULT _SetCompartmentBOOL(_In_ BOOL flag);
HRESULT _GetCompartmentDWORD(_Out_ DWORD &dw);
HRESULT _SetCompartmentDWORD(_In_ DWORD dw);
HRESULT _ClearCompartment();
VOID _GetGUID(GUID *pguid)
{
*pguid = _guidCompartment;
}
private:
GUID _guidCompartment;
IUnknown* _punk;
TfClientId _tfClientId;
};
typedef HRESULT (*CESCALLBACK)(void *pv, REFGUID guidCompartment);
class CCompartmentEventSink : public ITfCompartmentEventSink
{
public:
CCompartmentEventSink(_In_ CESCALLBACK pfnCallback, _In_ void *pv);
~CCompartmentEventSink();
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// ITfCompartmentEventSink
STDMETHODIMP OnChange(_In_ REFGUID guid);
// function
HRESULT _Advise(_In_ IUnknown *punk, _In_ REFGUID guidCompartment);
HRESULT _Unadvise();
private:
ITfCompartment *_pCompartment;
DWORD _dwCookie;
CESCALLBACK _pfnCallback;
void *_pv;
LONG _refCount;
};
+377
View File
@@ -0,0 +1,377 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
#include "SampleIME.h"
#include "CompositionProcessorEngine.h"
//+---------------------------------------------------------------------------
//
// ITfCompositionSink::OnCompositionTerminated
//
// Callback for ITfCompositionSink. The system calls this method whenever
// someone other than this service ends a composition.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnCompositionTerminated(TfEditCookie ecWrite, _In_ ITfComposition *pComposition)
{
// Clear dummy composition
_RemoveDummyCompositionForComposing(ecWrite, pComposition);
// Clear display attribute and end composition, _EndComposition will release composition for us
ITfContext* pContext = _pContext;
if (pContext)
{
pContext->AddRef();
}
_EndComposition(_pContext);
_DeleteCandidateList(FALSE, pContext);
if (pContext)
{
pContext->Release();
pContext = nullptr;
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _IsComposing
//
//----------------------------------------------------------------------------
BOOL CSampleIME::_IsComposing()
{
return _pComposition != nullptr;
}
//+---------------------------------------------------------------------------
//
// _SetComposition
//
//----------------------------------------------------------------------------
void CSampleIME::_SetComposition(_In_ ITfComposition *pComposition)
{
_pComposition = pComposition;
}
//+---------------------------------------------------------------------------
//
// _AddComposingAndChar
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_AddComposingAndChar(TfEditCookie ec, _In_ ITfContext *pContext, _In_ CStringRange *pstrAddString)
{
HRESULT hr = S_OK;
ULONG fetched = 0;
TF_SELECTION tfSelection;
if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched) != S_OK || fetched == 0)
return S_FALSE;
//
// make range start to selection
//
ITfRange* pAheadSelection = nullptr;
hr = pContext->GetStart(ec, &pAheadSelection);
if (SUCCEEDED(hr))
{
hr = pAheadSelection->ShiftEndToRange(ec, tfSelection.range, TF_ANCHOR_START);
if (SUCCEEDED(hr))
{
ITfRange* pRange = nullptr;
BOOL exist_composing = _FindComposingRange(ec, pContext, pAheadSelection, &pRange);
_SetInputString(ec, pContext, pRange, pstrAddString, exist_composing);
if (pRange)
{
pRange->Release();
}
}
}
tfSelection.range->Release();
if (pAheadSelection)
{
pAheadSelection->Release();
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _AddCharAndFinalize
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_AddCharAndFinalize(TfEditCookie ec, _In_ ITfContext *pContext, _In_ CStringRange *pstrAddString)
{
HRESULT hr = E_FAIL;
ULONG fetched = 0;
TF_SELECTION tfSelection;
if ((hr = pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched)) != S_OK || fetched != 1)
return hr;
// we use SetText here instead of InsertTextAtSelection because we've already started a composition
// we don't want to the app to adjust the insertion point inside our composition
hr = tfSelection.range->SetText(ec, 0, pstrAddString->Get(), (LONG)pstrAddString->GetLength());
if (hr == S_OK)
{
// update the selection, we'll make it an insertion point just past
// the inserted text.
tfSelection.range->Collapse(ec, TF_ANCHOR_END);
pContext->SetSelection(ec, 1, &tfSelection);
}
tfSelection.range->Release();
return hr;
}
//+---------------------------------------------------------------------------
//
// _FindComposingRange
//
//----------------------------------------------------------------------------
BOOL CSampleIME::_FindComposingRange(TfEditCookie ec, _In_ ITfContext *pContext, _In_ ITfRange *pSelection, _Outptr_result_maybenull_ ITfRange **ppRange)
{
if (ppRange == nullptr)
{
return FALSE;
}
*ppRange = nullptr;
// find GUID_PROP_COMPOSING
ITfProperty* pPropComp = nullptr;
IEnumTfRanges* enumComp = nullptr;
HRESULT hr = pContext->GetProperty(GUID_PROP_COMPOSING, &pPropComp);
if (FAILED(hr) || pPropComp == nullptr)
{
return FALSE;
}
hr = pPropComp->EnumRanges(ec, &enumComp, pSelection);
if (FAILED(hr) || enumComp == nullptr)
{
pPropComp->Release();
return FALSE;
}
BOOL isCompExist = FALSE;
VARIANT var;
ULONG fetched = 0;
while (enumComp->Next(1, ppRange, &fetched) == S_OK && fetched == 1)
{
hr = pPropComp->GetValue(ec, *ppRange, &var);
if (hr == S_OK)
{
if (var.vt == VT_I4 && var.lVal != 0)
{
isCompExist = TRUE;
break;
}
}
(*ppRange)->Release();
*ppRange = nullptr;
}
pPropComp->Release();
enumComp->Release();
return isCompExist;
}
//+---------------------------------------------------------------------------
//
// _SetInputString
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_SetInputString(TfEditCookie ec, _In_ ITfContext *pContext, _Out_opt_ ITfRange *pRange, _In_ CStringRange *pstrAddString, BOOL exist_composing)
{
ITfRange* pRangeInsert = nullptr;
if (!exist_composing)
{
_InsertAtSelection(ec, pContext, pstrAddString, &pRangeInsert);
if (pRangeInsert == nullptr)
{
return S_OK;
}
pRange = pRangeInsert;
}
if (pRange != nullptr)
{
pRange->SetText(ec, 0, pstrAddString->Get(), (LONG)pstrAddString->GetLength());
}
_SetCompositionLanguage(ec, pContext);
_SetCompositionDisplayAttributes(ec, pContext, _gaDisplayAttributeInput);
// update the selection, we'll make it an insertion point just past
// the inserted text.
ITfRange* pSelection = nullptr;
TF_SELECTION sel;
if ((pRange != nullptr) && (pRange->Clone(&pSelection) == S_OK))
{
pSelection->Collapse(ec, TF_ANCHOR_END);
sel.range = pSelection;
sel.style.ase = TF_AE_NONE;
sel.style.fInterimChar = FALSE;
pContext->SetSelection(ec, 1, &sel);
pSelection->Release();
}
if (pRangeInsert)
{
pRangeInsert->Release();
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _InsertAtSelection
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_InsertAtSelection(TfEditCookie ec, _In_ ITfContext *pContext, _In_ CStringRange *pstrAddString, _Outptr_ ITfRange **ppCompRange)
{
ITfRange* rangeInsert = nullptr;
ITfInsertAtSelection* pias = nullptr;
HRESULT hr = S_OK;
if (ppCompRange == nullptr)
{
hr = E_INVALIDARG;
goto Exit;
}
*ppCompRange = nullptr;
hr = pContext->QueryInterface(IID_ITfInsertAtSelection, (void **)&pias);
if (FAILED(hr))
{
goto Exit;
}
hr = pias->InsertTextAtSelection(ec, TF_IAS_QUERYONLY, pstrAddString->Get(), (LONG)pstrAddString->GetLength(), &rangeInsert);
if ( FAILED(hr) || rangeInsert == nullptr)
{
rangeInsert = nullptr;
pias->Release();
goto Exit;
}
*ppCompRange = rangeInsert;
pias->Release();
hr = S_OK;
Exit:
return hr;
}
//+---------------------------------------------------------------------------
//
// _RemoveDummyCompositionForComposing
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_RemoveDummyCompositionForComposing(TfEditCookie ec, _In_ ITfComposition *pComposition)
{
HRESULT hr = S_OK;
ITfRange* pRange = nullptr;
if (pComposition)
{
hr = pComposition->GetRange(&pRange);
if (SUCCEEDED(hr))
{
pRange->SetText(ec, 0, nullptr, 0);
pRange->Release();
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// _SetCompositionLanguage
//
//----------------------------------------------------------------------------
BOOL CSampleIME::_SetCompositionLanguage(TfEditCookie ec, _In_ ITfContext *pContext)
{
HRESULT hr = S_OK;
BOOL ret = TRUE;
CCompositionProcessorEngine* pCompositionProcessorEngine = nullptr;
pCompositionProcessorEngine = _pCompositionProcessorEngine;
LANGID langidProfile = 0;
pCompositionProcessorEngine->GetLanguageProfile(&langidProfile);
ITfRange* pRangeComposition = nullptr;
ITfProperty* pLanguageProperty = nullptr;
// we need a range and the context it lives in
hr = _pComposition->GetRange(&pRangeComposition);
if (FAILED(hr))
{
ret = FALSE;
goto Exit;
}
// get our the language property
hr = pContext->GetProperty(GUID_PROP_LANGID, &pLanguageProperty);
if (FAILED(hr))
{
ret = FALSE;
goto Exit;
}
VARIANT var;
var.vt = VT_I4; // we're going to set DWORD
var.lVal = langidProfile;
hr = pLanguageProperty->SetValue(ec, pRangeComposition, &var);
if (FAILED(hr))
{
ret = FALSE;
goto Exit;
}
pLanguageProperty->Release();
pRangeComposition->Release();
Exit:
return ret;
}
File diff suppressed because it is too large. Load diff
+195
View File
@@ -0,0 +1,195 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "sal.h"
#include "TableDictionaryEngine.h"
#include "KeyHandlerEditSession.h"
#include "SampleIMEBaseStructure.h"
#include "FileMapping.h"
#include "Compartment.h"
#include "define.h"
class CCompositionProcessorEngine
{
public:
CCompositionProcessorEngine(void);
~CCompositionProcessorEngine(void);
BOOL SetupLanguageProfile(LANGID langid, REFGUID guidLanguageProfile, _In_ ITfThreadMgr *pThreadMgr, TfClientId tfClientId, BOOL isSecureMode, BOOL isComLessMode);
// Get language profile.
GUID GetLanguageProfile(LANGID *plangid)
{
*plangid = _langid;
return _guidProfile;
}
// Get locale
LCID GetLocale()
{
return MAKELCID(_langid, SORT_DEFAULT);
}
BOOL IsVirtualKeyNeed(UINT uCode, _In_reads_(1) WCHAR *pwch, BOOL fComposing, CANDIDATE_MODE candidateMode, BOOL hasCandidateWithWildcard, _Out_opt_ _KEYSTROKE_STATE *pKeyState);
BOOL AddVirtualKey(WCHAR wch);
void RemoveVirtualKey(DWORD_PTR dwIndex);
void PurgeVirtualKey();
DWORD_PTR GetVirtualKeyLength() { return _keystrokeBuffer.GetLength(); }
WCHAR GetVirtualKey(DWORD_PTR dwIndex);
void GetReadingStrings(_Inout_ CSampleImeArray<CStringRange> *pReadingStrings, _Out_ BOOL *pIsWildcardIncluded);
void GetCandidateList(_Inout_ CSampleImeArray<CCandidateListItem> *pCandidateList, BOOL isIncrementalWordSearch, BOOL isWildcardSearch);
void GetCandidateStringInConverted(CStringRange &searchString, _In_ CSampleImeArray<CCandidateListItem> *pCandidateList);
// Preserved key handler
void OnPreservedKey(REFGUID rguid, _Out_ BOOL *pIsEaten, _In_ ITfThreadMgr *pThreadMgr, TfClientId tfClientId);
// Punctuation
BOOL IsPunctuation(WCHAR wch);
WCHAR GetPunctuation(WCHAR wch);
BOOL IsDoubleSingleByte(WCHAR wch);
BOOL IsWildcard() { return _isWildcard; }
BOOL IsDisableWildcardAtFirst() { return _isDisableWildcardAtFirst; }
BOOL IsWildcardChar(WCHAR wch) { return ((IsWildcardOneChar(wch) || IsWildcardAllChar(wch)) ? TRUE : FALSE); }
BOOL IsWildcardOneChar(WCHAR wch) { return (wch==L'?' ? TRUE : FALSE); }
BOOL IsWildcardAllChar(WCHAR wch) { return (wch==L'*' ? TRUE : FALSE); }
BOOL IsMakePhraseFromText() { return _hasMakePhraseFromText; }
BOOL IsKeystrokeSort() { return _isKeystrokeSort; }
// Dictionary engine
BOOL IsDictionaryAvailable() { return (_pTableDictionaryEngine ? TRUE : FALSE); }
// Language bar control
void SetLanguageBarStatus(DWORD status, BOOL isSet);
void ConversionModeCompartmentUpdated(_In_ ITfThreadMgr *pThreadMgr);
void ShowAllLanguageBarIcons();
void HideAllLanguageBarIcons();
inline CCandidateRange *GetCandidateListIndexRange() { return &_candidateListIndexRange; }
inline UINT GetCandidateListPhraseModifier() { return _candidateListPhraseModifier; }
inline UINT GetCandidateWindowWidth() { return _candidateWndWidth; }
private:
void InitKeyStrokeTable();
BOOL InitLanguageBar(_In_ CLangBarItemButton *pLanguageBar, _In_ ITfThreadMgr *pThreadMgr, TfClientId tfClientId, REFGUID guidCompartment);
struct _KEYSTROKE;
BOOL IsVirtualKeyKeystrokeComposition(UINT uCode, _Out_opt_ _KEYSTROKE_STATE *pKeyState, KEYSTROKE_FUNCTION function);
BOOL IsVirtualKeyKeystrokeCandidate(UINT uCode, _In_ _KEYSTROKE_STATE *pKeyState, CANDIDATE_MODE candidateMode, _Out_ BOOL *pfRetCode, _In_ CSampleImeArray<_KEYSTROKE> *pKeystrokeMetric);
BOOL IsKeystrokeRange(UINT uCode, _Out_ _KEYSTROKE_STATE *pKeyState, CANDIDATE_MODE candidateMode);
void SetupKeystroke();
void SetupPreserved(_In_ ITfThreadMgr *pThreadMgr, TfClientId tfClientId);
void SetupConfiguration();
void SetupLanguageBar(_In_ ITfThreadMgr *pThreadMgr, TfClientId tfClientId, BOOL isSecureMode);
void SetKeystrokeTable(_Inout_ CSampleImeArray<_KEYSTROKE> *pKeystroke);
void SetupPunctuationPair();
void CreateLanguageBarButton(DWORD dwEnable, GUID guidLangBar, _In_z_ LPCWSTR pwszDescriptionValue, _In_z_ LPCWSTR pwszTooltipValue, DWORD dwOnIconIndex, DWORD dwOffIconIndex, _Outptr_result_maybenull_ CLangBarItemButton **ppLangBarItemButton, BOOL isSecureMode);
void SetInitialCandidateListRange();
void SetDefaultCandidateTextFont();
void InitializeSampleIMECompartment(_In_ ITfThreadMgr *pThreadMgr, TfClientId tfClientId);
class XPreservedKey;
void SetPreservedKey(const CLSID clsid, TF_PRESERVEDKEY & tfPreservedKey, _In_z_ LPCWSTR pwszDescription, _Out_ XPreservedKey *pXPreservedKey);
BOOL InitPreservedKey(_In_ XPreservedKey *pXPreservedKey, _In_ ITfThreadMgr *pThreadMgr, TfClientId tfClientId);
BOOL CheckShiftKeyOnly(_In_ CSampleImeArray<TF_PRESERVEDKEY> *pTSFPreservedKeyTable);
static HRESULT CompartmentCallback(_In_ void *pv, REFGUID guidCompartment);
void PrivateCompartmentsUpdated(_In_ ITfThreadMgr *pThreadMgr);
void KeyboardOpenCompartmentUpdated(_In_ ITfThreadMgr *pThreadMgr);
BOOL SetupDictionaryFile();
CFile* GetDictionaryFile();
private:
struct _KEYSTROKE
{
UINT VirtualKey;
UINT Modifiers;
KEYSTROKE_FUNCTION Function;
_KEYSTROKE()
{
VirtualKey = 0;
Modifiers = 0;
Function = FUNCTION_NONE;
}
};
_KEYSTROKE _keystrokeTable[26];
CTableDictionaryEngine* _pTableDictionaryEngine;
CStringRange _keystrokeBuffer;
BOOL _hasWildcardIncludedInKeystrokeBuffer;
LANGID _langid;
GUID _guidProfile;
TfClientId _tfClientId;
CSampleImeArray<_KEYSTROKE> _KeystrokeComposition;
CSampleImeArray<_KEYSTROKE> _KeystrokeCandidate;
CSampleImeArray<_KEYSTROKE> _KeystrokeCandidateWildcard;
CSampleImeArray<_KEYSTROKE> _KeystrokeCandidateSymbol;
CSampleImeArray<_KEYSTROKE> _KeystrokeSymbol;
// Preserved key data
class XPreservedKey
{
public:
XPreservedKey();
~XPreservedKey();
BOOL UninitPreservedKey(_In_ ITfThreadMgr *pThreadMgr);
public:
CSampleImeArray<TF_PRESERVEDKEY> TSFPreservedKeyTable;
GUID Guid;
LPCWSTR Description;
};
XPreservedKey _PreservedKey_IMEMode;
XPreservedKey _PreservedKey_DoubleSingleByte;
XPreservedKey _PreservedKey_Punctuation;
// Punctuation data
CSampleImeArray<CPunctuationPair> _PunctuationPair;
CSampleImeArray<CPunctuationNestPair> _PunctuationNestPair;
// Language bar data
CLangBarItemButton* _pLanguageBar_IMEMode;
CLangBarItemButton* _pLanguageBar_DoubleSingleByte;
CLangBarItemButton* _pLanguageBar_Punctuation;
// Compartment
CCompartment* _pCompartmentConversion;
CCompartmentEventSink* _pCompartmentConversionEventSink;
CCompartmentEventSink* _pCompartmentKeyboardOpenEventSink;
CCompartmentEventSink* _pCompartmentDoubleSingleByteEventSink;
CCompartmentEventSink* _pCompartmentPunctuationEventSink;
// Configuration data
BOOL _isWildcard : 1;
BOOL _isDisableWildcardAtFirst : 1;
BOOL _hasMakePhraseFromText : 1;
BOOL _isKeystrokeSort : 1;
BOOL _isComLessMode : 1;
CCandidateRange _candidateListIndexRange;
UINT _candidateListPhraseModifier;
UINT _candidateWndWidth;
CFileMapping* _pDictionaryFile;
static const int OUT_OF_FILE_INDEX = -1;
};
+48
View File
@@ -0,0 +1,48 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "resource.h"
#define TEXTSERVICE_MODEL L"Apartment"
#define TEXTSERVICE_LANGID MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED)
#define TEXTSERVICE_ICON_INDEX -IDIS_SAMPLEIME
#define TEXTSERVICE_DIC L"SampleIMESimplifiedQuanPin.txt"
#define IME_MODE_ON_ICON_INDEX IDI_IME_MODE_ON
#define IME_MODE_OFF_ICON_INDEX IDI_IME_MODE_OFF
#define IME_DOUBLE_ON_INDEX IDI_DOUBLE_SINGLE_BYTE_ON
#define IME_DOUBLE_OFF_INDEX IDI_DOUBLE_SINGLE_BYTE_OFF
#define IME_PUNCTUATION_ON_INDEX IDI_PUNCTUATION_ON
#define IME_PUNCTUATION_OFF_INDEX IDI_PUNCTUATION_OFF
#define SAMPLEIME_FONT_DEFAULT L"Microsoft YaHei UI"
//---------------------------------------------------------------------
// defined Candidated Window
//---------------------------------------------------------------------
#define CANDWND_ROW_WIDTH (30)
#define CANDWND_BORDER_COLOR (RGB(0x00, 0x00, 0x00))
#define CANDWND_BORDER_WIDTH (2)
#define CANDWND_NUM_COLOR (RGB(0xB4, 0xB4, 0xB4))
#define CANDWND_SELECTED_ITEM_COLOR (RGB(0xFF, 0xFF, 0xFF))
#define CANDWND_SELECTED_BK_COLOR (RGB(0xA6, 0xA6, 0x00))
#define CANDWND_ITEM_COLOR (RGB(0x00, 0x00, 0x00))
//---------------------------------------------------------------------
// defined modifier
//---------------------------------------------------------------------
#define _TF_MOD_ON_KEYUP_SHIFT_ONLY (0x00010000 | TF_MOD_ON_KEYUP)
#define _TF_MOD_ON_KEYUP_CONTROL_ONLY (0x00020000 | TF_MOD_ON_KEYUP)
#define _TF_MOD_ON_KEYUP_ALT_ONLY (0x00040000 | TF_MOD_ON_KEYUP)
#define CAND_WIDTH (13) // * tmMaxCharWidth
//---------------------------------------------------------------------
// string length of CLSID
//---------------------------------------------------------------------
#define CLSID_STRLEN (38) // strlen("{xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx}")
+3
View File
@@ -0,0 +1,3 @@
# The *.txt files in this directory are UTF-16-encoded and should
# therefore be treated as pure binary data.
*.txt binary
Binary file not shown.
+222
View File
@@ -0,0 +1,222 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "DictionaryParser.h"
#include "SampleIMEBaseStructure.h"
//---------------------------------------------------------------------
//
// ctor
//
//---------------------------------------------------------------------
CDictionaryParser::CDictionaryParser(LCID locale)
{
_locale = locale;
}
//---------------------------------------------------------------------
//
// dtor
//
//---------------------------------------------------------------------
CDictionaryParser::~CDictionaryParser()
{
}
//---------------------------------------------------------------------
//
// ParseLine
//
// dwBufLen - in character count
//
//---------------------------------------------------------------------
BOOL CDictionaryParser::ParseLine(_In_reads_(dwBufLen) LPCWSTR pwszBuffer, DWORD_PTR dwBufLen, _Out_ CParserStringRange *psrgKeyword, _Inout_opt_ CSampleImeArray<CParserStringRange> *pValue)
{
LPCWSTR pwszKeyWordDelimiter = nullptr;
pwszKeyWordDelimiter = GetToken(pwszBuffer, dwBufLen, Global::KeywordDelimiter, psrgKeyword);
if (!(pwszKeyWordDelimiter))
{
return FALSE; // End of file
}
dwBufLen -= (pwszKeyWordDelimiter - pwszBuffer);
pwszBuffer = pwszKeyWordDelimiter + 1;
dwBufLen--;
// Get value.
if (pValue)
{
if (dwBufLen)
{
CParserStringRange* psrgValue = pValue->Append();
if (!psrgValue)
{
return FALSE;
}
psrgValue->Set(pwszBuffer, dwBufLen);
RemoveWhiteSpaceFromBegin(psrgValue);
RemoveWhiteSpaceFromEnd(psrgValue);
RemoveStringDelimiter(psrgValue);
}
}
return TRUE;
}
//---------------------------------------------------------------------
//
// GetToken
//
// dwBufLen - in character count
//
// return - pointer of delimiter which specified chDelimiter
//
//---------------------------------------------------------------------
_Ret_maybenull_
LPCWSTR CDictionaryParser::GetToken(_In_reads_(dwBufLen) LPCWSTR pwszBuffer, DWORD_PTR dwBufLen, _In_ const WCHAR chDelimiter, _Out_ CParserStringRange *psrgValue)
{
WCHAR ch = '\0';
psrgValue->Set(pwszBuffer, dwBufLen);
ch = *pwszBuffer;
while ((ch) && (ch != chDelimiter) && dwBufLen)
{
dwBufLen--;
pwszBuffer++;
if (ch == Global::StringDelimiter)
{
while (*pwszBuffer && (*pwszBuffer != Global::StringDelimiter) && dwBufLen)
{
dwBufLen--;
pwszBuffer++;
}
if (*pwszBuffer && dwBufLen)
{
dwBufLen--;
pwszBuffer++;
}
else
{
return nullptr;
}
}
ch = *pwszBuffer;
}
if (*pwszBuffer && dwBufLen)
{
LPCWSTR pwszStart = psrgValue->Get();
psrgValue->Set(pwszStart, pwszBuffer - pwszStart);
RemoveWhiteSpaceFromBegin(psrgValue);
RemoveWhiteSpaceFromEnd(psrgValue);
RemoveStringDelimiter(psrgValue);
return pwszBuffer;
}
RemoveWhiteSpaceFromBegin(psrgValue);
RemoveWhiteSpaceFromEnd(psrgValue);
RemoveStringDelimiter(psrgValue);
return nullptr;
}
//---------------------------------------------------------------------
//
// RemoveWhiteSpaceFromBegin
// RemoveWhiteSpaceFromEnd
// RemoveStringDelimiter
//
//---------------------------------------------------------------------
BOOL CDictionaryParser::RemoveWhiteSpaceFromBegin(_Inout_opt_ CStringRange *pString)
{
DWORD_PTR dwIndexTrace = 0; // in char
if (pString == nullptr)
{
return FALSE;
}
if (SkipWhiteSpace(_locale, pString->Get(), pString->GetLength(), &dwIndexTrace) != S_OK)
{
return FALSE;
}
pString->Set(pString->Get() + dwIndexTrace, pString->GetLength() - dwIndexTrace);
return TRUE;
}
BOOL CDictionaryParser::RemoveWhiteSpaceFromEnd(_Inout_opt_ CStringRange *pString)
{
if (pString == nullptr)
{
return FALSE;
}
DWORD_PTR dwTotalBufLen = pString->GetLength();
LPCWSTR pwszEnd = pString->Get() + dwTotalBufLen - 1;
while (dwTotalBufLen && (IsSpace(_locale, *pwszEnd) || *pwszEnd == L'\r' || *pwszEnd == L'\n'))
{
pwszEnd--;
dwTotalBufLen--;
}
pString->Set(pString->Get(), dwTotalBufLen);
return TRUE;
}
BOOL CDictionaryParser::RemoveStringDelimiter(_Inout_opt_ CStringRange *pString)
{
if (pString == nullptr)
{
return FALSE;
}
if (pString->GetLength() >= 2)
{
if ((*pString->Get() == Global::StringDelimiter) && (*(pString->Get()+pString->GetLength()-1) == Global::StringDelimiter))
{
pString->Set(pString->Get()+1, pString->GetLength()-2);
return TRUE;
}
}
return FALSE;
}
//---------------------------------------------------------------------
//
// GetOneLine
//
// dwBufLen - in character count
//
//---------------------------------------------------------------------
DWORD_PTR CDictionaryParser::GetOneLine(_In_z_ LPCWSTR pwszBuffer, DWORD_PTR dwBufLen)
{
DWORD_PTR dwIndexTrace = 0; // in char
if (FAILED(FindChar(L'\r', pwszBuffer, dwBufLen, &dwIndexTrace)))
{
if (FAILED(FindChar(L'\0', pwszBuffer, dwBufLen, &dwIndexTrace)))
{
return dwBufLen;
}
}
return dwIndexTrace;
}
+50
View File
@@ -0,0 +1,50 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "Globals.h"
//////////////////////////////////////////////////////////////////////
//
class CParserStringRange : public CStringRange
{
public:
CParserStringRange() : CStringRange()
{
_fEscapeIncluded = FALSE;
}
BOOL _fEscapeIncluded; // flag. This string range included escape sequence.
};
//////////////////////////////////////////////////////////////////////
//
class CDictionaryParser
{
public:
CDictionaryParser(LCID locale);
virtual ~CDictionaryParser();
BOOL ParseLine(_In_reads_(dwBufLen) LPCWSTR pwszBuffer, DWORD_PTR dwBufLen, _Out_ CParserStringRange *psrgKeyword, _Inout_opt_ CSampleImeArray<CParserStringRange> *pValue = nullptr);
// dwBufLen - in character count
_Ret_maybenull_
LPCWSTR GetToken(_In_reads_(dwBufLen) LPCWSTR pwszBuffer, DWORD_PTR dwBufLen, _In_ const WCHAR chDelimiter, _Out_ CParserStringRange *srgKeyWord);
protected:
BOOL RemoveWhiteSpaceFromBegin(_Inout_opt_ CStringRange *pString);
BOOL RemoveWhiteSpaceFromEnd(_Inout_opt_ CStringRange *pString);
BOOL RemoveStringDelimiter(_Inout_opt_ CStringRange *pString);
DWORD_PTR GetOneLine(_In_z_ LPCWSTR pwszBuffer, DWORD_PTR dwBufLen);
LCID _locale; // used for CompareString
};
+250
View File
@@ -0,0 +1,250 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "DictionarySearch.h"
#include "SampleIMEBaseStructure.h"
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CDictionarySearch::CDictionarySearch(LCID locale, _In_ CFile *pFile, _In_ CStringRange *pSearchKeyCode) : CDictionaryParser(locale)
{
_pFile = pFile;
_pSearchKeyCode = pSearchKeyCode;
_charIndex = 0;
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CDictionarySearch::~CDictionarySearch()
{
}
//+---------------------------------------------------------------------------
//
// FindPhrase
//
//----------------------------------------------------------------------------
BOOL CDictionarySearch::FindPhrase(_Out_ CDictionaryResult **ppdret)
{
return FindWorker(FALSE, ppdret, FALSE); // NO WILDCARD
}
//+---------------------------------------------------------------------------
//
// FindPhraseForWildcard
//
//----------------------------------------------------------------------------
BOOL CDictionarySearch::FindPhraseForWildcard(_Out_ CDictionaryResult **ppdret)
{
return FindWorker(FALSE, ppdret, TRUE); // Wildcard
}
//+---------------------------------------------------------------------------
//
// FindConvertedStringForWildcard
//
//----------------------------------------------------------------------------
BOOL CDictionarySearch::FindConvertedStringForWildcard(CDictionaryResult **ppdret)
{
return FindWorker(TRUE, ppdret, TRUE); // Wildcard
}
//+---------------------------------------------------------------------------
//
// FindWorker
//
//----------------------------------------------------------------------------
BOOL CDictionarySearch::FindWorker(BOOL isTextSearch, _Out_ CDictionaryResult **ppdret, BOOL isWildcardSearch)
{
DWORD_PTR dwTotalBufLen = GetBufferInWCharLength(); // in char
if (dwTotalBufLen == 0)
{
return FALSE;
}
const WCHAR *pwch = GetBufferInWChar();
DWORD_PTR indexTrace = 0; // in char
*ppdret = nullptr;
BOOL isFound = FALSE;
DWORD_PTR bufLenOneLine = 0;
TryAgain:
bufLenOneLine = GetOneLine(&pwch[indexTrace], dwTotalBufLen);
if (bufLenOneLine == 0)
{
goto FindNextLine;
}
else
{
CParserStringRange keyword;
DWORD_PTR bufLen = 0;
LPWSTR pText = nullptr;
if (!ParseLine(&pwch[indexTrace], bufLenOneLine, &keyword))
{
return FALSE; // error
}
if (!isTextSearch)
{
// Compare Dictionary key code and input key code
if (!isWildcardSearch)
{
if (CStringRange::Compare(_locale, &keyword, _pSearchKeyCode) != CSTR_EQUAL)
{
if (bufLen)
{
delete [] pText;
}
goto FindNextLine;
}
}
else
{
// Wildcard search
if (!CStringRange::WildcardCompare(_locale, _pSearchKeyCode, &keyword))
{
if (bufLen)
{
delete [] pText;
}
goto FindNextLine;
}
}
}
else
{
// Compare Dictionary converted string and input string
CSampleImeArray<CParserStringRange> convertedStrings;
if (!ParseLine(&pwch[indexTrace], bufLenOneLine, &keyword, &convertedStrings))
{
if (bufLen)
{
delete [] pText;
}
return FALSE;
}
if (convertedStrings.Count() == 1)
{
CStringRange* pTempString = convertedStrings.GetAt(0);
if (!isWildcardSearch)
{
if (CStringRange::Compare(_locale, pTempString, _pSearchKeyCode) != CSTR_EQUAL)
{
if (bufLen)
{
delete [] pText;
}
goto FindNextLine;
}
}
else
{
// Wildcard search
if (!CStringRange::WildcardCompare(_locale, _pSearchKeyCode, pTempString))
{
if (bufLen)
{
delete [] pText;
}
goto FindNextLine;
}
}
}
else
{
if (bufLen)
{
delete [] pText;
}
goto FindNextLine;
}
}
if (bufLen)
{
delete [] pText;
}
// Prepare return's CDictionaryResult
*ppdret = new (std::nothrow) CDictionaryResult();
if (!*ppdret)
{
return FALSE;
}
CSampleImeArray<CParserStringRange> valueStrings;
if (!ParseLine(&pwch[indexTrace], bufLenOneLine, &keyword, &valueStrings))
{
if (*ppdret)
{
delete *ppdret;
*ppdret = nullptr;
}
return FALSE;
}
(*ppdret)->_FindKeyCode = keyword;
(*ppdret)->_SearchKeyCode = *_pSearchKeyCode;
for (UINT i = 0; i < valueStrings.Count(); i++)
{
CStringRange* findPhrase = (*ppdret)->_FindPhraseList.Append();
if (findPhrase)
{
*findPhrase = *valueStrings.GetAt(i);
}
}
// Seek to next line
isFound = TRUE;
}
FindNextLine:
dwTotalBufLen -= bufLenOneLine;
if (dwTotalBufLen == 0)
{
indexTrace += bufLenOneLine;
_charIndex += indexTrace;
if (!isFound && *ppdret)
{
delete *ppdret;
*ppdret = nullptr;
}
return (isFound ? TRUE : FALSE); // End of file
}
indexTrace += bufLenOneLine;
if (pwch[indexTrace] == L'\r' || pwch[indexTrace] == L'\n' || pwch[indexTrace] == L'\0')
{
bufLenOneLine = 1;
goto FindNextLine;
}
if (isFound)
{
_charIndex += indexTrace;
return TRUE;
}
goto TryAgain;
}
+76
View File
@@ -0,0 +1,76 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "File.h"
#include "DictionaryParser.h"
#include "SampleIMEBaseStructure.h"
class CDictionaryResult;
//////////////////////////////////////////////////////////////////////
//
// CDictionarySearch declaration.
//
//////////////////////////////////////////////////////////////////////
class CDictionarySearch : CDictionaryParser
{
public:
CDictionarySearch(LCID locale, _In_ CFile *pFile, _In_ CStringRange *pSearchKeyCode);
virtual ~CDictionarySearch();
BOOL FindPhrase(_Out_ CDictionaryResult **ppdret);
BOOL FindPhraseForWildcard(_Out_ CDictionaryResult **ppdret);
BOOL FindConvertedStringForWildcard(CDictionaryResult **ppdret);
CStringRange* _pSearchKeyCode;
DWORD_PTR _charIndex; // in character. Always point start of line in dictionary file.
private:
BOOL FindWorker(BOOL isTextSearch, _Out_ CDictionaryResult **ppdret, BOOL isWildcardSearch);
DWORD_PTR GetBufferInWCharLength()
{
return (_pFile->GetFileSize() / sizeof(WCHAR)) - _charIndex; // in char count as a returned length.
}
const WCHAR* GetBufferInWChar()
{
return _pFile->GetReadBufferPointer() + _charIndex;
}
CFile* _pFile;
};
//////////////////////////////////////////////////////////////////////
//
// CDictionaryResult declaration.
//
//////////////////////////////////////////////////////////////////////
class CDictionaryResult
{
public:
CDictionaryResult() { }
virtual ~CDictionaryResult() { }
CDictionaryResult& operator=(CDictionaryResult& dret)
{
_FindKeyCode = dret._FindKeyCode;
_FindPhraseList = dret._FindPhraseList;
return *this;
}
CStringRange _SearchKeyCode;
CStringRange _FindKeyCode;
CSampleImeArray<CStringRange> _FindPhraseList;
};
+115
View File
@@ -0,0 +1,115 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "globals.h"
#include "SampleIME.h"
//+---------------------------------------------------------------------------
//
// _ClearCompositionDisplayAttributes
//
//----------------------------------------------------------------------------
void CSampleIME::_ClearCompositionDisplayAttributes(TfEditCookie ec, _In_ ITfContext *pContext)
{
ITfRange* pRangeComposition = nullptr;
ITfProperty* pDisplayAttributeProperty = nullptr;
// get the compositon range.
if (FAILED(_pComposition->GetRange(&pRangeComposition)))
{
return;
}
// get our the display attribute property
if (SUCCEEDED(pContext->GetProperty(GUID_PROP_ATTRIBUTE, &pDisplayAttributeProperty)))
{
// clear the value over the range
pDisplayAttributeProperty->Clear(ec, pRangeComposition);
pDisplayAttributeProperty->Release();
}
pRangeComposition->Release();
}
//+---------------------------------------------------------------------------
//
// _SetCompositionDisplayAttributes
//
//----------------------------------------------------------------------------
BOOL CSampleIME::_SetCompositionDisplayAttributes(TfEditCookie ec, _In_ ITfContext *pContext, TfGuidAtom gaDisplayAttribute)
{
ITfRange* pRangeComposition = nullptr;
ITfProperty* pDisplayAttributeProperty = nullptr;
HRESULT hr = S_OK;
// we need a range and the context it lives in
hr = _pComposition->GetRange(&pRangeComposition);
if (FAILED(hr))
{
return FALSE;
}
hr = E_FAIL;
// get our the display attribute property
if (SUCCEEDED(pContext->GetProperty(GUID_PROP_ATTRIBUTE, &pDisplayAttributeProperty)))
{
VARIANT var;
// set the value over the range
// the application will use this guid atom to lookup the acutal rendering information
var.vt = VT_I4; // we're going to set a TfGuidAtom
var.lVal = gaDisplayAttribute;
hr = pDisplayAttributeProperty->SetValue(ec, pRangeComposition, &var);
pDisplayAttributeProperty->Release();
}
pRangeComposition->Release();
return (hr == S_OK);
}
//+---------------------------------------------------------------------------
//
// _InitDisplayAttributeGuidAtom
//
// Because it's expensive to map our display attribute GUID to a TSF
// TfGuidAtom, we do it once when Activate is called.
//----------------------------------------------------------------------------
BOOL CSampleIME::_InitDisplayAttributeGuidAtom()
{
ITfCategoryMgr* pCategoryMgr = nullptr;
HRESULT hr = CoCreateInstance(CLSID_TF_CategoryMgr, nullptr, CLSCTX_INPROC_SERVER, IID_ITfCategoryMgr, (void**)&pCategoryMgr);
if (FAILED(hr))
{
return FALSE;
}
// register the display attribute for input text.
hr = pCategoryMgr->RegisterGUID(Global::SampleIMEGuidDisplayAttributeInput, &_gaDisplayAttributeInput);
if (FAILED(hr))
{
goto Exit;
}
// register the display attribute for the converted text.
hr = pCategoryMgr->RegisterGUID(Global::SampleIMEGuidDisplayAttributeConverted, &_gaDisplayAttributeConverted);
if (FAILED(hr))
{
goto Exit;
}
Exit:
pCategoryMgr->Release();
return (hr == S_OK);
}
+227
View File
@@ -0,0 +1,227 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "globals.h"
#include "DisplayAttributeInfo.h"
#include "TfInputProcessorProfile.h"
//+---------------------------------------------------------------------------
//
// The registry key and values
//
//----------------------------------------------------------------------------
// the registry values of the custmized display attributes
const WCHAR CDisplayAttributeInfoInput::_s_szValueName[] = L"DisplayAttributeInput";
const WCHAR CDisplayAttributeInfoConverted::_s_szValueName[] = L"DisplayAttributeConverted";
// The descriptions
const WCHAR CDisplayAttributeInfoInput::_s_szDescription[] = L"Sample IME Text Service Display Attribute Input";
const WCHAR CDisplayAttributeInfoConverted::_s_szDescription[] = L"Sample IME Text Service Display Attribute Converted";
//+---------------------------------------------------------------------------
//
// DisplayAttribute
//
//----------------------------------------------------------------------------
const TF_DISPLAYATTRIBUTE CDisplayAttributeInfoInput::_s_DisplayAttribute =
{
{ TF_CT_COLORREF, RGB(0, 103,206) }, // text color
{ TF_CT_NONE, 0 }, // background color (TF_CT_NONE => app default)
TF_LS_DOT, // underline style
FALSE, // underline boldness
{ TF_CT_COLORREF, RGB(0, 103,206) }, // underline color
TF_ATTR_INPUT // attribute info
};
const TF_DISPLAYATTRIBUTE CDisplayAttributeInfoConverted::_s_DisplayAttribute =
{
{ TF_CT_COLORREF, RGB(255, 255, 255) }, // text color
{ TF_CT_COLORREF, RGB( 0, 255, 255) }, // background color (TF_CT_NONE => app default)
TF_LS_NONE, // underline style
FALSE, // underline boldness
{ TF_CT_NONE, 0 }, // underline color
TF_ATTR_TARGET_CONVERTED // attribute info
};
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CDisplayAttributeInfo::CDisplayAttributeInfo()
{
DllAddRef();
_pguid = nullptr;
_pDisplayAttribute = nullptr;
_pValueName = nullptr;
_refCount = 1;
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CDisplayAttributeInfo::~CDisplayAttributeInfo()
{
DllRelease();
}
//+---------------------------------------------------------------------------
//
// QueryInterface
//
//----------------------------------------------------------------------------
STDAPI CDisplayAttributeInfo::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
return E_INVALIDARG;
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_ITfDisplayAttributeInfo))
{
*ppvObj = (ITfDisplayAttributeInfo *)this;
}
if (*ppvObj)
{
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//+---------------------------------------------------------------------------
//
// AddRef
//
//----------------------------------------------------------------------------
ULONG CDisplayAttributeInfo::AddRef(void)
{
return ++_refCount;
}
//+---------------------------------------------------------------------------
//
// Release
//
//----------------------------------------------------------------------------
ULONG CDisplayAttributeInfo::Release(void)
{
LONG cr = --_refCount;
assert(_refCount >= 0);
if (_refCount == 0)
{
delete this;
}
return cr;
}
//+---------------------------------------------------------------------------
//
// ITfDisplayAttributeInfo::GetGUID
//
//----------------------------------------------------------------------------
STDAPI CDisplayAttributeInfo::GetGUID(_Out_ GUID *pguid)
{
if (pguid == nullptr)
return E_INVALIDARG;
if (_pguid == nullptr)
return E_FAIL;
*pguid = *_pguid;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfDisplayAttributeInfo::GetDescription
//
//----------------------------------------------------------------------------
STDAPI CDisplayAttributeInfo::GetDescription(_Out_ BSTR *pbstrDesc)
{
BSTR tempDesc;
if (pbstrDesc == nullptr)
{
return E_INVALIDARG;
}
*pbstrDesc = nullptr;
if ((tempDesc = SysAllocString(_pDescription)) == nullptr)
{
return E_OUTOFMEMORY;
}
*pbstrDesc = tempDesc;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfDisplayAttributeInfo::GetAttributeInfo
//
//----------------------------------------------------------------------------
STDAPI CDisplayAttributeInfo::GetAttributeInfo(_Out_ TF_DISPLAYATTRIBUTE *ptfDisplayAttr)
{
if (ptfDisplayAttr == nullptr)
{
return E_INVALIDARG;
}
// return the default display attribute.
*ptfDisplayAttr = *_pDisplayAttribute;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfDisplayAttributeInfo::SetAttributeInfo
//
//----------------------------------------------------------------------------
STDAPI CDisplayAttributeInfo::SetAttributeInfo(_In_ const TF_DISPLAYATTRIBUTE *ptfDisplayAttr)
{
ptfDisplayAttr;
return E_NOTIMPL;
}
//+---------------------------------------------------------------------------
//
// ITfDisplayAttributeInfo::Reset
//
//----------------------------------------------------------------------------
STDAPI CDisplayAttributeInfo::Reset()
{
return SetAttributeInfo(_pDisplayAttribute);
}
+87
View File
@@ -0,0 +1,87 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
//+---------------------------------------------------------------------------
//
// CDisplayAttributeInfo class
//
//----------------------------------------------------------------------------
class CDisplayAttributeInfo : public ITfDisplayAttributeInfo
{
public:
CDisplayAttributeInfo();
~CDisplayAttributeInfo();
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// ITfDisplayAttributeInfo
STDMETHODIMP GetGUID(_Out_ GUID *pguid);
STDMETHODIMP GetDescription(_Out_ BSTR *pbstrDesc);
STDMETHODIMP GetAttributeInfo(_Out_ TF_DISPLAYATTRIBUTE *pTSFDisplayAttr);
STDMETHODIMP SetAttributeInfo(_In_ const TF_DISPLAYATTRIBUTE *ptfDisplayAttr);
STDMETHODIMP Reset();
protected:
const GUID* _pguid;
const TF_DISPLAYATTRIBUTE* _pDisplayAttribute;
const WCHAR* _pDescription;
const WCHAR* _pValueName;
private:
LONG _refCount; // COM ref count
};
//+---------------------------------------------------------------------------
//
// CDisplayAttributeInfoInput class
//
//----------------------------------------------------------------------------
class CDisplayAttributeInfoInput : public CDisplayAttributeInfo
{
public:
CDisplayAttributeInfoInput()
{
_pguid = &Global::SampleIMEGuidDisplayAttributeInput;
_pDisplayAttribute = &_s_DisplayAttribute;
_pDescription = _s_szDescription;
_pValueName = _s_szValueName;
}
static const TF_DISPLAYATTRIBUTE _s_DisplayAttribute;
static const WCHAR _s_szDescription[];
static const WCHAR _s_szValueName[];
};
//+---------------------------------------------------------------------------
//
// CDisplayAttributeInfoConverted class
//
//----------------------------------------------------------------------------
class CDisplayAttributeInfoConverted : public CDisplayAttributeInfo
{
public:
CDisplayAttributeInfoConverted()
{
_pguid = &Global::SampleIMEGuidDisplayAttributeConverted;
_pDisplayAttribute = &_s_DisplayAttribute;
_pDescription = _s_szDescription;
_pValueName = _s_szValueName;
}
static const TF_DISPLAYATTRIBUTE _s_DisplayAttribute;
static const WCHAR _s_szDescription[];
static const WCHAR _s_szValueName[];
};
+81
View File
@@ -0,0 +1,81 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "globals.h"
#include "SampleIME.h"
#include "DisplayAttributeInfo.h"
#include "EnumDisplayAttributeInfo.h"
//+---------------------------------------------------------------------------
//
// ITfDisplayAttributeProvider::EnumDisplayAttributeInfo
//
//----------------------------------------------------------------------------
STDAPI CSampleIME::EnumDisplayAttributeInfo(__RPC__deref_out_opt IEnumTfDisplayAttributeInfo **ppEnum)
{
CEnumDisplayAttributeInfo* pAttributeEnum = nullptr;
if (ppEnum == nullptr)
{
return E_INVALIDARG;
}
*ppEnum = nullptr;
pAttributeEnum = new (std::nothrow) CEnumDisplayAttributeInfo();
if (pAttributeEnum == nullptr)
{
return E_OUTOFMEMORY;
}
*ppEnum = pAttributeEnum;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfDisplayAttributeProvider::GetDisplayAttributeInfo
//
//----------------------------------------------------------------------------
STDAPI CSampleIME::GetDisplayAttributeInfo(__RPC__in REFGUID guidInfo, __RPC__deref_out_opt ITfDisplayAttributeInfo **ppInfo)
{
if (ppInfo == nullptr)
{
return E_INVALIDARG;
}
*ppInfo = nullptr;
// Which display attribute GUID?
if (IsEqualGUID(guidInfo, Global::SampleIMEGuidDisplayAttributeInput))
{
*ppInfo = new (std::nothrow) CDisplayAttributeInfoInput();
if ((*ppInfo) == nullptr)
{
return E_OUTOFMEMORY;
}
}
else if (IsEqualGUID(guidInfo, Global::SampleIMEGuidDisplayAttributeConverted))
{
*ppInfo = new (std::nothrow) CDisplayAttributeInfoConverted();
if ((*ppInfo) == nullptr)
{
return E_OUTOFMEMORY;
}
}
else
{
return E_INVALIDARG;
}
return S_OK;
}
+43
View File
@@ -0,0 +1,43 @@
//////////////////////////////////////////////////////////////////////
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// DisplayString.h
//
// CDisplayString declaration.
//
//////////////////////////////////////////////////////////////////////
#pragma once
#include "StringRange.h"
#include "PointerArray.h"
class CDisplayString
{
public:
CDisplayString() { }
~CDisplayString() { }
int Count() { }
// VOID SetDisplayString(int iIndex, WCHAR* pchText, USHORT cchMax, TF_DISPLAYATTRIBUTE tfDisplayAttribute) { }
// VOID GetDisplayString(int iIndex, WCHAR* pchText, USHORT cchMax, USHORT* pch, TF_DISPLAYATTRIBUTE tfDisplayAttribute) { }
VOID SetLogicalFont(LOGFONTW LogFont) { }
VOID GetLogicalFont(LOGFONTW* pLogFont) { }
private:
//typedef struct _DISPLAY_STRING {
// CStringRange _StringRange; // Unicode string.
// // Length and MaximumLength is in character count.
// // Buffer doesn't add zero terminate.
// TF_DISPLAYATTRIBUTE _tfDisplayAttribute; // Display attribute for each array.
//} DISPLAY_STRING;
//
// Array of DISPLAY_STRING
//
//CPointerArray<DISPLAY_STRING> _pDisplayString;
// Logical font
LOGFONTW _logfont;
};
+54
View File
@@ -0,0 +1,54 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
//+---------------------------------------------------------------------------
//
// DllMain
//
//----------------------------------------------------------------------------
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID pvReserved)
{
pvReserved;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
Global::dllInstanceHandle = hInstance;
if (!InitializeCriticalSectionAndSpinCount(&Global::CS, 0))
{
return FALSE;
}
if (!Global::RegisterWindowClass()) {
return FALSE;
}
break;
case DLL_PROCESS_DETACH:
DeleteCriticalSection(&Global::CS);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
+99
View File
@@ -0,0 +1,99 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "EditSession.h"
#include "SampleIME.h"
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CEditSessionBase::CEditSessionBase(_In_ CSampleIME *pTextService, _In_ ITfContext *pContext)
{
_refCount = 1;
_pContext = pContext;
_pContext->AddRef();
_pTextService = pTextService;
_pTextService->AddRef();
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CEditSessionBase::~CEditSessionBase()
{
_pContext->Release();
_pTextService->Release();
}
//+---------------------------------------------------------------------------
//
// QueryInterface
//
//----------------------------------------------------------------------------
STDAPI CEditSessionBase::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
{
return E_INVALIDARG;
}
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_ITfEditSession))
{
*ppvObj = (ITfLangBarItemButton *)this;
}
if (*ppvObj)
{
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//+---------------------------------------------------------------------------
//
// AddRef
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CEditSessionBase::AddRef(void)
{
return ++_refCount;
}
//+---------------------------------------------------------------------------
//
// Release
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CEditSessionBase::Release(void)
{
LONG cr = --_refCount;
assert(_refCount >= 0);
if (_refCount == 0)
{
delete this;
}
return cr;
}
+33
View File
@@ -0,0 +1,33 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
class CSampleIME;
class CEditSessionBase : public ITfEditSession
{
public:
CEditSessionBase(_In_ CSampleIME *pTextService, _In_ ITfContext *pContext);
virtual ~CEditSessionBase();
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// ITfEditSession
virtual STDMETHODIMP DoEditSession(TfEditCookie ec) = 0;
protected:
ITfContext *_pContext;
CSampleIME *_pTextService;
private:
LONG _refCount; // COM ref count
};
+98
View File
@@ -0,0 +1,98 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
#include "EditSession.h"
#include "SampleIME.h"
//////////////////////////////////////////////////////////////////////
//
// ITfEditSession
// CEditSessionBase
// CEndCompositionEditSession class
//
//////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// CEndCompositionEditSession
//
//----------------------------------------------------------------------------
class CEndCompositionEditSession : public CEditSessionBase
{
public:
CEndCompositionEditSession(_In_ CSampleIME *pTextService, _In_ ITfContext *pContext) : CEditSessionBase(pTextService, pContext)
{
}
// ITfEditSession
STDMETHODIMP DoEditSession(TfEditCookie ec)
{
_pTextService->_TerminateComposition(ec, _pContext, TRUE);
return S_OK;
}
};
//////////////////////////////////////////////////////////////////////
//
// CSampleIME class
//
//////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// _TerminateComposition
//
//----------------------------------------------------------------------------
void CSampleIME::_TerminateComposition(TfEditCookie ec, _In_ ITfContext *pContext, BOOL isCalledFromDeactivate)
{
isCalledFromDeactivate;
if (_pComposition != nullptr)
{
// remove the display attribute from the composition range.
_ClearCompositionDisplayAttributes(ec, pContext);
if (FAILED(_pComposition->EndComposition(ec)))
{
// if we fail to EndComposition, then we need to close the reverse reading window.
_DeleteCandidateList(TRUE, pContext);
}
_pComposition->Release();
_pComposition = nullptr;
if (_pContext)
{
_pContext->Release();
_pContext = nullptr;
}
}
}
//+---------------------------------------------------------------------------
//
// _EndComposition
//
//----------------------------------------------------------------------------
void CSampleIME::_EndComposition(_In_opt_ ITfContext *pContext)
{
CEndCompositionEditSession *pEditSession = new (std::nothrow) CEndCompositionEditSession(this, pContext);
HRESULT hr = S_OK;
if (nullptr != pEditSession)
{
pContext->RequestEditSession(_tfClientId, pEditSession, TF_ES_ASYNCDONTCARE | TF_ES_READWRITE, &hr);
pEditSession->Release();
}
}
+226
View File
@@ -0,0 +1,226 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "globals.h"
#include "SampleIME.h"
#include "DisplayAttributeInfo.h"
#include "EnumDisplayAttributeInfo.h"
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CEnumDisplayAttributeInfo::CEnumDisplayAttributeInfo()
{
DllAddRef();
_index = 0;
_refCount = 1;
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CEnumDisplayAttributeInfo::~CEnumDisplayAttributeInfo()
{
DllRelease();
}
//+---------------------------------------------------------------------------
//
// QueryInterface
//
//----------------------------------------------------------------------------
STDAPI CEnumDisplayAttributeInfo::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
return E_INVALIDARG;
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_IEnumTfDisplayAttributeInfo))
{
*ppvObj = (IEnumTfDisplayAttributeInfo *)this;
}
if (*ppvObj)
{
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//+---------------------------------------------------------------------------
//
// AddRef
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CEnumDisplayAttributeInfo::AddRef()
{
return ++_refCount;
}
//+---------------------------------------------------------------------------
//
// Release
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CEnumDisplayAttributeInfo::Release()
{
LONG cr = --_refCount;
assert(_refCount >= 0);
if (_refCount == 0)
{
delete this;
}
return cr;
}
//+---------------------------------------------------------------------------
//
// IEnumTfDisplayAttributeInfo::Clone
//
// Returns a copy of the object.
//----------------------------------------------------------------------------
STDAPI CEnumDisplayAttributeInfo::Clone(_Out_ IEnumTfDisplayAttributeInfo **ppEnum)
{
CEnumDisplayAttributeInfo* pClone = nullptr;
if (ppEnum == nullptr)
{
return E_INVALIDARG;
}
*ppEnum = nullptr;
pClone = new (std::nothrow) CEnumDisplayAttributeInfo();
if ((pClone) == nullptr)
{
return E_OUTOFMEMORY;
}
// the clone should match this object's state
pClone->_index = _index;
*ppEnum = pClone;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// IEnumTfDisplayAttributeInfo::Next
//
// Returns an array of display attribute info objects supported by this service.
//----------------------------------------------------------------------------
const int MAX_DISPLAY_ATTRIBUTE_INFO = 2;
STDAPI CEnumDisplayAttributeInfo::Next(ULONG ulCount, __RPC__out_ecount_part(ulCount, *pcFetched) ITfDisplayAttributeInfo **rgInfo, __RPC__out ULONG *pcFetched)
{
ULONG fetched;
fetched = 0;
if (ulCount == 0)
{
return S_OK;
}
if (rgInfo == nullptr)
{
return E_INVALIDARG;
}
*rgInfo = nullptr;
while (fetched < ulCount)
{
ITfDisplayAttributeInfo* pDisplayAttributeInfo = nullptr;
if (_index == 0)
{
pDisplayAttributeInfo = new (std::nothrow) CDisplayAttributeInfoInput();
if ((pDisplayAttributeInfo) == nullptr)
{
return E_OUTOFMEMORY;
}
}
else if (_index == 1)
{
pDisplayAttributeInfo = new (std::nothrow) CDisplayAttributeInfoConverted();
if ((pDisplayAttributeInfo) == nullptr)
{
return E_OUTOFMEMORY;
}
}
else
{
break;
}
*rgInfo = pDisplayAttributeInfo;
rgInfo++;
fetched++;
_index++;
}
if (pcFetched != nullptr)
{
// technically this is only legal if ulCount == 1, but we won't check
*pcFetched = fetched;
}
return (fetched == ulCount) ? S_OK : S_FALSE;
}
//+---------------------------------------------------------------------------
//
// IEnumTfDisplayAttributeInfo::Reset
//
// Resets the enumeration.
//----------------------------------------------------------------------------
STDAPI CEnumDisplayAttributeInfo::Reset()
{
_index = 0;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// IEnumTfDisplayAttributeInfo::Skip
//
// Skips past objects in the enumeration.
//----------------------------------------------------------------------------
STDAPI CEnumDisplayAttributeInfo::Skip(ULONG ulCount)
{
if ((ulCount + _index) > MAX_DISPLAY_ATTRIBUTE_INFO || (ulCount + _index) < ulCount)
{
_index = MAX_DISPLAY_ATTRIBUTE_INFO;
return S_FALSE;
}
_index += ulCount;
return S_OK;
}
+36
View File
@@ -0,0 +1,36 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
//+---------------------------------------------------------------------------
//
// CEnumDisplayAttributeInfo
//
//----------------------------------------------------------------------------
class CEnumDisplayAttributeInfo : public IEnumTfDisplayAttributeInfo
{
public:
CEnumDisplayAttributeInfo();
~CEnumDisplayAttributeInfo();
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IEnumTfDisplayAttributeInfo
STDMETHODIMP Clone(_Out_ IEnumTfDisplayAttributeInfo **ppEnum);
STDMETHODIMP Next(ULONG ulCount, __RPC__out_ecount_part(ulCount, *pcFetched) ITfDisplayAttributeInfo **rgInfo, __RPC__out ULONG *pcFetched);
STDMETHODIMP Reset();
STDMETHODIMP Skip(ULONG ulCount);
private:
LONG _index; // next display attribute to enum
LONG _refCount; // COM ref count
};
+146
View File
@@ -0,0 +1,146 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "private.h"
#include "EnumTfCandidates.h"
HRESULT CEnumTfCandidates::CreateInstance(_Out_ CEnumTfCandidates **ppobj, _In_ const CSampleImeArray<ITfCandidateString*> &rgelm, UINT currentNum)
{
if (ppobj == nullptr)
{
return E_INVALIDARG;
}
*ppobj = nullptr;
*ppobj = new (std::nothrow) CEnumTfCandidates(rgelm, currentNum);
if (*ppobj == nullptr)
{
return E_OUTOFMEMORY;
}
return S_OK;
}
HRESULT CEnumTfCandidates::CreateInstance(REFIID riid, _Out_ void **ppvObj, _In_ const CSampleImeArray<ITfCandidateString*> &rgelm, UINT currentNum)
{
if (ppvObj == nullptr)
{
return E_POINTER;
}
*ppvObj = nullptr;
*ppvObj = new (std::nothrow) CEnumTfCandidates(rgelm, currentNum);
if (*ppvObj == nullptr)
{
return E_OUTOFMEMORY;
}
return ((CEnumTfCandidates*)(*ppvObj))->QueryInterface(riid, ppvObj);
}
CEnumTfCandidates::CEnumTfCandidates(_In_ const CSampleImeArray<ITfCandidateString*> &rgelm, UINT currentNum)
{
_refCount = 0;
_rgelm = rgelm;
_currentCandidateStrIndex = currentNum;
}
CEnumTfCandidates::~CEnumTfCandidates()
{
}
//
// IUnknown methods
//
STDMETHODIMP CEnumTfCandidates::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
{
return E_POINTER;
}
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, __uuidof(IEnumTfCandidates)))
{
*ppvObj = (IEnumTfCandidates*)this;
}
if (*ppvObj == nullptr)
{
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) CEnumTfCandidates::AddRef()
{
return (ULONG)InterlockedIncrement(&_refCount);
}
STDMETHODIMP_(ULONG) CEnumTfCandidates::Release()
{
ULONG cRef = (ULONG)InterlockedDecrement(&_refCount);
if (0 < cRef)
{
return cRef;
}
delete this;
return 0;
}
//
// IEnumTfCandidates methods
//
STDMETHODIMP CEnumTfCandidates::Next(ULONG ulCount, _Out_ ITfCandidateString **ppObj, _Out_ ULONG *pcFetched)
{
ULONG fetched = 0;
if (ppObj == nullptr)
{
return E_INVALIDARG;
}
*ppObj = nullptr;
while ((fetched < ulCount) && (_currentCandidateStrIndex < _rgelm.Count()))
{
*ppObj = *_rgelm.GetAt(_currentCandidateStrIndex);
_currentCandidateStrIndex++;
fetched++;
}
if (pcFetched)
{
*pcFetched = fetched;
}
return (fetched == ulCount) ? S_OK : S_FALSE;
}
STDMETHODIMP CEnumTfCandidates::Skip(ULONG ulCount)
{
while ((0 < ulCount) && (_currentCandidateStrIndex < _rgelm.Count()))
{
_currentCandidateStrIndex++;
ulCount--;
}
return (0 < ulCount) ? S_FALSE : S_OK;
}
STDMETHODIMP CEnumTfCandidates::Reset()
{
_currentCandidateStrIndex = 0;
return S_OK;
}
STDMETHODIMP CEnumTfCandidates::Clone(_Out_ IEnumTfCandidates **ppEnum)
{
return CreateInstance(__uuidof(IEnumTfCandidates), (void**)ppEnum, _rgelm, _currentCandidateStrIndex);
}
+40
View File
@@ -0,0 +1,40 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "Globals.h"
class CEnumTfCandidates : public IEnumTfCandidates
{
protected:
// constructor/destructor
CEnumTfCandidates(_In_ const CSampleImeArray<ITfCandidateString*> &rgelm, UINT currentNum);
virtual ~CEnumTfCandidates(void);
public:
// create instance
static HRESULT CreateInstance(_Out_ CEnumTfCandidates **ppobj, _In_ const CSampleImeArray<ITfCandidateString*> &rgelm, UINT currentNum = 0);
static HRESULT CreateInstance(REFIID riid, _Out_ void **ppvObj, _In_ const CSampleImeArray<ITfCandidateString*> &rgelm, UINT currentNum = 0);
// IUnknown methods
virtual STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
virtual STDMETHODIMP_(ULONG) AddRef(void);
virtual STDMETHODIMP_(ULONG) Release(void);
// IEnumTfCandidates methods
virtual STDMETHODIMP Next(ULONG ulCount, _Out_ ITfCandidateString **ppObj, _Out_ ULONG *pcFetched);
virtual STDMETHODIMP Skip(ULONG ulCount);
virtual STDMETHODIMP Reset();
virtual STDMETHODIMP Clone(_Out_ IEnumTfCandidates **ppEnum);
protected:
LONG _refCount;
CSampleImeArray<ITfCandidateString*> _rgelm;
UINT _currentCandidateStrIndex;
};
+254
View File
@@ -0,0 +1,254 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#ifndef UNICODE
#define UNICODE
#endif // !UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif // !UNICODE
#include "Private.h"
#include "File.h"
#include "SampleIMEBaseStructure.h"
//---------------------------------------------------------------------
//
// ctor
//
//---------------------------------------------------------------------
CFile::CFile(UINT codePage)
{
_codePage = codePage;
_fileHandle = nullptr;
_pReadBuffer = nullptr;
_fileSize = 0;
_filePosPointer = 0;
_pFileName = nullptr;
}
//---------------------------------------------------------------------
//
// dtor
//
//---------------------------------------------------------------------
CFile::~CFile()
{
if (_pReadBuffer)
{
delete[] _pReadBuffer;
_pReadBuffer = nullptr;
}
if (_fileHandle)
{
CloseHandle(_fileHandle);
_fileHandle = nullptr;
}
if (_pFileName)
{
delete[] _pFileName;
_pFileName = nullptr;
}
}
//---------------------------------------------------------------------
//
// CreateFile
//
//---------------------------------------------------------------------
BOOL CFile::CreateFile(_In_ PCWSTR pFileName, DWORD desiredAccess, DWORD creationDisposition, DWORD sharedMode,
_Inout_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD flagsAndAttributes,
_Inout_opt_ HANDLE templateFileHandle)
{
size_t fullPathLen = wcslen(pFileName);
if (!_pFileName)
{
_pFileName = new (std::nothrow) WCHAR[fullPathLen + 1];
}
if (!_pFileName)
{
return FALSE;
}
StringCchCopyN(_pFileName, fullPathLen + 1, pFileName, fullPathLen);
_fileHandle = ::CreateFile(pFileName, desiredAccess, sharedMode, lpSecurityAttributes, creationDisposition,
flagsAndAttributes, templateFileHandle);
if (_fileHandle == INVALID_HANDLE_VALUE)
{
return FALSE;
}
_fileSize = ::GetFileSize(_fileHandle, NULL);
return TRUE;
}
//---------------------------------------------------------------------
//
// SetupReadBuffer
//
//---------------------------------------------------------------------
BOOL CFile::SetupReadBuffer()
{
const WCHAR *pWideBuffer = nullptr;
_pReadBuffer = (const WCHAR *)new (std::nothrow) BYTE[_fileSize];
if (!_pReadBuffer)
{
return FALSE;
}
DWORD dwNumberOfByteRead = 0;
if (!ReadFile(_fileHandle, (LPVOID)_pReadBuffer, (DWORD)_fileSize, &dwNumberOfByteRead, NULL))
{
delete[] _pReadBuffer;
_pReadBuffer = nullptr;
return FALSE;
}
if (!IsTextUnicode(_pReadBuffer, dwNumberOfByteRead, NULL))
{
// This is ASCII file.
// Read file with Unicode conversion.
int wideLength = 0;
wideLength = MultiByteToWideChar(_codePage, 0, (LPCSTR)_pReadBuffer, dwNumberOfByteRead, NULL, 0);
if (wideLength <= 0)
{
delete[] _pReadBuffer;
_pReadBuffer = nullptr;
return FALSE;
}
pWideBuffer = new (std::nothrow) WCHAR[wideLength];
if (!pWideBuffer)
{
delete[] _pReadBuffer;
_pReadBuffer = nullptr;
return FALSE;
}
wideLength =
MultiByteToWideChar(_codePage, 0, (LPCSTR)_pReadBuffer, (DWORD)_fileSize, (LPWSTR)pWideBuffer, wideLength);
if (wideLength <= 0)
{
delete[] pWideBuffer;
delete[] _pReadBuffer;
_pReadBuffer = nullptr;
return FALSE;
}
_fileSize = wideLength * sizeof(WCHAR);
delete[] _pReadBuffer;
_pReadBuffer = pWideBuffer;
}
else if (_fileSize > sizeof(WCHAR))
{
// Read file in allocated buffer
pWideBuffer = new (std::nothrow) WCHAR[_fileSize / sizeof(WCHAR) - 1];
if (!pWideBuffer)
{
delete[] _pReadBuffer;
_pReadBuffer = nullptr;
return FALSE;
}
// skip unicode byte-order signature
SetFilePointer(_fileHandle, sizeof(WCHAR), NULL, FILE_BEGIN);
if (!ReadFile(_fileHandle, (LPVOID)pWideBuffer, (DWORD)(_fileSize - sizeof(WCHAR)), &dwNumberOfByteRead, NULL))
{
delete[] pWideBuffer;
delete[] _pReadBuffer;
_pReadBuffer = nullptr;
return FALSE;
}
_fileSize -= sizeof(WCHAR);
delete[] _pReadBuffer;
_pReadBuffer = pWideBuffer;
}
else
{
return FALSE;
}
return TRUE;
}
//+---------------------------------------------------------------------------
//
// IsEndOfFile
//
//----------------------------------------------------------------------------
BOOL CFile::IsEndOfFile()
{
return _fileSize == _filePosPointer ? TRUE : FALSE;
}
//+---------------------------------------------------------------------------
//
// NextLine
//
//----------------------------------------------------------------------------
VOID CFile::NextLine()
{
DWORD_PTR totalBufLen = GetBufferInWCharLength();
if (totalBufLen == 0)
{
goto SetEOF;
}
const WCHAR *pwch = GetBufferInWChar();
DWORD_PTR indexTrace = 0; // in char
if (FindChar(L'\r', pwch, totalBufLen, &indexTrace) != S_OK)
{
goto SetEOF;
}
if (indexTrace >= DWORD_MAX - 1)
{
goto SetEOF;
}
indexTrace++; // skip CR
totalBufLen -= indexTrace;
if (totalBufLen == 0)
{
goto SetEOF;
}
if (pwch[indexTrace] != L'\n')
{
_filePosPointer += (indexTrace * sizeof(WCHAR));
return;
}
indexTrace++;
totalBufLen--;
if (totalBufLen == 0)
{
goto SetEOF;
}
_filePosPointer += (indexTrace * sizeof(WCHAR));
return;
SetEOF:
_filePosPointer = _fileSize;
return;
}
+70
View File
@@ -0,0 +1,70 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
// #include "Private.h"
class CFile
{
public:
CFile(UINT codePage = CP_ACP);
virtual ~CFile();
BOOL CreateFile(_In_ PCWSTR pFileName, DWORD desiredAccess, DWORD creationDisposition,
DWORD sharedMode = 0, _Inout_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr, DWORD flagsAndAttributes = 0, _Inout_opt_ HANDLE templateFileHandle = nullptr);
BOOL IsEndOfFile();
VOID NextLine();
_Ret_maybenull_
const WCHAR *GetReadBufferPointer()
{
if (!_pReadBuffer)
{
if (!SetupReadBuffer())
{
return nullptr;
}
}
return _pReadBuffer;
}
DWORD_PTR GetFileSize() { return _fileSize;}
LPCWSTR GetFileName() { return _pFileName;}
protected:
virtual BOOL SetupReadBuffer();
protected:
const WCHAR* _pReadBuffer; // read buffer memory.
DWORD_PTR _fileSize; // in byte.
HANDLE _fileHandle; // file handle for CreateFile
private:
DWORD_PTR GetBufferInWCharLength()
{
if (_filePosPointer == 0 && _fileSize > 0)
{
// skip Unicode byte order mark
GetReadBufferPointer();
}
return(_fileSize - _filePosPointer) / sizeof(WCHAR); // in char count as a returned length.
}
const WCHAR *GetBufferInWChar()
{
const WCHAR *pwch = GetReadBufferPointer();
return(const WCHAR*)((BYTE*)pwch + _filePosPointer);
}
private:
UINT _codePage; // used for MultiByteToWideChar
DWORD_PTR _filePosPointer; // in byte. Always point start of line.
LPWSTR _pFileName;
};
+87
View File
@@ -0,0 +1,87 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "FileMapping.h"
#include "Globals.h"
//---------------------------------------------------------------------
//
// ctor
//
//---------------------------------------------------------------------
CFileMapping::CFileMapping() : CFile()
{
_fileMappingHandle = nullptr;
_pMapBuffer = nullptr;
}
//---------------------------------------------------------------------
//
// dtor
//
//---------------------------------------------------------------------
CFileMapping::~CFileMapping()
{
if (_pMapBuffer)
{
UnmapViewOfFile(_pMapBuffer);
_pMapBuffer = nullptr;
_pReadBuffer = nullptr;
}
if (_fileMappingHandle)
{
CloseHandle(_fileMappingHandle);
_fileMappingHandle = nullptr;
}
}
//---------------------------------------------------------------------
//
// SetupReadBuffer
//
//---------------------------------------------------------------------
BOOL CFileMapping::SetupReadBuffer()
{
if (_fileSize > sizeof(WCHAR))
{
//
// Read file in file mapping
//
_fileMappingHandle = CreateFileMapping(_fileHandle, NULL, PAGE_READONLY, 0, 0, NULL);
if (_fileMappingHandle)
{
_pMapBuffer = (const WCHAR *)MapViewOfFile(_fileMappingHandle, FILE_MAP_READ, 0, 0, 0);
if (_pMapBuffer)
{
if (IsTextUnicode(_pMapBuffer, (int)_fileSize, NULL))
{
_pReadBuffer = (WCHAR*)_pMapBuffer;
// skip Unicode byte order mark
if (*((WCHAR*)_pMapBuffer) == Global::UnicodeByteOrderMark)
{
_pReadBuffer++;
_fileSize--;
}
return TRUE;
}
UnmapViewOfFile(_pReadBuffer);
_pReadBuffer = nullptr;
}
CloseHandle(_fileMappingHandle);
_fileMappingHandle = nullptr;
}
}
return FALSE;
}
+46
View File
@@ -0,0 +1,46 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "File.h"
class CFileMapping : public CFile
{
public:
CFileMapping();
virtual ~CFileMapping();
BOOL CreateFile(_In_ PCWSTR pFileName, DWORD desiredAccess, DWORD creationDisposition,
DWORD sharedMode = 0, _Inout_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr, DWORD flagsAndAttributes = 0, _Inout_opt_ HANDLE templateFileHandle = nullptr)
{
return CFile::CreateFile(pFileName, desiredAccess, creationDisposition,
sharedMode, lpSecurityAttributes, flagsAndAttributes, templateFileHandle);
}
BOOL IsEndOfFile()
{
return CFile::IsEndOfFile();
}
VOID NextLine()
{
CFile::NextLine();
}
const WCHAR *GetReadBufferPointer() { return CFile::GetReadBufferPointer(); }
DWORD_PTR GetFileSize() { return CFile::GetFileSize(); }
LPCWSTR GetFileName() { return CFile::GetFileName(); }
protected:
BOOL SetupReadBuffer();
private:
HANDLE _fileMappingHandle; // file handle for CreateFileMapping
const VOID *_pMapBuffer; // read buffer memory.
};
+55
View File
@@ -0,0 +1,55 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "SampleIME.h"
#include "SearchCandidateProvider.h"
//+---------------------------------------------------------------------------
//
// _InitFunctionProviderSink
//
//----------------------------------------------------------------------------
BOOL CSampleIME::_InitFunctionProviderSink()
{
ITfSourceSingle* pSourceSingle = nullptr;
BOOL ret = FALSE;
if (SUCCEEDED(_pThreadMgr->QueryInterface(IID_ITfSourceSingle, (void **)&pSourceSingle)))
{
IUnknown* punk = nullptr;
if (SUCCEEDED(QueryInterface(IID_IUnknown, (void **)&punk)))
{
if (SUCCEEDED(pSourceSingle->AdviseSingleSink(_tfClientId, IID_ITfFunctionProvider, punk)))
{
if (SUCCEEDED(CSearchCandidateProvider::CreateInstance(&_pITfFnSearchCandidateProvider, (ITfTextInputProcessorEx*)this)))
{
ret = TRUE;
}
}
punk->Release();
}
pSourceSingle->Release();
}
return ret;
}
//+---------------------------------------------------------------------------
//
// _UninitFunctionProviderSink
//
//----------------------------------------------------------------------------
void CSampleIME::_UninitFunctionProviderSink()
{
ITfSourceSingle* pSourceSingle = nullptr;
if (SUCCEEDED(_pThreadMgr->QueryInterface(IID_ITfSourceSingle, (void **)&pSourceSingle)))
{
pSourceSingle->UnadviseSingleSink(_tfClientId, IID_ITfFunctionProvider);
pSourceSingle->Release();
}
}
+43
View File
@@ -0,0 +1,43 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "EditSession.h"
#include "GetTextExtentEditSession.h"
#include "TfTextLayoutSink.h"
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CGetTextExtentEditSession::CGetTextExtentEditSession(_In_ CSampleIME *pTextService, _In_ ITfContext *pContext, _In_ ITfContextView *pContextView, _In_ ITfRange *pRangeComposition, _In_ CTfTextLayoutSink *pTfTextLayoutSink) : CEditSessionBase(pTextService, pContext)
{
_pContextView = pContextView;
_pRangeComposition = pRangeComposition;
_pTfTextLayoutSink = pTfTextLayoutSink;
}
//+---------------------------------------------------------------------------
//
// ITfEditSession::DoEditSession
//
//----------------------------------------------------------------------------
STDAPI CGetTextExtentEditSession::DoEditSession(TfEditCookie ec)
{
RECT rc = {0, 0, 0, 0};
BOOL isClipped = TRUE;
if (SUCCEEDED(_pContextView->GetTextExt(ec, _pRangeComposition, &rc, &isClipped)))
{
_pTfTextLayoutSink->_LayoutChangeNotification(&rc);
}
return S_OK;
}
+41
View File
@@ -0,0 +1,41 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "EditSession.h"
class CSampleIME;
class CTfTextLayoutSink;
//////////////////////////////////////////////////////////////////////
//
// ITfEditSession
// CEditSessionBase
// CGetTextExtentEditSession class
//
//////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// CGetTextExtentEditSession
//
//----------------------------------------------------------------------------
class CGetTextExtentEditSession : public CEditSessionBase
{
public:
CGetTextExtentEditSession(_In_ CSampleIME *pTextService, _In_ ITfContext *pContext, _In_ ITfContextView *pContextView, _In_ ITfRange *pRangeComposition, _In_ CTfTextLayoutSink *pTextLayoutSink);
// ITfEditSession
STDMETHODIMP DoEditSession(TfEditCookie ec);
private:
ITfContextView* _pContextView;
ITfRange* _pRangeComposition;
CTfTextLayoutSink* _pTfTextLayoutSink;
};
+460
View File
@@ -0,0 +1,460 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "resource.h"
#include "BaseWindow.h"
#include "define.h"
#include "SampleIMEBaseStructure.h"
namespace Global {
HINSTANCE dllInstanceHandle;
LONG dllRefCount = -1;
CRITICAL_SECTION CS;
HFONT defaultlFontHandle; // Global font object we use everywhere
//---------------------------------------------------------------------
// SampleIME CLSID
//---------------------------------------------------------------------
// {D2291A80-84D8-4641-9AB2-BDD1472C846B}
extern const CLSID SampleIMECLSID = {
0xd2291a80,
0x84d8,
0x4641,
{ 0x9a, 0xb2, 0xbd, 0xd1, 0x47, 0x2c, 0x84, 0x6b }
};
//---------------------------------------------------------------------
// Profile GUID
//---------------------------------------------------------------------
// {83955C0E-2C09-47a5-BCF3-F2B98E11EE8B}
extern const GUID SampleIMEGuidProfile = {
0x83955c0e,
0x2c09,
0x47a5,
{ 0xbc, 0xf3, 0xf2, 0xb9, 0x8e, 0x11, 0xee, 0x8b }
};
//---------------------------------------------------------------------
// PreserveKey GUID
//---------------------------------------------------------------------
// {4B62B54B-F828-43B5-9095-A96DF9CBDF38}
extern const GUID SampleIMEGuidImeModePreserveKey = {
0x4b62b54b,
0xf828,
0x43b5,
{ 0x90, 0x95, 0xa9, 0x6d, 0xf9, 0xcb, 0xdf, 0x38 }
};
// {5A08D6C4-4563-4E46-8DDB-65E75C4E73A3}
extern const GUID SampleIMEGuidDoubleSingleBytePreserveKey = {
0x5a08d6c4,
0x4563,
0x4e46,
{ 0x8d, 0xdb, 0x65, 0xe7, 0x5c, 0x4e, 0x73, 0xa3 }
};
// {175F062E-B961-4AED-A3DF-59F78A02862D}
extern const GUID SampleIMEGuidPunctuationPreserveKey = {
0x175f062e,
0xb961,
0x4aed,
{ 0xa3, 0xdf, 0x59, 0xf7, 0x8a, 0x2, 0x86, 0x2d }
};
//---------------------------------------------------------------------
// Compartments
//---------------------------------------------------------------------
// {101011C5-CF72-4F0C-A515-153019593F10}
extern const GUID SampleIMEGuidCompartmentDoubleSingleByte = {
0x101011c5,
0xcf72,
0x4f0c,
{ 0xa5, 0x15, 0x15, 0x30, 0x19, 0x59, 0x3f, 0x10 }
};
// {DD321BCC-A7F8-4561-9B61-9B3508C9BA97}
extern const GUID SampleIMEGuidCompartmentPunctuation = {
0xdd321bcc,
0xa7f8,
0x4561,
{ 0x9b, 0x61, 0x9b, 0x35, 0x8, 0xc9, 0xba, 0x97 }
};
//---------------------------------------------------------------------
// LanguageBars
//---------------------------------------------------------------------
// {89BE500C-9462-4070-9DB0-B467BB051327}
extern const GUID SampleIMEGuidLangBarIMEMode = {
0x89be500c,
0x9462,
0x4070,
{ 0x9d, 0xb0, 0xb4, 0x67, 0xbb, 0x5, 0x13, 0x27 }
};
// {6A11D9DE-46DB-455B-A257-2EB615746BF4}
extern const GUID SampleIMEGuidLangBarDoubleSingleByte = {
0x6a11d9de,
0x46db,
0x455b,
{ 0xa2, 0x57, 0x2e, 0xb6, 0x15, 0x74, 0x6b, 0xf4 }
};
// {F29C731A-A51E-49FB-8A3C-EE51752912E2}
extern const GUID SampleIMEGuidLangBarPunctuation = {
0xf29c731a,
0xa51e,
0x49fb,
{ 0x8a, 0x3c, 0xee, 0x51, 0x75, 0x29, 0x12, 0xe2 }
};
// {4C802E2C-8140-4436-A5E5-F7C544EBC9CD}
extern const GUID SampleIMEGuidDisplayAttributeInput = {
0x4c802e2c,
0x8140,
0x4436,
{ 0xa5, 0xe5, 0xf7, 0xc5, 0x44, 0xeb, 0xc9, 0xcd }
};
// {9A1CC683-F2A7-4701-9C6E-2DA69A5CD474}
extern const GUID SampleIMEGuidDisplayAttributeConverted = {
0x9a1cc683,
0xf2a7,
0x4701,
{ 0x9c, 0x6e, 0x2d, 0xa6, 0x9a, 0x5c, 0xd4, 0x74 }
};
//---------------------------------------------------------------------
// UI element
//---------------------------------------------------------------------
// {84B0749F-8DE7-4732-907A-3BCB150A01A8}
extern const GUID SampleIMEGuidCandUIElement = {
0x84b0749f,
0x8de7,
0x4732,
{ 0x90, 0x7a, 0x3b, 0xcb, 0x15, 0xa, 0x1, 0xa8 }
};
//---------------------------------------------------------------------
// Unicode byte order mark
//---------------------------------------------------------------------
extern const WCHAR UnicodeByteOrderMark = 0xFEFF;
//---------------------------------------------------------------------
// dictionary table delimiter
//---------------------------------------------------------------------
extern const WCHAR KeywordDelimiter = L'=';
extern const WCHAR StringDelimiter = L'\"';
//---------------------------------------------------------------------
// defined item in setting file table [PreservedKey] section
//---------------------------------------------------------------------
extern const WCHAR ImeModeDescription[] = L"Chinese/English input (Shift)";
extern const int ImeModeOnIcoIndex = IME_MODE_ON_ICON_INDEX;
extern const int ImeModeOffIcoIndex = IME_MODE_OFF_ICON_INDEX;
extern const WCHAR DoubleSingleByteDescription[] = L"Double/Single byte (Shift+Space)";
extern const int DoubleSingleByteOnIcoIndex = IME_DOUBLE_ON_INDEX;
extern const int DoubleSingleByteOffIcoIndex = IME_DOUBLE_OFF_INDEX;
extern const WCHAR PunctuationDescription[] = L"Chinese/English punctuation (Ctrl+.)";
extern const int PunctuationOnIcoIndex = IME_PUNCTUATION_ON_INDEX;
extern const int PunctuationOffIcoIndex = IME_PUNCTUATION_OFF_INDEX;
//---------------------------------------------------------------------
// defined item in setting file table [LanguageBar] section
//---------------------------------------------------------------------
extern const WCHAR LangbarImeModeDescription[] = L"Conversion mode";
extern const WCHAR LangbarDoubleSingleByteDescription[] = L"Character width";
extern const WCHAR LangbarPunctuationDescription[] = L"Punctuation";
//---------------------------------------------------------------------
// windows class / titile / atom
//---------------------------------------------------------------------
extern const WCHAR CandidateClassName[] = L"SampleIME.CandidateWindow";
ATOM AtomCandidateWindow;
extern const WCHAR ShadowClassName[] = L"SampleIME.ShadowWindow";
ATOM AtomShadowWindow;
extern const WCHAR ScrollBarClassName[] = L"SampleIME.ScrollBarWindow";
ATOM AtomScrollBarWindow;
BOOL RegisterWindowClass()
{
if (!CBaseWindow::_InitWindowClass(CandidateClassName, &AtomCandidateWindow))
{
return FALSE;
}
if (!CBaseWindow::_InitWindowClass(ShadowClassName, &AtomShadowWindow))
{
return FALSE;
}
if (!CBaseWindow::_InitWindowClass(ScrollBarClassName, &AtomScrollBarWindow))
{
return FALSE;
}
return TRUE;
}
//---------------------------------------------------------------------
// defined full width characters for Double/Single byte conversion
//---------------------------------------------------------------------
extern const WCHAR FullWidthCharTable[] = {
// ! " # $ % & ' ( ) * + , - . /
0x3000, 0xFF01, 0xFF02, 0xFF03, 0xFF04, 0xFF05, 0xFF06, 0xFF07, 0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F,
// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F,
// @ A B C D E F G H I J K L M N 0
0xFF20, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F,
// P Q R S T U V W X Y Z [ \ ] ^ _
0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F,
// ' a b c d e f g h i j k l m n o
0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
// p q r s t u v w x y z { | } ~
0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFF5E
};
//---------------------------------------------------------------------
// defined punctuation characters
//---------------------------------------------------------------------
extern const struct _PUNCTUATION PunctuationTable[14] = {
{L'!', 0xFF01},
{L'$', 0xFFE5},
{L'&', 0x2014},
{L'(', 0xFF08},
{L')', 0xFF09},
{L',', 0xFF0C},
{L'.', 0x3002},
{L':', 0xFF1A},
{L';', 0xFF1B},
{L'?', 0xFF1F},
{L'@', 0x00B7},
{L'\\', 0x3001},
{L'^', 0x2026},
{L'_', 0x2014}
};
//+---------------------------------------------------------------------------
//
// CheckModifiers
//
//----------------------------------------------------------------------------
#define TF_MOD_ALLALT (TF_MOD_RALT | TF_MOD_LALT | TF_MOD_ALT)
#define TF_MOD_ALLCONTROL (TF_MOD_RCONTROL | TF_MOD_LCONTROL | TF_MOD_CONTROL)
#define TF_MOD_ALLSHIFT (TF_MOD_RSHIFT | TF_MOD_LSHIFT | TF_MOD_SHIFT)
#define TF_MOD_RLALT (TF_MOD_RALT | TF_MOD_LALT)
#define TF_MOD_RLCONTROL (TF_MOD_RCONTROL | TF_MOD_LCONTROL)
#define TF_MOD_RLSHIFT (TF_MOD_RSHIFT | TF_MOD_LSHIFT)
#define CheckMod(m0, m1, mod) \
if (m1 & TF_MOD_ ## mod ##) \
{ \
if (!(m0 & TF_MOD_ ## mod ##)) \
{ \
return FALSE; \
} \
} \
else \
{ \
if ((m1 ^ m0) & TF_MOD_RL ## mod ##) \
{ \
return FALSE; \
} \
} \
BOOL CheckModifiers(UINT modCurrent, UINT mod)
{
mod &= ~TF_MOD_ON_KEYUP;
if (mod & TF_MOD_IGNORE_ALL_MODIFIER)
{
return TRUE;
}
if (modCurrent == mod)
{
return TRUE;
}
if (modCurrent && !mod)
{
return FALSE;
}
CheckMod(modCurrent, mod, ALT);
CheckMod(modCurrent, mod, SHIFT);
CheckMod(modCurrent, mod, CONTROL);
return TRUE;
}
//+---------------------------------------------------------------------------
//
// UpdateModifiers
//
// wParam - virtual-key code
// lParam - [0-15] Repeat count
// [16-23] Scan code
// [24] Extended key
// [25-28] Reserved
// [29] Context code
// [30] Previous key state
// [31] Transition state
//----------------------------------------------------------------------------
USHORT ModifiersValue = 0;
BOOL IsShiftKeyDownOnly = FALSE;
BOOL IsControlKeyDownOnly = FALSE;
BOOL IsAltKeyDownOnly = FALSE;
BOOL UpdateModifiers(WPARAM wParam, LPARAM lParam)
{
// high-order bit : key down
// low-order bit : toggled
SHORT sksMenu = GetKeyState(VK_MENU);
SHORT sksCtrl = GetKeyState(VK_CONTROL);
SHORT sksShft = GetKeyState(VK_SHIFT);
switch (wParam & 0xff)
{
case VK_MENU:
// is VK_MENU down?
if (sksMenu & 0x8000)
{
// is extended key?
if (lParam & 0x01000000)
{
ModifiersValue |= (TF_MOD_RALT | TF_MOD_ALT);
}
else
{
ModifiersValue |= (TF_MOD_LALT | TF_MOD_ALT);
}
// is previous key state up?
if (!(lParam & 0x40000000))
{
// is VK_CONTROL and VK_SHIFT up?
if (!(sksCtrl & 0x8000) && !(sksShft & 0x8000))
{
IsAltKeyDownOnly = TRUE;
}
else
{
IsShiftKeyDownOnly = FALSE;
IsControlKeyDownOnly = FALSE;
IsAltKeyDownOnly = FALSE;
}
}
}
break;
case VK_CONTROL:
// is VK_CONTROL down?
if (sksCtrl & 0x8000)
{
// is extended key?
if (lParam & 0x01000000)
{
ModifiersValue |= (TF_MOD_RCONTROL | TF_MOD_CONTROL);
}
else
{
ModifiersValue |= (TF_MOD_LCONTROL | TF_MOD_CONTROL);
}
// is previous key state up?
if (!(lParam & 0x40000000))
{
// is VK_SHIFT and VK_MENU up?
if (!(sksShft & 0x8000) && !(sksMenu & 0x8000))
{
IsControlKeyDownOnly = TRUE;
}
else
{
IsShiftKeyDownOnly = FALSE;
IsControlKeyDownOnly = FALSE;
IsAltKeyDownOnly = FALSE;
}
}
}
break;
case VK_SHIFT:
// is VK_SHIFT down?
if (sksShft & 0x8000)
{
// is scan code 0x36(right shift)?
if (((lParam >> 16) & 0x00ff) == 0x36)
{
ModifiersValue |= (TF_MOD_RSHIFT | TF_MOD_SHIFT);
}
else
{
ModifiersValue |= (TF_MOD_LSHIFT | TF_MOD_SHIFT);
}
// is previous key state up?
if (!(lParam & 0x40000000))
{
// is VK_MENU and VK_CONTROL up?
if (!(sksMenu & 0x8000) && !(sksCtrl & 0x8000))
{
IsShiftKeyDownOnly = TRUE;
}
else
{
IsShiftKeyDownOnly = FALSE;
IsControlKeyDownOnly = FALSE;
IsAltKeyDownOnly = FALSE;
}
}
}
break;
default:
IsShiftKeyDownOnly = FALSE;
IsControlKeyDownOnly = FALSE;
IsAltKeyDownOnly = FALSE;
break;
}
if (!(sksMenu & 0x8000))
{
ModifiersValue &= ~TF_MOD_ALLALT;
}
if (!(sksCtrl & 0x8000))
{
ModifiersValue &= ~TF_MOD_ALLCONTROL;
}
if (!(sksShft & 0x8000))
{
ModifiersValue &= ~TF_MOD_ALLSHIFT;
}
return TRUE;
}
//---------------------------------------------------------------------
// override CompareElements
//---------------------------------------------------------------------
BOOL CompareElements(LCID locale, const CStringRange* pElement1, const CStringRange* pElement2)
{
return (CStringRange::Compare(locale, (CStringRange*)pElement1, (CStringRange*)pElement2) == CSTR_EQUAL) ? TRUE : FALSE;
}
}
+162
View File
@@ -0,0 +1,162 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "private.h"
#include "define.h"
#include "SampleIMEBaseStructure.h"
void DllAddRef();
void DllRelease();
namespace Global {
//---------------------------------------------------------------------
// inline
//---------------------------------------------------------------------
inline void SafeRelease(_In_ IUnknown *punk)
{
if (punk != nullptr)
{
punk->Release();
}
}
inline void QuickVariantInit(_Inout_ VARIANT *pvar)
{
pvar->vt = VT_EMPTY;
}
inline void QuickVariantClear(_Inout_ VARIANT *pvar)
{
switch (pvar->vt)
{
// some ovbious VTs that don't need to call VariantClear.
case VT_EMPTY:
case VT_NULL:
case VT_I2:
case VT_I4:
case VT_R4:
case VT_R8:
case VT_CY:
case VT_DATE:
case VT_I1:
case VT_UI1:
case VT_UI2:
case VT_UI4:
case VT_I8:
case VT_UI8:
case VT_INT:
case VT_UINT:
case VT_BOOL:
break;
// Call release for VT_UNKNOWN.
case VT_UNKNOWN:
SafeRelease(pvar->punkVal);
break;
default:
// we call OleAut32 for other VTs.
VariantClear(pvar);
break;
}
pvar->vt = VT_EMPTY;
}
//+---------------------------------------------------------------------------
//
// IsTooSimilar
//
// Return TRUE if the colors cr1 and cr2 are so similar that they
// are hard to distinguish. Used for deciding to use reverse video
// selection instead of system selection colors.
//
//----------------------------------------------------------------------------
inline BOOL IsTooSimilar(COLORREF cr1, COLORREF cr2)
{
if ((cr1 | cr2) & 0xFF000000) // One color and/or the other isn't RGB, so algorithm doesn't apply
{
return FALSE;
}
LONG DeltaR = abs(GetRValue(cr1) - GetRValue(cr2));
LONG DeltaG = abs(GetGValue(cr1) - GetGValue(cr2));
LONG DeltaB = abs(GetBValue(cr1) - GetBValue(cr2));
return DeltaR + DeltaG + DeltaB < 80;
}
//---------------------------------------------------------------------
// extern
//---------------------------------------------------------------------
extern HINSTANCE dllInstanceHandle;
extern ATOM AtomCandidateWindow;
extern ATOM AtomShadowWindow;
extern ATOM AtomScrollBarWindow;
BOOL RegisterWindowClass();
extern LONG dllRefCount;
extern CRITICAL_SECTION CS;
extern HFONT defaultlFontHandle; // Global font object we use everywhere
extern const CLSID SampleIMECLSID;
extern const CLSID SampleIMEGuidProfile;
extern const CLSID SampleIMEGuidImeModePreserveKey;
extern const CLSID SampleIMEGuidDoubleSingleBytePreserveKey;
extern const CLSID SampleIMEGuidPunctuationPreserveKey;
LRESULT CALLBACK ThreadKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
BOOL CheckModifiers(UINT uModCurrent, UINT uMod);
BOOL UpdateModifiers(WPARAM wParam, LPARAM lParam);
extern USHORT ModifiersValue;
extern BOOL IsShiftKeyDownOnly;
extern BOOL IsControlKeyDownOnly;
extern BOOL IsAltKeyDownOnly;
extern const GUID SampleIMEGuidCompartmentDoubleSingleByte;
extern const GUID SampleIMEGuidCompartmentPunctuation;
extern const WCHAR FullWidthCharTable[];
extern const struct _PUNCTUATION PunctuationTable[14];
extern const GUID SampleIMEGuidLangBarIMEMode;
extern const GUID SampleIMEGuidLangBarDoubleSingleByte;
extern const GUID SampleIMEGuidLangBarPunctuation;
extern const GUID SampleIMEGuidDisplayAttributeInput;
extern const GUID SampleIMEGuidDisplayAttributeConverted;
extern const GUID SampleIMEGuidCandUIElement;
extern const WCHAR UnicodeByteOrderMark;
extern const WCHAR KeywordDelimiter;
extern const WCHAR StringDelimiter;
extern const WCHAR ImeModeDescription[];
extern const int ImeModeOnIcoIndex;
extern const int ImeModeOffIcoIndex;
extern const WCHAR DoubleSingleByteDescription[];
extern const int DoubleSingleByteOnIcoIndex;
extern const int DoubleSingleByteOffIcoIndex;
extern const WCHAR PunctuationDescription[];
extern const int PunctuationOnIcoIndex;
extern const int PunctuationOffIcoIndex;
extern const WCHAR LangbarImeModeDescription[];
extern const WCHAR LangbarDoubleSingleByteDescription[];
extern const WCHAR LangbarPunctuationDescription[];
}
+457
View File
@@ -0,0 +1,457 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
#include "SampleIME.h"
#include "CandidateListUIPresenter.h"
#include "CompositionProcessorEngine.h"
#include "KeyHandlerEditSession.h"
#include "Compartment.h"
// 0xF003, 0xF004 are the keys that the touch keyboard sends for next/previous
#define THIRDPARTY_NEXTPAGE static_cast<WORD>(0xF003)
#define THIRDPARTY_PREVPAGE static_cast<WORD>(0xF004)
// Because the code mostly works with VKeys, here map a WCHAR back to a VKKey for certain
// vkeys that the IME handles specially
__inline UINT VKeyFromVKPacketAndWchar(UINT vk, WCHAR wch)
{
UINT vkRet = vk;
if (LOWORD(vk) == VK_PACKET)
{
if (wch == L' ')
{
vkRet = VK_SPACE;
}
else if ((wch >= L'0') && (wch <= L'9'))
{
vkRet = static_cast<UINT>(wch);
}
else if ((wch >= L'a') && (wch <= L'z'))
{
vkRet = (UINT)(L'A') + ((UINT)(L'z') - static_cast<UINT>(wch));
}
else if ((wch >= L'A') && (wch <= L'Z'))
{
vkRet = static_cast<UINT>(wch);
}
else if (wch == THIRDPARTY_NEXTPAGE)
{
vkRet = VK_NEXT;
}
else if (wch == THIRDPARTY_PREVPAGE)
{
vkRet = VK_PRIOR;
}
}
return vkRet;
}
//+---------------------------------------------------------------------------
//
// _IsKeyEaten
//
//----------------------------------------------------------------------------
BOOL CSampleIME::_IsKeyEaten(_In_ ITfContext *pContext, UINT codeIn, _Out_ UINT *pCodeOut, _Out_writes_(1) WCHAR *pwch, _Out_opt_ _KEYSTROKE_STATE *pKeyState)
{
pContext;
*pCodeOut = codeIn;
BOOL isOpen = FALSE;
CCompartment CompartmentKeyboardOpen(_pThreadMgr, _tfClientId, GUID_COMPARTMENT_KEYBOARD_OPENCLOSE);
CompartmentKeyboardOpen._GetCompartmentBOOL(isOpen);
BOOL isDoubleSingleByte = FALSE;
CCompartment CompartmentDoubleSingleByte(_pThreadMgr, _tfClientId, Global::SampleIMEGuidCompartmentDoubleSingleByte);
CompartmentDoubleSingleByte._GetCompartmentBOOL(isDoubleSingleByte);
BOOL isPunctuation = FALSE;
CCompartment CompartmentPunctuation(_pThreadMgr, _tfClientId, Global::SampleIMEGuidCompartmentPunctuation);
CompartmentPunctuation._GetCompartmentBOOL(isPunctuation);
if (pKeyState)
{
pKeyState->Category = CATEGORY_NONE;
pKeyState->Function = FUNCTION_NONE;
}
if (pwch)
{
*pwch = L'\0';
}
// if the keyboard is disabled, we don't eat keys.
if (_IsKeyboardDisabled())
{
return FALSE;
}
//
// Map virtual key to character code
//
BOOL isTouchKeyboardSpecialKeys = FALSE;
WCHAR wch = ConvertVKey(codeIn);
*pCodeOut = VKeyFromVKPacketAndWchar(codeIn, wch);
if ((wch == THIRDPARTY_NEXTPAGE) || (wch == THIRDPARTY_PREVPAGE))
{
// We always eat the above softkeyboard special keys
isTouchKeyboardSpecialKeys = TRUE;
if (pwch)
{
*pwch = wch;
}
}
// if the keyboard is closed, we don't eat keys, with the exception of the touch keyboard specials keys
if (!isOpen && !isDoubleSingleByte && !isPunctuation)
{
return isTouchKeyboardSpecialKeys;
}
if (pwch)
{
*pwch = wch;
}
//
// Get composition engine
//
CCompositionProcessorEngine *pCompositionProcessorEngine;
pCompositionProcessorEngine = _pCompositionProcessorEngine;
if (isOpen)
{
//
// The candidate or phrase list handles the keys through ITfKeyEventSink.
//
// eat only keys that CKeyHandlerEditSession can handles.
//
if (pCompositionProcessorEngine->IsVirtualKeyNeed(*pCodeOut, pwch, _IsComposing(), _candidateMode, _isCandidateWithWildcard, pKeyState))
{
return TRUE;
}
}
//
// Punctuation
//
if (pCompositionProcessorEngine->IsPunctuation(wch))
{
if ((_candidateMode == CANDIDATE_NONE) && isPunctuation)
{
if (pKeyState)
{
pKeyState->Category = CATEGORY_COMPOSING;
pKeyState->Function = FUNCTION_PUNCTUATION;
}
return TRUE;
}
}
//
// Double/Single byte
//
if (isDoubleSingleByte && pCompositionProcessorEngine->IsDoubleSingleByte(wch))
{
if (_candidateMode == CANDIDATE_NONE)
{
if (pKeyState)
{
pKeyState->Category = CATEGORY_COMPOSING;
pKeyState->Function = FUNCTION_DOUBLE_SINGLE_BYTE;
}
return TRUE;
}
}
return isTouchKeyboardSpecialKeys;
}
//+---------------------------------------------------------------------------
//
// ConvertVKey
//
//----------------------------------------------------------------------------
WCHAR CSampleIME::ConvertVKey(UINT code)
{
//
// Map virtual key to scan code
//
UINT scanCode = 0;
scanCode = MapVirtualKey(code, 0);
//
// Keyboard state
//
BYTE abKbdState[256] = {'\0'};
if (!GetKeyboardState(abKbdState))
{
return 0;
}
//
// Map virtual key to character code
//
WCHAR wch = '\0';
if (ToUnicode(code, scanCode, abKbdState, &wch, 1, 0) == 1)
{
return wch;
}
return 0;
}
//+---------------------------------------------------------------------------
//
// _IsKeyboardDisabled
//
//----------------------------------------------------------------------------
BOOL CSampleIME::_IsKeyboardDisabled()
{
ITfDocumentMgr* pDocMgrFocus = nullptr;
ITfContext* pContext = nullptr;
BOOL isDisabled = FALSE;
if ((_pThreadMgr->GetFocus(&pDocMgrFocus) != S_OK) ||
(pDocMgrFocus == nullptr))
{
// if there is no focus document manager object, the keyboard
// is disabled.
isDisabled = TRUE;
}
else if ((pDocMgrFocus->GetTop(&pContext) != S_OK) ||
(pContext == nullptr))
{
// if there is no context object, the keyboard is disabled.
isDisabled = TRUE;
}
else
{
CCompartment CompartmentKeyboardDisabled(_pThreadMgr, _tfClientId, GUID_COMPARTMENT_KEYBOARD_DISABLED);
CompartmentKeyboardDisabled._GetCompartmentBOOL(isDisabled);
CCompartment CompartmentEmptyContext(_pThreadMgr, _tfClientId, GUID_COMPARTMENT_EMPTYCONTEXT);
CompartmentEmptyContext._GetCompartmentBOOL(isDisabled);
}
if (pContext)
{
pContext->Release();
}
if (pDocMgrFocus)
{
pDocMgrFocus->Release();
}
return isDisabled;
}
//+---------------------------------------------------------------------------
//
// ITfKeyEventSink::OnSetFocus
//
// Called by the system whenever this service gets the keystroke device focus.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnSetFocus(BOOL fForeground)
{
fForeground;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfKeyEventSink::OnTestKeyDown
//
// Called by the system to query this service wants a potential keystroke.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnTestKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten)
{
Global::UpdateModifiers(wParam, lParam);
_KEYSTROKE_STATE KeystrokeState;
WCHAR wch = '\0';
UINT code = 0;
*pIsEaten = _IsKeyEaten(pContext, (UINT)wParam, &code, &wch, &KeystrokeState);
if (KeystrokeState.Category == CATEGORY_INVOKE_COMPOSITION_EDIT_SESSION)
{
//
// Invoke key handler edit session
//
KeystrokeState.Category = CATEGORY_COMPOSING;
_InvokeKeyHandler(pContext, code, wch, (DWORD)lParam, KeystrokeState);
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfKeyEventSink::OnKeyDown
//
// Called by the system to offer this service a keystroke. If *pIsEaten == TRUE
// on exit, the application will not handle the keystroke.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten)
{
Global::UpdateModifiers(wParam, lParam);
_KEYSTROKE_STATE KeystrokeState;
WCHAR wch = '\0';
UINT code = 0;
*pIsEaten = _IsKeyEaten(pContext, (UINT)wParam, &code, &wch, &KeystrokeState);
if (*pIsEaten)
{
bool needInvokeKeyHandler = true;
//
// Invoke key handler edit session
//
if (code == VK_ESCAPE)
{
KeystrokeState.Category = CATEGORY_COMPOSING;
}
// Always eat THIRDPARTY_NEXTPAGE and THIRDPARTY_PREVPAGE keys, but don't always process them.
if ((wch == THIRDPARTY_NEXTPAGE) || (wch == THIRDPARTY_PREVPAGE))
{
needInvokeKeyHandler = !((KeystrokeState.Category == CATEGORY_NONE) && (KeystrokeState.Function == FUNCTION_NONE));
}
if (needInvokeKeyHandler)
{
_InvokeKeyHandler(pContext, code, wch, (DWORD)lParam, KeystrokeState);
}
}
else if (KeystrokeState.Category == CATEGORY_INVOKE_COMPOSITION_EDIT_SESSION)
{
// Invoke key handler edit session
KeystrokeState.Category = CATEGORY_COMPOSING;
_InvokeKeyHandler(pContext, code, wch, (DWORD)lParam, KeystrokeState);
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfKeyEventSink::OnTestKeyUp
//
// Called by the system to query this service wants a potential keystroke.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnTestKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten)
{
if (pIsEaten == nullptr)
{
return E_INVALIDARG;
}
Global::UpdateModifiers(wParam, lParam);
WCHAR wch = '\0';
UINT code = 0;
*pIsEaten = _IsKeyEaten(pContext, (UINT)wParam, &code, &wch, NULL);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfKeyEventSink::OnKeyUp
//
// Called by the system to offer this service a keystroke. If *pIsEaten == TRUE
// on exit, the application will not handle the keystroke.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten)
{
Global::UpdateModifiers(wParam, lParam);
WCHAR wch = '\0';
UINT code = 0;
*pIsEaten = _IsKeyEaten(pContext, (UINT)wParam, &code, &wch, NULL);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfKeyEventSink::OnPreservedKey
//
// Called when a hotkey (registered by us, or by the system) is typed.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnPreservedKey(ITfContext *pContext, REFGUID rguid, BOOL *pIsEaten)
{
pContext;
CCompositionProcessorEngine *pCompositionProcessorEngine;
pCompositionProcessorEngine = _pCompositionProcessorEngine;
pCompositionProcessorEngine->OnPreservedKey(rguid, pIsEaten, _GetThreadMgr(), _GetClientId());
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _InitKeyEventSink
//
// Advise a keystroke sink.
//----------------------------------------------------------------------------
BOOL CSampleIME::_InitKeyEventSink()
{
ITfKeystrokeMgr* pKeystrokeMgr = nullptr;
HRESULT hr = S_OK;
if (FAILED(_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr, (void **)&pKeystrokeMgr)))
{
return FALSE;
}
hr = pKeystrokeMgr->AdviseKeyEventSink(_tfClientId, (ITfKeyEventSink *)this, TRUE);
pKeystrokeMgr->Release();
return (hr == S_OK);
}
//+---------------------------------------------------------------------------
//
// _UninitKeyEventSink
//
// Unadvise a keystroke sink. Assumes we have advised one already.
//----------------------------------------------------------------------------
void CSampleIME::_UninitKeyEventSink()
{
ITfKeystrokeMgr* pKeystrokeMgr = nullptr;
if (FAILED(_pThreadMgr->QueryInterface(IID_ITfKeystrokeMgr, (void **)&pKeystrokeMgr)))
{
return;
}
pKeystrokeMgr->UnadviseKeyEventSink(_tfClientId);
pKeystrokeMgr->Release();
}
+635
View File
@@ -0,0 +1,635 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
#include "EditSession.h"
#include "SampleIME.h"
#include "CandidateListUIPresenter.h"
#include "CompositionProcessorEngine.h"
//////////////////////////////////////////////////////////////////////
//
// CSampleIME class
//
//////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// _IsRangeCovered
//
// Returns TRUE if pRangeTest is entirely contained within pRangeCover.
//
//----------------------------------------------------------------------------
BOOL CSampleIME::_IsRangeCovered(TfEditCookie ec, _In_ ITfRange *pRangeTest, _In_ ITfRange *pRangeCover)
{
LONG lResult = 0;;
if (FAILED(pRangeCover->CompareStart(ec, pRangeTest, TF_ANCHOR_START, &lResult))
|| (lResult > 0))
{
return FALSE;
}
if (FAILED(pRangeCover->CompareEnd(ec, pRangeTest, TF_ANCHOR_END, &lResult))
|| (lResult < 0))
{
return FALSE;
}
return TRUE;
}
//+---------------------------------------------------------------------------
//
// _DeleteCandidateList
//
//----------------------------------------------------------------------------
VOID CSampleIME::_DeleteCandidateList(BOOL isForce, _In_opt_ ITfContext *pContext)
{
isForce;pContext;
CCompositionProcessorEngine* pCompositionProcessorEngine = nullptr;
pCompositionProcessorEngine = _pCompositionProcessorEngine;
pCompositionProcessorEngine->PurgeVirtualKey();
if (_pCandidateListUIPresenter)
{
_pCandidateListUIPresenter->_EndCandidateList();
_candidateMode = CANDIDATE_NONE;
_isCandidateWithWildcard = FALSE;
}
}
//+---------------------------------------------------------------------------
//
// _HandleComplete
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_HandleComplete(TfEditCookie ec, _In_ ITfContext *pContext)
{
_DeleteCandidateList(FALSE, pContext);
// just terminate the composition
_TerminateComposition(ec, pContext);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _HandleCancel
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_HandleCancel(TfEditCookie ec, _In_ ITfContext *pContext)
{
_RemoveDummyCompositionForComposing(ec, _pComposition);
_DeleteCandidateList(FALSE, pContext);
_TerminateComposition(ec, pContext);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _HandleCompositionInput
//
// If the keystroke happens within a composition, eat the key and return S_OK.
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_HandleCompositionInput(TfEditCookie ec, _In_ ITfContext *pContext, WCHAR wch)
{
ITfRange* pRangeComposition = nullptr;
TF_SELECTION tfSelection;
ULONG fetched = 0;
BOOL isCovered = TRUE;
CCompositionProcessorEngine* pCompositionProcessorEngine = nullptr;
pCompositionProcessorEngine = _pCompositionProcessorEngine;
if ((_pCandidateListUIPresenter != nullptr) && (_candidateMode != CANDIDATE_INCREMENTAL))
{
_HandleCompositionFinalize(ec, pContext, FALSE);
}
// Start the new (std::nothrow) compositon if there is no composition.
if (!_IsComposing())
{
_StartComposition(pContext);
}
// first, test where a keystroke would go in the document if we did an insert
if (pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched) != S_OK || fetched != 1)
{
return S_FALSE;
}
// is the insertion point covered by a composition?
if (SUCCEEDED(_pComposition->GetRange(&pRangeComposition)))
{
isCovered = _IsRangeCovered(ec, tfSelection.range, pRangeComposition);
pRangeComposition->Release();
if (!isCovered)
{
goto Exit;
}
}
// Add virtual key to composition processor engine
pCompositionProcessorEngine->AddVirtualKey(wch);
_HandleCompositionInputWorker(pCompositionProcessorEngine, ec, pContext);
Exit:
tfSelection.range->Release();
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _HandleCompositionInputWorker
//
// If the keystroke happens within a composition, eat the key and return S_OK.
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_HandleCompositionInputWorker(_In_ CCompositionProcessorEngine *pCompositionProcessorEngine, TfEditCookie ec, _In_ ITfContext *pContext)
{
HRESULT hr = S_OK;
CSampleImeArray<CStringRange> readingStrings;
BOOL isWildcardIncluded = TRUE;
//
// Get reading string from composition processor engine
//
pCompositionProcessorEngine->GetReadingStrings(&readingStrings, &isWildcardIncluded);
for (UINT index = 0; index < readingStrings.Count(); index++)
{
hr = _AddComposingAndChar(ec, pContext, readingStrings.GetAt(index));
if (FAILED(hr))
{
return hr;
}
}
//
// Get candidate string from composition processor engine
//
CSampleImeArray<CCandidateListItem> candidateList;
pCompositionProcessorEngine->GetCandidateList(&candidateList, TRUE, FALSE);
if ((candidateList.Count()))
{
hr = _CreateAndStartCandidate(pCompositionProcessorEngine, ec, pContext);
if (SUCCEEDED(hr))
{
_pCandidateListUIPresenter->_ClearList();
_pCandidateListUIPresenter->_SetText(&candidateList, TRUE);
}
}
else if (_pCandidateListUIPresenter)
{
_pCandidateListUIPresenter->_ClearList();
}
else if (readingStrings.Count() && isWildcardIncluded)
{
hr = _CreateAndStartCandidate(pCompositionProcessorEngine, ec, pContext);
if (SUCCEEDED(hr))
{
_pCandidateListUIPresenter->_ClearList();
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// _CreateAndStartCandidate
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_CreateAndStartCandidate(_In_ CCompositionProcessorEngine *pCompositionProcessorEngine, TfEditCookie ec, _In_ ITfContext *pContext)
{
HRESULT hr = S_OK;
if (((_candidateMode == CANDIDATE_PHRASE) && (_pCandidateListUIPresenter))
|| ((_candidateMode == CANDIDATE_NONE) && (_pCandidateListUIPresenter)))
{
// Recreate candidate list
_pCandidateListUIPresenter->_EndCandidateList();
delete _pCandidateListUIPresenter;
_pCandidateListUIPresenter = nullptr;
_candidateMode = CANDIDATE_NONE;
_isCandidateWithWildcard = FALSE;
}
if (_pCandidateListUIPresenter == nullptr)
{
_pCandidateListUIPresenter = new (std::nothrow) CCandidateListUIPresenter(this, Global::AtomCandidateWindow,
CATEGORY_CANDIDATE,
pCompositionProcessorEngine->GetCandidateListIndexRange(),
FALSE);
if (!_pCandidateListUIPresenter)
{
return E_OUTOFMEMORY;
}
_candidateMode = CANDIDATE_INCREMENTAL;
_isCandidateWithWildcard = FALSE;
// we don't cache the document manager object. So get it from pContext.
ITfDocumentMgr* pDocumentMgr = nullptr;
if (SUCCEEDED(pContext->GetDocumentMgr(&pDocumentMgr)))
{
// get the composition range.
ITfRange* pRange = nullptr;
if (SUCCEEDED(_pComposition->GetRange(&pRange)))
{
hr = _pCandidateListUIPresenter->_StartCandidateList(_tfClientId, pDocumentMgr, pContext, ec, pRange, pCompositionProcessorEngine->GetCandidateWindowWidth());
pRange->Release();
}
pDocumentMgr->Release();
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// _HandleCompositionFinalize
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_HandleCompositionFinalize(TfEditCookie ec, _In_ ITfContext *pContext, BOOL isCandidateList)
{
HRESULT hr = S_OK;
if (isCandidateList && _pCandidateListUIPresenter)
{
// Finalize selected candidate string from CCandidateListUIPresenter
DWORD_PTR candidateLen = 0;
const WCHAR *pCandidateString = nullptr;
candidateLen = _pCandidateListUIPresenter->_GetSelectedCandidateString(&pCandidateString);
CStringRange candidateString;
candidateString.Set(pCandidateString, candidateLen);
if (candidateLen)
{
// Finalize character
hr = _AddCharAndFinalize(ec, pContext, &candidateString);
if (FAILED(hr))
{
return hr;
}
}
}
else
{
// Finalize current text store strings
if (_IsComposing())
{
ULONG fetched = 0;
TF_SELECTION tfSelection;
if (FAILED(pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched)) || fetched != 1)
{
return S_FALSE;
}
ITfRange* pRangeComposition = nullptr;
if (SUCCEEDED(_pComposition->GetRange(&pRangeComposition)))
{
if (_IsRangeCovered(ec, tfSelection.range, pRangeComposition))
{
_EndComposition(pContext);
}
pRangeComposition->Release();
}
tfSelection.range->Release();
}
}
_HandleCancel(ec, pContext);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _HandleCompositionConvert
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_HandleCompositionConvert(TfEditCookie ec, _In_ ITfContext *pContext, BOOL isWildcardSearch)
{
HRESULT hr = S_OK;
CSampleImeArray<CCandidateListItem> candidateList;
//
// Get candidate string from composition processor engine
//
CCompositionProcessorEngine* pCompositionProcessorEngine = nullptr;
pCompositionProcessorEngine = _pCompositionProcessorEngine;
pCompositionProcessorEngine->GetCandidateList(&candidateList, FALSE, isWildcardSearch);
// If there is no candlidate listin the current reading string, we don't do anything. Just wait for
// next char to be ready for the conversion with it.
int nCount = candidateList.Count();
if (nCount)
{
if (_pCandidateListUIPresenter)
{
_pCandidateListUIPresenter->_EndCandidateList();
delete _pCandidateListUIPresenter;
_pCandidateListUIPresenter = nullptr;
_candidateMode = CANDIDATE_NONE;
_isCandidateWithWildcard = FALSE;
}
//
// create an instance of the candidate list class.
//
if (_pCandidateListUIPresenter == nullptr)
{
_pCandidateListUIPresenter = new (std::nothrow) CCandidateListUIPresenter(this, Global::AtomCandidateWindow,
CATEGORY_CANDIDATE,
pCompositionProcessorEngine->GetCandidateListIndexRange(),
FALSE);
if (!_pCandidateListUIPresenter)
{
return E_OUTOFMEMORY;
}
_candidateMode = CANDIDATE_ORIGINAL;
}
_isCandidateWithWildcard = isWildcardSearch;
// we don't cache the document manager object. So get it from pContext.
ITfDocumentMgr* pDocumentMgr = nullptr;
if (SUCCEEDED(pContext->GetDocumentMgr(&pDocumentMgr)))
{
// get the composition range.
ITfRange* pRange = nullptr;
if (SUCCEEDED(_pComposition->GetRange(&pRange)))
{
hr = _pCandidateListUIPresenter->_StartCandidateList(_tfClientId, pDocumentMgr, pContext, ec, pRange, pCompositionProcessorEngine->GetCandidateWindowWidth());
pRange->Release();
}
pDocumentMgr->Release();
}
if (SUCCEEDED(hr))
{
_pCandidateListUIPresenter->_SetText(&candidateList, FALSE);
}
}
return hr;
}
//+---------------------------------------------------------------------------
//
// _HandleCompositionBackspace
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_HandleCompositionBackspace(TfEditCookie ec, _In_ ITfContext *pContext)
{
ITfRange* pRangeComposition = nullptr;
TF_SELECTION tfSelection;
ULONG fetched = 0;
BOOL isCovered = TRUE;
// Start the new (std::nothrow) compositon if there is no composition.
if (!_IsComposing())
{
return S_OK;
}
// first, test where a keystroke would go in the document if we did an insert
if (FAILED(pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched)) || fetched != 1)
{
return S_FALSE;
}
// is the insertion point covered by a composition?
if (SUCCEEDED(_pComposition->GetRange(&pRangeComposition)))
{
isCovered = _IsRangeCovered(ec, tfSelection.range, pRangeComposition);
pRangeComposition->Release();
if (!isCovered)
{
goto Exit;
}
}
//
// Add virtual key to composition processor engine
//
CCompositionProcessorEngine* pCompositionProcessorEngine = nullptr;
pCompositionProcessorEngine = _pCompositionProcessorEngine;
DWORD_PTR vKeyLen = pCompositionProcessorEngine->GetVirtualKeyLength();
if (vKeyLen)
{
pCompositionProcessorEngine->RemoveVirtualKey(vKeyLen - 1);
if (pCompositionProcessorEngine->GetVirtualKeyLength())
{
_HandleCompositionInputWorker(pCompositionProcessorEngine, ec, pContext);
}
else
{
_HandleCancel(ec, pContext);
}
}
Exit:
tfSelection.range->Release();
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _HandleCompositionArrowKey
//
// Update the selection within a composition.
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_HandleCompositionArrowKey(TfEditCookie ec, _In_ ITfContext *pContext, KEYSTROKE_FUNCTION keyFunction)
{
ITfRange* pRangeComposition = nullptr;
TF_SELECTION tfSelection;
ULONG fetched = 0;
// get the selection
if (FAILED(pContext->GetSelection(ec, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched))
|| fetched != 1)
{
// no selection, eat the keystroke
return S_OK;
}
// get the composition range
if (FAILED(_pComposition->GetRange(&pRangeComposition)))
{
goto Exit;
}
// For incremental candidate list
if (_pCandidateListUIPresenter)
{
_pCandidateListUIPresenter->AdviseUIChangedByArrowKey(keyFunction);
}
pContext->SetSelection(ec, 1, &tfSelection);
pRangeComposition->Release();
Exit:
tfSelection.range->Release();
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _HandleCompositionPunctuation
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_HandleCompositionPunctuation(TfEditCookie ec, _In_ ITfContext *pContext, WCHAR wch)
{
HRESULT hr = S_OK;
if (_candidateMode != CANDIDATE_NONE && _pCandidateListUIPresenter)
{
DWORD_PTR candidateLen = 0;
const WCHAR* pCandidateString = nullptr;
candidateLen = _pCandidateListUIPresenter->_GetSelectedCandidateString(&pCandidateString);
CStringRange candidateString;
candidateString.Set(pCandidateString, candidateLen);
if (candidateLen)
{
_AddComposingAndChar(ec, pContext, &candidateString);
}
}
//
// Get punctuation char from composition processor engine
//
CCompositionProcessorEngine* pCompositionProcessorEngine = nullptr;
pCompositionProcessorEngine = _pCompositionProcessorEngine;
WCHAR punctuation = pCompositionProcessorEngine->GetPunctuation(wch);
CStringRange punctuationString;
punctuationString.Set(&punctuation, 1);
// Finalize character
hr = _AddCharAndFinalize(ec, pContext, &punctuationString);
if (FAILED(hr))
{
return hr;
}
_HandleCancel(ec, pContext);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _HandleCompositionDoubleSingleByte
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::_HandleCompositionDoubleSingleByte(TfEditCookie ec, _In_ ITfContext *pContext, WCHAR wch)
{
HRESULT hr = S_OK;
WCHAR fullWidth = Global::FullWidthCharTable[wch - 0x20];
CStringRange fullWidthString;
fullWidthString.Set(&fullWidth, 1);
// Finalize character
hr = _AddCharAndFinalize(ec, pContext, &fullWidthString);
if (FAILED(hr))
{
return hr;
}
_HandleCancel(ec, pContext);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _InvokeKeyHandler
//
// This text service is interested in handling keystrokes to demonstrate the
// use the compositions. Some apps will cancel compositions if they receive
// keystrokes while a compositions is ongoing.
//
// param
// [in] uCode - virtual key code of WM_KEYDOWN wParam
// [in] dwFlags - WM_KEYDOWN lParam
// [in] dwKeyFunction - Function regarding virtual key
//----------------------------------------------------------------------------
HRESULT CSampleIME::_InvokeKeyHandler(_In_ ITfContext *pContext, UINT code, WCHAR wch, DWORD flags, _KEYSTROKE_STATE keyState)
{
flags;
CKeyHandlerEditSession* pEditSession = nullptr;
HRESULT hr = E_FAIL;
// we'll insert a char ourselves in place of this keystroke
pEditSession = new (std::nothrow) CKeyHandlerEditSession(this, pContext, code, wch, keyState);
if (pEditSession == nullptr)
{
goto Exit;
}
//
// Call CKeyHandlerEditSession::DoEditSession().
//
// Do not specify TF_ES_SYNC so edit session is not invoked on WinWord
//
hr = pContext->RequestEditSession(_tfClientId, pEditSession, TF_ES_ASYNCDONTCARE | TF_ES_READWRITE, &hr);
pEditSession->Release();
Exit:
return hr;
}
+46
View File
@@ -0,0 +1,46 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "KeyHandlerEditSession.h"
#include "EditSession.h"
#include "SampleIME.h"
#include "CompositionProcessorEngine.h"
#include "KeyStateCategory.h"
//////////////////////////////////////////////////////////////////////
//
// ITfEditSession
// CEditSessionBase
// CKeyHandlerEditSession class
//
//////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// CKeyHandlerEditSession::DoEditSession
//
//----------------------------------------------------------------------------
STDAPI CKeyHandlerEditSession::DoEditSession(TfEditCookie ec)
{
HRESULT hResult = S_OK;
CKeyStateCategoryFactory* pKeyStateCategoryFactory = CKeyStateCategoryFactory::Instance();
CKeyStateCategory* pKeyStateCategory = pKeyStateCategoryFactory->MakeKeyStateCategory(_KeyState.Category, _pTextService);
if (pKeyStateCategory)
{
KeyHandlerEditSessionDTO keyHandlerEditSessioDTO(ec, _pContext, _uCode,_wch, _KeyState.Function);
hResult = pKeyStateCategory->KeyStateHandler(_KeyState.Function, keyHandlerEditSessioDTO);
pKeyStateCategory->Release();
pKeyStateCategoryFactory->Release();
}
return hResult;
}
+30
View File
@@ -0,0 +1,30 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "EditSession.h"
#include "Globals.h"
class CKeyHandlerEditSession : public CEditSessionBase
{
public:
CKeyHandlerEditSession(CSampleIME *pTextService, ITfContext *pContext, UINT uCode, WCHAR wch, _KEYSTROKE_STATE keyState) : CEditSessionBase(pTextService, pContext)
{
_uCode = uCode;
_wch = wch;
_KeyState = keyState;
}
// ITfEditSession
STDMETHODIMP DoEditSession(TfEditCookie ec);
private:
UINT _uCode; // virtual key code
WCHAR _wch; // character code
_KEYSTROKE_STATE _KeyState; // key function regarding virtual key
};
+370
View File
@@ -0,0 +1,370 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "KeyStateCategory.h"
CKeyStateCategoryFactory* CKeyStateCategoryFactory::_instance;
CKeyStateCategoryFactory::CKeyStateCategoryFactory()
{
_instance = nullptr;
}
CKeyStateCategoryFactory* CKeyStateCategoryFactory::Instance()
{
if (nullptr == _instance)
{
_instance = new (std::nothrow) CKeyStateCategoryFactory();
}
return _instance;
}
CKeyStateCategory* CKeyStateCategoryFactory::MakeKeyStateCategory(KEYSTROKE_CATEGORY keyCategory, _In_ CSampleIME *pTextService)
{
CKeyStateCategory* pKeyState = nullptr;
switch (keyCategory)
{
case CATEGORY_NONE:
pKeyState = new (std::nothrow) CKeyStateNull(pTextService);
break;
case CATEGORY_COMPOSING:
pKeyState = new (std::nothrow) CKeyStateComposing(pTextService);
break;
case CATEGORY_CANDIDATE:
pKeyState = new (std::nothrow) CKeyStateCandidate(pTextService);
break;
case CATEGORY_PHRASE:
pKeyState = new (std::nothrow) CKeyStatePhrase(pTextService);
break;
default:
pKeyState = new (std::nothrow) CKeyStateNull(pTextService);
break;
}
return pKeyState;
}
void CKeyStateCategoryFactory::Release()
{
if (_instance)
{
delete _instance;
_instance = nullptr;
}
}
/*
class CKeyStateCategory
*/
CKeyStateCategory::CKeyStateCategory(_In_ CSampleIME *pTextService)
{
_pTextService = pTextService;
}
CKeyStateCategory::~CKeyStateCategory(void)
{
}
HRESULT CKeyStateCategory::KeyStateHandler(KEYSTROKE_FUNCTION function, KeyHandlerEditSessionDTO dto)
{
switch(function)
{
case FUNCTION_INPUT:
return HandleKeyInput(dto);
case FUNCTION_FINALIZE_TEXTSTORE_AND_INPUT:
return HandleKeyFinalizeTextStoreAndInput(dto);
case FUNCTION_FINALIZE_TEXTSTORE:
return HandleKeyFinalizeTextStore(dto);
case FUNCTION_FINALIZE_CANDIDATELIST_AND_INPUT:
return HandleKeyFinalizeCandidatelistAndInput(dto);
case FUNCTION_FINALIZE_CANDIDATELIST:
return HandleKeyFinalizeCandidatelist(dto);
case FUNCTION_CONVERT:
return HandleKeyConvert(dto);
case FUNCTION_CONVERT_WILDCARD:
return HandleKeyConvertWildCard(dto);
case FUNCTION_CANCEL:
return HandleKeyCancel(dto);
case FUNCTION_BACKSPACE:
return HandleKeyBackspace(dto);
case FUNCTION_MOVE_LEFT:
case FUNCTION_MOVE_RIGHT:
return HandleKeyArrow(dto);
case FUNCTION_MOVE_UP:
case FUNCTION_MOVE_DOWN:
case FUNCTION_MOVE_PAGE_UP:
case FUNCTION_MOVE_PAGE_DOWN:
case FUNCTION_MOVE_PAGE_TOP:
case FUNCTION_MOVE_PAGE_BOTTOM:
return HandleKeyArrow(dto);
case FUNCTION_DOUBLE_SINGLE_BYTE:
return HandleKeyDoubleSingleByte(dto);
case FUNCTION_PUNCTUATION:
return HandleKeyPunctuation(dto);
case FUNCTION_SELECT_BY_NUMBER:
return HandleKeySelectByNumber(dto);
}
return E_INVALIDARG;
}
void CKeyStateCategory::Release()
{
delete this;
}
// _HandleCompositionInput
HRESULT CKeyStateCategory::HandleKeyInput(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
// HandleKeyFinalizeTextStore
HRESULT CKeyStateCategory::HandleKeyFinalizeTextStore(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
// HandleKeyCompositionFinalizeTextStoreAndInput
HRESULT CKeyStateCategory::HandleKeyFinalizeTextStoreAndInput(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
// HandleKeyCompositionFinalizeCandidatelistAndInput
HRESULT CKeyStateCategory::HandleKeyFinalizeCandidatelistAndInput(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
// HandleKeyCompositionFinalizeCandidatelist
HRESULT CKeyStateCategory::HandleKeyFinalizeCandidatelist(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
// HandleKeyConvert
HRESULT CKeyStateCategory::HandleKeyConvert(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
// HandleKeyConvertWildCard
HRESULT CKeyStateCategory::HandleKeyConvertWildCard(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
//_HandleCancel
HRESULT CKeyStateCategory::HandleKeyCancel(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
//_HandleCompositionBackspace
HRESULT CKeyStateCategory::HandleKeyBackspace(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
//_HandleCompositionArrowKey
HRESULT CKeyStateCategory::HandleKeyArrow(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
//_HandleCompositionDoubleSingleByte
HRESULT CKeyStateCategory::HandleKeyDoubleSingleByte(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
//_HandleCompositionPunctuation
HRESULT CKeyStateCategory::HandleKeyPunctuation(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
HRESULT CKeyStateCategory::HandleKeySelectByNumber(KeyHandlerEditSessionDTO dto)
{
dto;
return E_NOTIMPL;
}
/*
class CKeyStateComposing
*/
CKeyStateComposing::CKeyStateComposing(_In_ CSampleIME *pTextService) : CKeyStateCategory(pTextService)
{
}
HRESULT CKeyStateComposing::HandleKeyInput(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCompositionInput(dto.ec, dto.pContext, dto.wch);
}
HRESULT CKeyStateComposing::HandleKeyFinalizeTextStoreAndInput(KeyHandlerEditSessionDTO dto)
{
_pTextService->_HandleCompositionFinalize(dto.ec, dto.pContext, FALSE);
return _pTextService->_HandleCompositionInput(dto.ec, dto.pContext, dto.wch);
}
HRESULT CKeyStateComposing::HandleKeyFinalizeTextStore(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCompositionFinalize(dto.ec, dto.pContext, FALSE);
}
HRESULT CKeyStateComposing::HandleKeyFinalizeCandidatelistAndInput(KeyHandlerEditSessionDTO dto)
{
_pTextService->_HandleCompositionFinalize(dto.ec, dto.pContext, TRUE);
return _pTextService->_HandleCompositionInput(dto.ec, dto.pContext, dto.wch);
}
HRESULT CKeyStateComposing::HandleKeyFinalizeCandidatelist(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCompositionFinalize(dto.ec, dto.pContext, TRUE);
}
HRESULT CKeyStateComposing::HandleKeyConvert(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCompositionConvert(dto.ec, dto.pContext, FALSE);
}
HRESULT CKeyStateComposing::HandleKeyConvertWildCard(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCompositionConvert(dto.ec, dto.pContext, TRUE);
}
HRESULT CKeyStateComposing::HandleKeyCancel(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCancel(dto.ec, dto.pContext);
}
HRESULT CKeyStateComposing::HandleKeyBackspace(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCompositionBackspace(dto.ec, dto.pContext);
}
HRESULT CKeyStateComposing::HandleKeyArrow(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCompositionArrowKey(dto.ec, dto.pContext, dto.arrowKey);
}
HRESULT CKeyStateComposing::HandleKeyDoubleSingleByte(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCompositionDoubleSingleByte(dto.ec, dto.pContext, dto.wch);
}
HRESULT CKeyStateComposing::HandleKeyPunctuation(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCompositionPunctuation(dto.ec, dto.pContext, dto.wch);
}
/*
class CKeyStateCandidate
*/
CKeyStateCandidate::CKeyStateCandidate(_In_ CSampleIME *pTextService) : CKeyStateCategory(pTextService)
{
}
// _HandleCandidateInput
HRESULT CKeyStateCandidate::HandleKeyFinalizeCandidatelist(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCandidateFinalize(dto.ec, dto.pContext);
}
// HandleKeyFinalizeCandidatelistAndInput
HRESULT CKeyStateCandidate::HandleKeyFinalizeCandidatelistAndInput(KeyHandlerEditSessionDTO dto)
{
_pTextService->_HandleCandidateFinalize(dto.ec, dto.pContext);
return _pTextService->_HandleCompositionInput(dto.ec, dto.pContext, dto.wch);
}
//_HandleCandidateConvert
HRESULT CKeyStateCandidate::HandleKeyConvert(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCandidateConvert(dto.ec, dto.pContext);
}
//_HandleCancel
HRESULT CKeyStateCandidate::HandleKeyCancel(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCancel(dto.ec, dto.pContext);
}
//_HandleCandidateArrowKey
HRESULT CKeyStateCandidate::HandleKeyArrow(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCandidateArrowKey(dto.ec, dto.pContext, dto.arrowKey);
}
//_HandleCandidateSelectByNumber
HRESULT CKeyStateCandidate::HandleKeySelectByNumber(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCandidateSelectByNumber(dto.ec, dto.pContext, dto.code);
}
/*
class CKeyStatePhrase
*/
CKeyStatePhrase::CKeyStatePhrase(_In_ CSampleIME *pTextService) : CKeyStateCategory(pTextService)
{
}
//HandleKeyFinalizeCandidatelist
HRESULT CKeyStatePhrase::HandleKeyFinalizeCandidatelist(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandlePhraseFinalize(dto.ec, dto.pContext);
}
//HandleKeyCancel
HRESULT CKeyStatePhrase::HandleKeyCancel(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandleCancel(dto.ec, dto.pContext);
}
//HandleKeyArrow
HRESULT CKeyStatePhrase::HandleKeyArrow(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandlePhraseArrowKey(dto.ec, dto.pContext, dto.arrowKey);
}
//HandleKeySelectByNumber
HRESULT CKeyStatePhrase::HandleKeySelectByNumber(KeyHandlerEditSessionDTO dto)
{
return _pTextService->_HandlePhraseSelectByNumber(dto.ec, dto.pContext, dto.code);
}
+236
View File
@@ -0,0 +1,236 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "Globals.h"
#include "Private.h"
#include "SampleIME.h"
class CKeyStateCategory;
class CKeyStateCategoryFactory
{
public:
static CKeyStateCategoryFactory* Instance();
CKeyStateCategory* MakeKeyStateCategory(KEYSTROKE_CATEGORY keyCategory, _In_ CSampleIME *pTextService);
void Release();
protected:
CKeyStateCategoryFactory();
private:
static CKeyStateCategoryFactory* _instance;
};
typedef struct KeyHandlerEditSessionDTO
{
KeyHandlerEditSessionDTO::KeyHandlerEditSessionDTO(TfEditCookie tFEC, _In_ ITfContext *pTfContext, UINT virualCode, WCHAR inputChar, KEYSTROKE_FUNCTION arrowKeyFunction)
{
ec = tFEC;
pContext = pTfContext;
code = virualCode;
wch = inputChar;
arrowKey = arrowKeyFunction;
}
TfEditCookie ec;
ITfContext* pContext;
UINT code;
WCHAR wch;
KEYSTROKE_FUNCTION arrowKey;
}KeyHandlerEditSessionDTO;
class CKeyStateCategory
{
public:
CKeyStateCategory(_In_ CSampleIME *pTextService);
protected:
~CKeyStateCategory(void);
public:
HRESULT KeyStateHandler(KEYSTROKE_FUNCTION function, KeyHandlerEditSessionDTO dto);
void Release(void);
protected:
// HandleKeyInput
virtual HRESULT HandleKeyInput(KeyHandlerEditSessionDTO dto);
// HandleKeyFinalizeTextStoreAndInput
virtual HRESULT HandleKeyFinalizeTextStoreAndInput(KeyHandlerEditSessionDTO dto);
// HandleKeyFinalizeTextStore
virtual HRESULT HandleKeyFinalizeTextStore(KeyHandlerEditSessionDTO dto);
// HandleKeyFinalizeCandidatelistAndInput
virtual HRESULT HandleKeyFinalizeCandidatelistAndInput(KeyHandlerEditSessionDTO dto);
// HandleKeyFinalizeCandidatelist
virtual HRESULT HandleKeyFinalizeCandidatelist(KeyHandlerEditSessionDTO dto);
// HandleKeyConvert
virtual HRESULT HandleKeyConvert(KeyHandlerEditSessionDTO dto);
// HandleKeyConvertWild
virtual HRESULT HandleKeyConvertWildCard(KeyHandlerEditSessionDTO dto);
// HandleKeyCancel
virtual HRESULT HandleKeyCancel(KeyHandlerEditSessionDTO dto);
// HandleKeyBackspace
virtual HRESULT HandleKeyBackspace(KeyHandlerEditSessionDTO dto);
// HandleKeyArrow
virtual HRESULT HandleKeyArrow(KeyHandlerEditSessionDTO dto);
// HandleKeyDoubleSingleByte
virtual HRESULT HandleKeyDoubleSingleByte(KeyHandlerEditSessionDTO dto);
// HandleKeyPunctuation
virtual HRESULT HandleKeyPunctuation(KeyHandlerEditSessionDTO dto);
// HandleKeySelectByNumber
virtual HRESULT HandleKeySelectByNumber(KeyHandlerEditSessionDTO dto);
protected:
CSampleIME* _pTextService;
};
class CKeyStateComposing : public CKeyStateCategory
{
public:
CKeyStateComposing(_In_ CSampleIME *pTextService);
protected:
// _HandleCompositionInput
HRESULT HandleKeyInput(KeyHandlerEditSessionDTO dto);
// HandleKeyCompositionFinalizeTextStoreAndInput
HRESULT HandleKeyFinalizeTextStoreAndInput(KeyHandlerEditSessionDTO dto);
// HandleKeyFinalizeTextStore
HRESULT HandleKeyFinalizeTextStore(KeyHandlerEditSessionDTO dto);
// HandleKeyCompositionFinalizeCandidatelistAndInput
HRESULT HandleKeyFinalizeCandidatelistAndInput(KeyHandlerEditSessionDTO dto);
// HandleKeyCompositionFinalizeCandidatelist
HRESULT HandleKeyFinalizeCandidatelist(KeyHandlerEditSessionDTO dto);
// HandleCompositionConvert
HRESULT HandleKeyConvert(KeyHandlerEditSessionDTO dto);
// HandleKeyCompositionConvertWildCard
HRESULT HandleKeyConvertWildCard(KeyHandlerEditSessionDTO dto);
// HandleCancel
HRESULT HandleKeyCancel(KeyHandlerEditSessionDTO dto);
// HandleCompositionBackspace
HRESULT HandleKeyBackspace(KeyHandlerEditSessionDTO dto);
// HandleArrowKey
HRESULT HandleKeyArrow(KeyHandlerEditSessionDTO dto);
// HandleKeyDoubleSingleByte
HRESULT HandleKeyDoubleSingleByte(KeyHandlerEditSessionDTO dto);
// HandleKeyCompositionPunctuation
HRESULT HandleKeyPunctuation(KeyHandlerEditSessionDTO dto);
};
class CKeyStateCandidate : public CKeyStateCategory
{
public:
CKeyStateCandidate(_In_ CSampleIME *pTextService);
protected:
// HandleKeyFinalizeCandidatelist
HRESULT HandleKeyFinalizeCandidatelist(KeyHandlerEditSessionDTO dto);
// HandleKeyFinalizeCandidatelistAndInput
HRESULT HandleKeyFinalizeCandidatelistAndInput(KeyHandlerEditSessionDTO dto);
//_HandleCandidateConvert
HRESULT HandleKeyConvert(KeyHandlerEditSessionDTO dto);
//_HandleCancel
HRESULT HandleKeyCancel(KeyHandlerEditSessionDTO dto);
//_HandleCandidateArrowKey
HRESULT HandleKeyArrow(KeyHandlerEditSessionDTO dto);
//_HandleCandidateSelectByNumber
HRESULT HandleKeySelectByNumber(KeyHandlerEditSessionDTO dto);
};
class CKeyStatePhrase : public CKeyStateCategory
{
public:
CKeyStatePhrase(_In_ CSampleIME *pTextService);
protected:
//_HandleCancel
HRESULT HandleKeyFinalizeCandidatelist(KeyHandlerEditSessionDTO dto);
//_HandleCancel
HRESULT HandleKeyCancel(KeyHandlerEditSessionDTO dto);
//_HandlePhraseArrowKey
HRESULT HandleKeyArrow(KeyHandlerEditSessionDTO dto);
//_HandlePhraseSelectByNumber
HRESULT HandleKeySelectByNumber(KeyHandlerEditSessionDTO dto);
};
//degeneration class
class CKeyStateNull : public CKeyStateCategory
{
public:
CKeyStateNull(_In_ CSampleIME *pTextService) : CKeyStateCategory(pTextService) {};
protected:
// _HandleNullInput
HRESULT HandleKeyInput(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyInput(dto); };
// HandleKeyNullFinalizeTextStoreAndInput
HRESULT HandleKeyFinalizeTextStoreAndInput(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyFinalizeTextStoreAndInput(dto); };
// HandleKeyFinalizeTextStore
HRESULT HandleKeyFinalizeTextStore(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyFinalizeTextStore(dto); };
// HandleKeyNullFinalizeCandidatelistAndInput
HRESULT HandleKeyFinalizeCandidatelistAndInput(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyFinalizeCandidatelistAndInput(dto); };
// HandleKeyNullFinalizeCandidatelist
HRESULT HandleKeyFinalizeCandidatelist(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyFinalizeCandidatelist(dto); };
//_HandleNullConvert
HRESULT HandleKeyConvert(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyConvert(dto); };
//_HandleNullCancel
HRESULT HandleKeyCancel(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyCancel(dto); };
// HandleKeyNullConvertWild
HRESULT HandleKeyConvertWildCard(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyConvertWildCard(dto); };
//_HandleNullBackspace
HRESULT HandleKeyBackspace(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyBackspace(dto); };
//_HandleNullArrowKey
HRESULT HandleKeyArrow(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyArrow(dto); };
// HandleKeyDoubleSingleByte
HRESULT HandleKeyDoubleSingleByte(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyDoubleSingleByte(dto); };
// HandleKeyPunctuation
HRESULT HandleKeyPunctuation(KeyHandlerEditSessionDTO dto) { return __super::HandleKeyPunctuation(dto); };
//_HandleNullCandidateSelectByNumber
HRESULT HandleKeySelectByNumber(KeyHandlerEditSessionDTO dto) { return __super::HandleKeySelectByNumber(dto); };
};
+662
View File
@@ -0,0 +1,662 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "SampleIME.h"
#include "CompositionProcessorEngine.h"
#include "LanguageBar.h"
#include "Globals.h"
#include "Compartment.h"
//+---------------------------------------------------------------------------
//
// CSampleIME::_UpdateLanguageBarOnSetFocus
//
//----------------------------------------------------------------------------
void CSampleIME::_UpdateLanguageBarOnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus)
{
BOOL needDisableButtons = FALSE;
if (!pDocMgrFocus)
{
needDisableButtons = TRUE;
}
else
{
IEnumTfContexts* pEnumContext = nullptr;
if (FAILED(pDocMgrFocus->EnumContexts(&pEnumContext)) || !pEnumContext)
{
needDisableButtons = TRUE;
}
else
{
ULONG fetched = 0;
ITfContext* pContext = nullptr;
if (FAILED(pEnumContext->Next(1, &pContext, &fetched)) || fetched != 1)
{
needDisableButtons = TRUE;
}
if (!pContext)
{
// context is not associated
needDisableButtons = TRUE;
}
else
{
pContext->Release();
}
}
if (pEnumContext)
{
pEnumContext->Release();
}
}
CCompositionProcessorEngine* pCompositionProcessorEngine = nullptr;
pCompositionProcessorEngine = _pCompositionProcessorEngine;
pCompositionProcessorEngine->SetLanguageBarStatus(TF_LBI_STATUS_DISABLED, needDisableButtons);
}
//+---------------------------------------------------------------------------
//
// CCompositionProcessorEngine::SetLanguageBarStatus
//
//----------------------------------------------------------------------------
VOID CCompositionProcessorEngine::SetLanguageBarStatus(DWORD status, BOOL isSet)
{
if (_pLanguageBar_IMEMode) {
_pLanguageBar_IMEMode->SetStatus(status, isSet);
}
if (_pLanguageBar_DoubleSingleByte) {
_pLanguageBar_DoubleSingleByte->SetStatus(status, isSet);
}
if (_pLanguageBar_Punctuation) {
_pLanguageBar_Punctuation->SetStatus(status, isSet);
}
}
//+---------------------------------------------------------------------------
//
// CLangBarItemButton::ctor
//
//----------------------------------------------------------------------------
CLangBarItemButton::CLangBarItemButton(REFGUID guidLangBar, LPCWSTR description, LPCWSTR tooltip, DWORD onIconIndex, DWORD offIconIndex, BOOL isSecureMode)
{
DWORD bufLen = 0;
DllAddRef();
// initialize TF_LANGBARITEMINFO structure.
_tfLangBarItemInfo.clsidService = Global::SampleIMECLSID; // This LangBarItem belongs to this TextService.
_tfLangBarItemInfo.guidItem = guidLangBar; // GUID of this LangBarItem.
_tfLangBarItemInfo.dwStyle = (TF_LBI_STYLE_BTN_BUTTON | TF_LBI_STYLE_SHOWNINTRAY); // This LangBar is a button type.
_tfLangBarItemInfo.ulSort = 0; // The position of this LangBar Item is not specified.
StringCchCopy(_tfLangBarItemInfo.szDescription, ARRAYSIZE(_tfLangBarItemInfo.szDescription), description); // Set the description of this LangBar Item.
// Initialize the sink pointer to NULL.
_pLangBarItemSink = nullptr;
// Initialize ICON index and file name.
_onIconIndex = onIconIndex;
_offIconIndex = offIconIndex;
// Initialize compartment.
_pCompartment = nullptr;
_pCompartmentEventSink = nullptr;
_isAddedToLanguageBar = FALSE;
_isSecureMode = isSecureMode;
_status = 0;
_refCount = 1;
// Initialize Tooltip
_pTooltipText = nullptr;
if (tooltip)
{
size_t len = 0;
if (StringCchLength(tooltip, STRSAFE_MAX_CCH, &len) != S_OK)
{
len = 0;
}
bufLen = static_cast<DWORD>(len) + 1;
_pTooltipText = (LPCWSTR) new (std::nothrow) WCHAR[ bufLen ];
if (_pTooltipText)
{
StringCchCopy((LPWSTR)_pTooltipText, bufLen, tooltip);
}
}
}
//+---------------------------------------------------------------------------
//
// CLangBarItemButton::dtor
//
//----------------------------------------------------------------------------
CLangBarItemButton::~CLangBarItemButton()
{
DllRelease();
CleanUp();
}
//+---------------------------------------------------------------------------
//
// CLangBarItemButton::CleanUp
//
//----------------------------------------------------------------------------
void CLangBarItemButton::CleanUp()
{
if (_pTooltipText)
{
delete [] _pTooltipText;
_pTooltipText = nullptr;
}
ITfThreadMgr* pThreadMgr = nullptr;
HRESULT hr = CoCreateInstance(CLSID_TF_ThreadMgr,
NULL,
CLSCTX_INPROC_SERVER,
IID_ITfThreadMgr,
(void**)&pThreadMgr);
if (SUCCEEDED(hr))
{
_UnregisterCompartment(pThreadMgr);
_RemoveItem(pThreadMgr);
pThreadMgr->Release();
pThreadMgr = nullptr;
}
if (_pCompartment)
{
delete _pCompartment;
_pCompartment = nullptr;
}
if (_pCompartmentEventSink)
{
delete _pCompartmentEventSink;
_pCompartmentEventSink = nullptr;
}
}
//+---------------------------------------------------------------------------
//
// CLangBarItemButton::QueryInterface
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
{
return E_INVALIDARG;
}
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_ITfLangBarItem) ||
IsEqualIID(riid, IID_ITfLangBarItemButton))
{
*ppvObj = (ITfLangBarItemButton *)this;
}
else if (IsEqualIID(riid, IID_ITfSource))
{
*ppvObj = (ITfSource *)this;
}
if (*ppvObj)
{
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//+---------------------------------------------------------------------------
//
// CLangBarItemButton::AddRef
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CLangBarItemButton::AddRef()
{
return ++_refCount;
}
//+---------------------------------------------------------------------------
//
// CLangBarItemButton::Release
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CLangBarItemButton::Release()
{
LONG cr = --_refCount;
assert(_refCount >= 0);
if (_refCount == 0)
{
delete this;
}
return cr;
}
//+---------------------------------------------------------------------------
//
// GetInfo
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::GetInfo(_Out_ TF_LANGBARITEMINFO *pInfo)
{
_tfLangBarItemInfo.dwStyle |= TF_LBI_STYLE_SHOWNINTRAY;
*pInfo = _tfLangBarItemInfo;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// GetStatus
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::GetStatus(_Out_ DWORD *pdwStatus)
{
if (pdwStatus == nullptr)
{
E_INVALIDARG;
}
*pdwStatus = _status;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// SetStatus
//
//----------------------------------------------------------------------------
void CLangBarItemButton::SetStatus(DWORD dwStatus, BOOL fSet)
{
BOOL isChange = FALSE;
if (fSet)
{
if (!(_status & dwStatus))
{
_status |= dwStatus;
isChange = TRUE;
}
}
else
{
if (_status & dwStatus)
{
_status &= ~dwStatus;
isChange = TRUE;
}
}
if (isChange && _pLangBarItemSink)
{
_pLangBarItemSink->OnUpdate(TF_LBI_STATUS | TF_LBI_ICON);
}
return;
}
//+---------------------------------------------------------------------------
//
// Show
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::Show(BOOL fShow)
{
fShow;
if (_pLangBarItemSink)
{
_pLangBarItemSink->OnUpdate(TF_LBI_STATUS);
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// GetTooltipString
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::GetTooltipString(_Out_ BSTR *pbstrToolTip)
{
*pbstrToolTip = SysAllocString(_pTooltipText);
return (*pbstrToolTip == nullptr) ? E_OUTOFMEMORY : S_OK;
}
//+---------------------------------------------------------------------------
//
// OnClick
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::OnClick(TfLBIClick click, POINT pt, _In_ const RECT *prcArea)
{
click;pt;
prcArea;
BOOL isOn = FALSE;
_pCompartment->_GetCompartmentBOOL(isOn);
_pCompartment->_SetCompartmentBOOL(isOn ? FALSE : TRUE);
return S_OK;
}
//+---------------------------------------------------------------------------
//
// InitMenu
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::InitMenu(_In_ ITfMenu *pMenu)
{
pMenu;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// OnMenuSelect
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::OnMenuSelect(UINT wID)
{
wID;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// GetIcon
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::GetIcon(_Out_ HICON *phIcon)
{
BOOL isOn = FALSE;
if (!_pCompartment)
{
return E_FAIL;
}
if (!phIcon)
{
return E_FAIL;
}
*phIcon = nullptr;
_pCompartment->_GetCompartmentBOOL(isOn);
DWORD status = 0;
GetStatus(&status);
// If IME is working on the UAC mode, the size of ICON should be 24 x 24.
int desiredSize = 16;
if (_isSecureMode) // detect UAC mode
{
desiredSize = _isSecureMode ? 24 : 16;
}
if (isOn && !(status & TF_LBI_STATUS_DISABLED))
{
if (Global::dllInstanceHandle)
{
*phIcon = reinterpret_cast<HICON>(LoadImage(Global::dllInstanceHandle, MAKEINTRESOURCE(_onIconIndex), IMAGE_ICON, desiredSize, desiredSize, 0));
}
}
else
{
if (Global::dllInstanceHandle)
{
*phIcon = reinterpret_cast<HICON>(LoadImage(Global::dllInstanceHandle, MAKEINTRESOURCE(_offIconIndex), IMAGE_ICON, desiredSize, desiredSize, 0));
}
}
return (*phIcon != NULL) ? S_OK : E_FAIL;
}
//+---------------------------------------------------------------------------
//
// GetText
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::GetText(_Out_ BSTR *pbstrText)
{
*pbstrText = SysAllocString(_tfLangBarItemInfo.szDescription);
return (*pbstrText == nullptr) ? E_OUTOFMEMORY : S_OK;
}
//+---------------------------------------------------------------------------
//
// AdviseSink
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::AdviseSink(__RPC__in REFIID riid, __RPC__in_opt IUnknown *punk, __RPC__out DWORD *pdwCookie)
{
// We allow only ITfLangBarItemSink interface.
if (!IsEqualIID(IID_ITfLangBarItemSink, riid))
{
return CONNECT_E_CANNOTCONNECT;
}
// We support only one sink once.
if (_pLangBarItemSink != nullptr)
{
return CONNECT_E_ADVISELIMIT;
}
// Query the ITfLangBarItemSink interface and store it into _pLangBarItemSink.
if (punk == nullptr)
{
return E_INVALIDARG;
}
if (punk->QueryInterface(IID_ITfLangBarItemSink, (void **)&_pLangBarItemSink) != S_OK)
{
_pLangBarItemSink = nullptr;
return E_NOINTERFACE;
}
// return our cookie.
*pdwCookie = _cookie;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// UnadviseSink
//
//----------------------------------------------------------------------------
STDAPI CLangBarItemButton::UnadviseSink(DWORD dwCookie)
{
// Check the given cookie.
if (dwCookie != _cookie)
{
return CONNECT_E_NOCONNECTION;
}
// If there is nno connected sink, we just fail.
if (_pLangBarItemSink == nullptr)
{
return CONNECT_E_NOCONNECTION;
}
_pLangBarItemSink->Release();
_pLangBarItemSink = nullptr;
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _AddItem
//
//----------------------------------------------------------------------------
HRESULT CLangBarItemButton::_AddItem(_In_ ITfThreadMgr *pThreadMgr)
{
HRESULT hr = S_OK;
ITfLangBarItemMgr* pLangBarItemMgr = nullptr;
if (_isAddedToLanguageBar)
{
return S_OK;
}
hr = pThreadMgr->QueryInterface(IID_ITfLangBarItemMgr, (void **)&pLangBarItemMgr);
if (SUCCEEDED(hr))
{
hr = pLangBarItemMgr->AddItem(this);
if (SUCCEEDED(hr))
{
_isAddedToLanguageBar = TRUE;
}
pLangBarItemMgr->Release();
}
return hr;
}
//+---------------------------------------------------------------------------
//
// _RemoveItem
//
//----------------------------------------------------------------------------
HRESULT CLangBarItemButton::_RemoveItem(_In_ ITfThreadMgr *pThreadMgr)
{
HRESULT hr = S_OK;
ITfLangBarItemMgr* pLangBarItemMgr = nullptr;
if (!_isAddedToLanguageBar)
{
return S_OK;
}
hr = pThreadMgr->QueryInterface(IID_ITfLangBarItemMgr, (void **)&pLangBarItemMgr);
if (SUCCEEDED(hr))
{
hr = pLangBarItemMgr->RemoveItem(this);
if (SUCCEEDED(hr))
{
_isAddedToLanguageBar = FALSE;
}
pLangBarItemMgr->Release();
}
return hr;
}
//+---------------------------------------------------------------------------
//
// _RegisterCompartment
//
//----------------------------------------------------------------------------
BOOL CLangBarItemButton::_RegisterCompartment(_In_ ITfThreadMgr *pThreadMgr, TfClientId tfClientId, REFGUID guidCompartment)
{
_pCompartment = new (std::nothrow) CCompartment(pThreadMgr, tfClientId, guidCompartment);
if (_pCompartment)
{
// Advice ITfCompartmentEventSink
_pCompartmentEventSink = new (std::nothrow) CCompartmentEventSink(_CompartmentCallback, this);
if (_pCompartmentEventSink)
{
_pCompartmentEventSink->_Advise(pThreadMgr, guidCompartment);
}
else
{
delete _pCompartment;
_pCompartment = nullptr;
}
}
return _pCompartment ? TRUE : FALSE;
}
//+---------------------------------------------------------------------------
//
// _UnregisterCompartment
//
//----------------------------------------------------------------------------
BOOL CLangBarItemButton::_UnregisterCompartment(_In_ ITfThreadMgr *pThreadMgr)
{
pThreadMgr;
if (_pCompartment)
{
// Unadvice ITfCompartmentEventSink
if (_pCompartmentEventSink)
{
_pCompartmentEventSink->_Unadvise();
}
// clear ITfCompartment
_pCompartment->_ClearCompartment();
}
return TRUE;
}
//+---------------------------------------------------------------------------
//
// _CompartmentCallback
//
//----------------------------------------------------------------------------
// static
HRESULT CLangBarItemButton::_CompartmentCallback(_In_ void *pv, REFGUID guidCompartment)
{
CLangBarItemButton* fakeThis = (CLangBarItemButton*)pv;
GUID guid = GUID_NULL;
fakeThis->_pCompartment->_GetGUID(&guid);
if (IsEqualGUID(guid, guidCompartment))
{
if (fakeThis->_pLangBarItemSink)
{
fakeThis->_pLangBarItemSink->OnUpdate(TF_LBI_STATUS | TF_LBI_ICON);
}
}
return S_OK;
}
+74
View File
@@ -0,0 +1,74 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
class CCompartment;
class CCompartmentEventSink;
class CLangBarItemButton : public ITfLangBarItemButton,
public ITfSource
{
public:
CLangBarItemButton(REFGUID guidLangBar, LPCWSTR description, LPCWSTR tooltip, DWORD onIconIndex, DWORD offIconIndex, BOOL isSecureMode);
~CLangBarItemButton();
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// ITfLangBarItem
STDMETHODIMP GetInfo(_Out_ TF_LANGBARITEMINFO *pInfo);
STDMETHODIMP GetStatus(_Out_ DWORD *pdwStatus);
STDMETHODIMP Show(BOOL fShow);
STDMETHODIMP GetTooltipString(_Out_ BSTR *pbstrToolTip);
// ITfLangBarItemButton
STDMETHODIMP OnClick(TfLBIClick click, POINT pt, _In_ const RECT *prcArea);
STDMETHODIMP InitMenu(_In_ ITfMenu *pMenu);
STDMETHODIMP OnMenuSelect(UINT wID);
STDMETHODIMP GetIcon(_Out_ HICON *phIcon);
STDMETHODIMP GetText(_Out_ BSTR *pbstrText);
// ITfSource
STDMETHODIMP AdviseSink(__RPC__in REFIID riid, __RPC__in_opt IUnknown *punk, __RPC__out DWORD *pdwCookie);
STDMETHODIMP UnadviseSink(DWORD dwCookie);
// Add/Remove languagebar item
HRESULT _AddItem(_In_ ITfThreadMgr *pThreadMgr);
HRESULT _RemoveItem(_In_ ITfThreadMgr *pThreadMgr);
// Register compartment for button On/Off switch
BOOL _RegisterCompartment(_In_ ITfThreadMgr *pThreadMgr, TfClientId tfClientId, REFGUID guidCompartment);
BOOL _UnregisterCompartment(_In_ ITfThreadMgr *pThreadMgr);
void CleanUp();
void SetStatus(DWORD dwStatus, BOOL fSet);
private:
ITfLangBarItemSink* _pLangBarItemSink;
TF_LANGBARITEMINFO _tfLangBarItemInfo;
LPCWSTR _pTooltipText;
DWORD _onIconIndex;
DWORD _offIconIndex;
BOOL _isAddedToLanguageBar;
BOOL _isSecureMode;
DWORD _status;
CCompartment* _pCompartment;
CCompartmentEventSink* _pCompartmentEventSink;
static HRESULT _CompartmentCallback(_In_ void *pv, REFGUID guidCompartment);
// The cookie for the sink to CLangBarItemButton.
static const DWORD _cookie = 0;
LONG _refCount;
};
+22
View File
@@ -0,0 +1,22 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "stdafx.h"
#include "sal.h"
#include <combaseapi.h>
#include <olectl.h>
#include <assert.h>
#include <strsafe.h>
#include <intsafe.h>
#include "initguid.h"
#include "msctf.h"
#include "ctffunc.h"
+13
View File
@@ -0,0 +1,13 @@
how to install ime
```
regsvr32 "C:\Program Files\SampleIME\SampleIME.dll"
regsvr32 "C:\Program Files (x86)\SampleIME\SampleIME.dll"
```
how to uninstall ime
```shell
regsvr32 /u "C:\Program Files\SampleIME\SampleIME.dll"
regsvr32 /u "C:\Program Files (x86)\SampleIME\SampleIME.dll"
```
+278
View File
@@ -0,0 +1,278 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "RegKey.h"
//---------------------------------------------------------------------
//
// ctor
//
//---------------------------------------------------------------------
CRegKey::CRegKey()
{
_keyHandle = nullptr;
}
//---------------------------------------------------------------------
//
// dtor
//
//---------------------------------------------------------------------
CRegKey::~CRegKey()
{
Close();
}
//---------------------------------------------------------------------
//
// operator
//
//---------------------------------------------------------------------
HKEY CRegKey::GetHKEY()
{
return _keyHandle;
}
//---------------------------------------------------------------------
//
// Create
//
//---------------------------------------------------------------------
LONG CRegKey::Create(_In_ HKEY hKeyPresent, _In_ LPCWSTR pwszKeyName, _In_reads_opt_(255) LPWSTR pwszClass, DWORD dwOptions, REGSAM samDesired, _Inout_ LPSECURITY_ATTRIBUTES lpSecAttr, _Out_opt_ LPDWORD lpdwDisposition)
{
DWORD disposition = 0;
HKEY keyHandle = nullptr;
LONG res = RegCreateKeyEx(hKeyPresent, pwszKeyName, 0,
pwszClass, dwOptions, samDesired, lpSecAttr, &keyHandle, &disposition);
if (lpdwDisposition != nullptr)
{
*lpdwDisposition = disposition;
}
if (res == ERROR_SUCCESS)
{
Close();
_keyHandle = keyHandle;
}
return res;
}
//---------------------------------------------------------------------
//
// Open
//
//---------------------------------------------------------------------
LONG CRegKey::Open(_In_ HKEY hKeyParent, _In_ LPCWSTR pwszKeyName, REGSAM samDesired)
{
HKEY keyHandle = nullptr;
LONG res = RegOpenKeyEx(hKeyParent, pwszKeyName, 0, samDesired, &keyHandle);
if (res == ERROR_SUCCESS)
{
Close();
_keyHandle = keyHandle;
}
return res;
}
//---------------------------------------------------------------------
//
// Close
//
//---------------------------------------------------------------------
LONG CRegKey::Close()
{
LONG res = ERROR_SUCCESS;
if (_keyHandle)
{
res = RegCloseKey(_keyHandle);
_keyHandle = nullptr;
}
return res;
}
//---------------------------------------------------------------------
//
// DeleteSubKey
// RecurseDeleteKey
//
//---------------------------------------------------------------------
LONG CRegKey::DeleteSubKey(_In_ LPCWSTR pwszSubKey)
{
return RegDeleteKey(_keyHandle, pwszSubKey);
}
LONG CRegKey::RecurseDeleteKey(_In_ LPCWSTR pwszSubKey)
{
CRegKey key;
LONG res = key.Open(_keyHandle, pwszSubKey, KEY_READ | KEY_WRITE);
if (res != ERROR_SUCCESS)
{
return res;
}
FILETIME time;
WCHAR subKeyName[256] = {'\0'};
DWORD subKeyNameSize = ARRAYSIZE(subKeyName);
while (RegEnumKeyEx(key.GetHKEY(), 0, subKeyName, &subKeyNameSize, NULL, NULL, NULL, &time) == ERROR_SUCCESS)
{
subKeyName[ARRAYSIZE(subKeyName)-1] = L'\0';
res = key.RecurseDeleteKey(subKeyName);
if (res != ERROR_SUCCESS)
{
return res;
}
subKeyNameSize = ARRAYSIZE(subKeyName);
}
key.Close();
return DeleteSubKey(pwszSubKey);
}
//---------------------------------------------------------------------
//
// DeleteValue
//
//---------------------------------------------------------------------
LONG CRegKey::DeleteValue(_In_ LPCWSTR pwszValue)
{
return RegDeleteValue(_keyHandle, pwszValue);
}
//---------------------------------------------------------------------
//
// QueryStingValue
// SetStringValue
//
//---------------------------------------------------------------------
LONG CRegKey::QueryStringValue(_In_opt_ LPCWSTR pwszValueName, _Out_writes_opt_(*pnChars) LPWSTR pwszValue, _Inout_ ULONG *pnChars)
{
LONG res = 0;
DWORD dataType = REG_NONE;
ULONG pwszValueSize = 0;
if (pnChars == nullptr)
{
return E_INVALIDARG;
}
pwszValueSize = (*pnChars)*sizeof(WCHAR);
*pnChars = 0;
res = RegQueryValueEx(_keyHandle, pwszValueName, NULL, &dataType, (LPBYTE)pwszValue, &pwszValueSize);
if (res != ERROR_SUCCESS)
{
return res;
}
if ((dataType != REG_SZ) && (dataType != REG_EXPAND_SZ))
{
return ERROR_INVALID_DATA;
}
*pnChars = pwszValueSize / sizeof(WCHAR);
return ERROR_SUCCESS;
}
LONG CRegKey::SetStringValue(_In_opt_ LPCWSTR pwszValueName, _In_ LPCWSTR pwszValue, DWORD dwType)
{
size_t lenOfValue = 0;
if (pwszValue == nullptr)
{
return ERROR_INVALID_PARAMETER;
}
if (StringCchLength(pwszValue, STRSAFE_MAX_CCH, &lenOfValue) != S_OK)
{
return ERROR_INVALID_PARAMETER;
}
DWORD len = static_cast<DWORD>(lenOfValue);
return RegSetValueEx(_keyHandle, pwszValueName, NULL, dwType, (LPBYTE)pwszValue, (++len)*sizeof(WCHAR));
}
//---------------------------------------------------------------------
//
// QueryDWORDValue
// SetDWORDValue
//
//---------------------------------------------------------------------
LONG CRegKey::QueryDWORDValue(_In_opt_ LPCWSTR pwszValueName, _Out_ DWORD &dwValue)
{
LONG res = 0;
DWORD dataType = REG_NONE;
ULONG pwszValueSize = 0;
pwszValueSize = sizeof(DWORD);
res = RegQueryValueEx(_keyHandle, pwszValueName, NULL, &dataType, (LPBYTE)(&dwValue), &pwszValueSize);
if (res != ERROR_SUCCESS)
{
return res;
}
if (dataType != REG_DWORD)
{
return ERROR_INVALID_DATA;
}
return ERROR_SUCCESS;
}
LONG CRegKey::SetDWORDValue(_In_opt_ LPCWSTR pwszValueName, DWORD dwValue)
{
return RegSetValueEx(_keyHandle, pwszValueName, NULL, REG_DWORD, (LPBYTE)(&dwValue), sizeof(DWORD));
}
//---------------------------------------------------------------------
//
// QueryBinaryValue
// SetBinaryValue
//
//---------------------------------------------------------------------
LONG CRegKey::QueryBinaryValue(_In_opt_ LPCWSTR pwszValueName, _Out_writes_opt_(cbData) BYTE* lpData, DWORD cbData)
{
LONG res = 0;
DWORD dataType = REG_NONE;
ULONG pwszValueSize = 0;
pwszValueSize = cbData;
res = RegQueryValueEx(_keyHandle, pwszValueName, NULL, &dataType, lpData, &pwszValueSize);
if (res != ERROR_SUCCESS)
{
return res;
}
if (dataType != REG_BINARY)
{
return ERROR_INVALID_DATA;
}
if (pwszValueSize != cbData)
{
return ERROR_INVALID_DATA;
}
return ERROR_SUCCESS;
}
LONG CRegKey::SetBinaryValue(_In_opt_ LPCWSTR pwszValueName, _In_reads_(cbData) BYTE* lpData, DWORD cbData)
{
return RegSetValueEx(_keyHandle, pwszValueName, NULL, REG_BINARY, lpData, cbData);
}
+45
View File
@@ -0,0 +1,45 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
class CRegKey
{
public:
CRegKey();
~CRegKey();
HKEY GetHKEY();
LONG Create(_In_ HKEY hKeyPresent, _In_ LPCWSTR pwszKeyName,
_In_reads_opt_(255) LPWSTR pwszClass = REG_NONE,
DWORD dwOptions = REG_OPTION_NON_VOLATILE,
REGSAM samDesired = KEY_READ | KEY_WRITE,
_Inout_ LPSECURITY_ATTRIBUTES lpSecAttr = nullptr,
_Out_opt_ LPDWORD lpdwDisposition = nullptr);
LONG Open(_In_ HKEY hKeyParent, _In_ LPCWSTR pwszKeyName,
REGSAM samDesired = KEY_READ | KEY_WRITE);
LONG Close();
LONG DeleteSubKey(_In_ LPCWSTR pwszSubKey);
LONG RecurseDeleteKey(_In_ LPCWSTR pwszSubKey);
LONG DeleteValue(_In_ LPCWSTR pwszValue);
LONG QueryStringValue(_In_opt_ LPCWSTR pwszValueName, _Out_writes_opt_(*pnChars) LPWSTR pwszValue, _Inout_ ULONG *pnChars);
LONG SetStringValue(_In_opt_ LPCWSTR pwszValueName, _In_ LPCWSTR pwszValue, DWORD dwType = REG_SZ);
LONG QueryDWORDValue(_In_opt_ LPCWSTR pwszValueName, _Out_ DWORD &dwValue);
LONG SetDWORDValue(_In_opt_ LPCWSTR pwszValueName, DWORD dwValue);
LONG QueryBinaryValue(_In_opt_ LPCWSTR pwszValueName, _Out_writes_opt_(cbData) BYTE* lpData, DWORD cbData);
LONG SetBinaryValue(_In_opt_ LPCWSTR pwszValueName, _In_reads_(cbData) BYTE* lpData, DWORD cbData);
private:
HKEY _keyHandle;
};
+283
View File
@@ -0,0 +1,283 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
static const WCHAR RegInfo_Prefix_CLSID[] = L"CLSID\\";
static const WCHAR RegInfo_Key_InProSvr32[] = L"InProcServer32";
static const WCHAR RegInfo_Key_ThreadModel[] = L"ThreadingModel";
static const WCHAR TEXTSERVICE_DESC[] = L"Sample IME";
static const GUID SupportCategories[] = {
GUID_TFCAT_TIP_KEYBOARD,
GUID_TFCAT_DISPLAYATTRIBUTEPROVIDER,
GUID_TFCAT_TIPCAP_UIELEMENTENABLED,
GUID_TFCAT_TIPCAP_SECUREMODE,
GUID_TFCAT_TIPCAP_COMLESS,
GUID_TFCAT_TIPCAP_INPUTMODECOMPARTMENT,
GUID_TFCAT_TIPCAP_IMMERSIVESUPPORT,
GUID_TFCAT_TIPCAP_SYSTRAYSUPPORT,
};
//+---------------------------------------------------------------------------
//
// RegisterProfiles
//
//----------------------------------------------------------------------------
BOOL RegisterProfiles()
{
HRESULT hr = S_FALSE;
ITfInputProcessorProfileMgr *pITfInputProcessorProfileMgr = nullptr;
hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfileMgr, (void**)&pITfInputProcessorProfileMgr);
if (FAILED(hr))
{
return FALSE;
}
WCHAR achIconFile[MAX_PATH] = {'\0'};
DWORD cchA = 0;
cchA = GetModuleFileName(Global::dllInstanceHandle, achIconFile, MAX_PATH);
cchA = cchA >= MAX_PATH ? (MAX_PATH - 1) : cchA;
achIconFile[cchA] = '\0';
size_t lenOfDesc = 0;
hr = StringCchLength(TEXTSERVICE_DESC, STRSAFE_MAX_CCH, &lenOfDesc);
if (hr != S_OK)
{
goto Exit;
}
hr = pITfInputProcessorProfileMgr->RegisterProfile(Global::SampleIMECLSID,
TEXTSERVICE_LANGID,
Global::SampleIMEGuidProfile,
TEXTSERVICE_DESC,
static_cast<ULONG>(lenOfDesc),
achIconFile,
cchA,
(UINT)TEXTSERVICE_ICON_INDEX, NULL, 0, TRUE, 0);
if (FAILED(hr))
{
goto Exit;
}
Exit:
if (pITfInputProcessorProfileMgr)
{
pITfInputProcessorProfileMgr->Release();
}
return (hr == S_OK);
}
//+---------------------------------------------------------------------------
//
// UnregisterProfiles
//
//----------------------------------------------------------------------------
void UnregisterProfiles()
{
HRESULT hr = S_OK;
ITfInputProcessorProfileMgr *pITfInputProcessorProfileMgr = nullptr;
hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfileMgr, (void**)&pITfInputProcessorProfileMgr);
if (FAILED(hr))
{
goto Exit;
}
hr = pITfInputProcessorProfileMgr->UnregisterProfile(Global::SampleIMECLSID, TEXTSERVICE_LANGID, Global::SampleIMEGuidProfile, 0);
if (FAILED(hr))
{
goto Exit;
}
Exit:
if (pITfInputProcessorProfileMgr)
{
pITfInputProcessorProfileMgr->Release();
}
return;
}
//+---------------------------------------------------------------------------
//
// RegisterCategories
//
//----------------------------------------------------------------------------
BOOL RegisterCategories()
{
ITfCategoryMgr* pCategoryMgr = nullptr;
HRESULT hr = S_OK;
hr = CoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfCategoryMgr, (void**)&pCategoryMgr);
if (FAILED(hr))
{
return FALSE;
}
for each(GUID guid in SupportCategories)
{
hr = pCategoryMgr->RegisterCategory(Global::SampleIMECLSID, guid, Global::SampleIMECLSID);
}
pCategoryMgr->Release();
return (hr == S_OK);
}
//+---------------------------------------------------------------------------
//
// UnregisterCategories
//
//----------------------------------------------------------------------------
void UnregisterCategories()
{
ITfCategoryMgr* pCategoryMgr = S_OK;
HRESULT hr = S_OK;
hr = CoCreateInstance(CLSID_TF_CategoryMgr, NULL, CLSCTX_INPROC_SERVER, IID_ITfCategoryMgr, (void**)&pCategoryMgr);
if (FAILED(hr))
{
return;
}
for each(GUID guid in SupportCategories)
{
pCategoryMgr->UnregisterCategory(Global::SampleIMECLSID, guid, Global::SampleIMECLSID);
}
pCategoryMgr->Release();
return;
}
//+---------------------------------------------------------------------------
//
// RecurseDeleteKey
//
// RecurseDeleteKey is necessary because on NT RegDeleteKey doesn't work if the
// specified key has subkeys
//----------------------------------------------------------------------------
LONG RecurseDeleteKey(_In_ HKEY hParentKey, _In_ LPCTSTR lpszKey)
{
HKEY regKeyHandle = nullptr;
LONG res = 0;
FILETIME time;
WCHAR stringBuffer[256] = {'\0'};
DWORD size = ARRAYSIZE(stringBuffer);
if (RegOpenKey(hParentKey, lpszKey, &regKeyHandle) != ERROR_SUCCESS)
{
return ERROR_SUCCESS;
}
res = ERROR_SUCCESS;
while (RegEnumKeyEx(regKeyHandle, 0, stringBuffer, &size, NULL, NULL, NULL, &time) == ERROR_SUCCESS)
{
stringBuffer[ARRAYSIZE(stringBuffer)-1] = '\0';
res = RecurseDeleteKey(regKeyHandle, stringBuffer);
if (res != ERROR_SUCCESS)
{
break;
}
size = ARRAYSIZE(stringBuffer);
}
RegCloseKey(regKeyHandle);
return res == ERROR_SUCCESS ? RegDeleteKey(hParentKey, lpszKey) : res;
}
//+---------------------------------------------------------------------------
//
// RegisterServer
//
//----------------------------------------------------------------------------
BOOL RegisterServer()
{
DWORD copiedStringLen = 0;
HKEY regKeyHandle = nullptr;
HKEY regSubkeyHandle = nullptr;
BOOL ret = FALSE;
WCHAR achIMEKey[ARRAYSIZE(RegInfo_Prefix_CLSID) + CLSID_STRLEN] = {'\0'};
WCHAR achFileName[MAX_PATH] = {'\0'};
if (!CLSIDToString(Global::SampleIMECLSID, achIMEKey + ARRAYSIZE(RegInfo_Prefix_CLSID) - 1))
{
return FALSE;
}
memcpy(achIMEKey, RegInfo_Prefix_CLSID, sizeof(RegInfo_Prefix_CLSID) - sizeof(WCHAR));
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, achIMEKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &regKeyHandle, &copiedStringLen) == ERROR_SUCCESS)
{
if (RegSetValueEx(regKeyHandle, NULL, 0, REG_SZ, (const BYTE *)TEXTSERVICE_DESC, (_countof(TEXTSERVICE_DESC))*sizeof(WCHAR)) != ERROR_SUCCESS)
{
goto Exit;
}
if (RegCreateKeyEx(regKeyHandle, RegInfo_Key_InProSvr32, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &regSubkeyHandle, &copiedStringLen) == ERROR_SUCCESS)
{
copiedStringLen = GetModuleFileNameW(Global::dllInstanceHandle, achFileName, ARRAYSIZE(achFileName));
copiedStringLen = (copiedStringLen >= (MAX_PATH - 1)) ? MAX_PATH : (++copiedStringLen);
if (RegSetValueEx(regSubkeyHandle, NULL, 0, REG_SZ, (const BYTE *)achFileName, (copiedStringLen)*sizeof(WCHAR)) != ERROR_SUCCESS)
{
goto Exit;
}
if (RegSetValueEx(regSubkeyHandle, RegInfo_Key_ThreadModel, 0, REG_SZ, (const BYTE *)TEXTSERVICE_MODEL, (_countof(TEXTSERVICE_MODEL)) * sizeof(WCHAR)) != ERROR_SUCCESS)
{
goto Exit;
}
ret = TRUE;
}
}
Exit:
if (regSubkeyHandle)
{
RegCloseKey(regSubkeyHandle);
regSubkeyHandle = nullptr;
}
if (regKeyHandle)
{
RegCloseKey(regKeyHandle);
regKeyHandle = nullptr;
}
return ret;
}
//+---------------------------------------------------------------------------
//
// UnregisterServer
//
//----------------------------------------------------------------------------
void UnregisterServer()
{
WCHAR achIMEKey[ARRAYSIZE(RegInfo_Prefix_CLSID) + CLSID_STRLEN] = {'\0'};
if (!CLSIDToString(Global::SampleIMECLSID, achIMEKey + ARRAYSIZE(RegInfo_Prefix_CLSID) - 1))
{
return;
}
memcpy(achIMEKey, RegInfo_Prefix_CLSID, sizeof(RegInfo_Prefix_CLSID) - sizeof(WCHAR));
RecurseDeleteKey(HKEY_CLASSES_ROOT, achIMEKey);
}
+432
View File
@@ -0,0 +1,432 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "globals.h"
#include "SampleIME.h"
#include "CandidateListUIPresenter.h"
#include "CompositionProcessorEngine.h"
#include "Compartment.h"
//+---------------------------------------------------------------------------
//
// CreateInstance
//
//----------------------------------------------------------------------------
/* static */
HRESULT CSampleIME::CreateInstance(_In_ IUnknown *pUnkOuter, REFIID riid, _Outptr_ void **ppvObj)
{
CSampleIME* pSampleIME = nullptr;
HRESULT hr = S_OK;
if (ppvObj == nullptr)
{
return E_INVALIDARG;
}
*ppvObj = nullptr;
if (nullptr != pUnkOuter)
{
return CLASS_E_NOAGGREGATION;
}
pSampleIME = new (std::nothrow) CSampleIME();
if (pSampleIME == nullptr)
{
return E_OUTOFMEMORY;
}
hr = pSampleIME->QueryInterface(riid, ppvObj);
pSampleIME->Release();
return hr;
}
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CSampleIME::CSampleIME()
{
DllAddRef();
_pThreadMgr = nullptr;
_threadMgrEventSinkCookie = TF_INVALID_COOKIE;
_pTextEditSinkContext = nullptr;
_textEditSinkCookie = TF_INVALID_COOKIE;
_activeLanguageProfileNotifySinkCookie = TF_INVALID_COOKIE;
_dwThreadFocusSinkCookie = TF_INVALID_COOKIE;
_pComposition = nullptr;
_pCompositionProcessorEngine = nullptr;
_candidateMode = CANDIDATE_NONE;
_pCandidateListUIPresenter = nullptr;
_isCandidateWithWildcard = FALSE;
_pDocMgrLastFocused = nullptr;
_pSIPIMEOnOffCompartment = nullptr;
_dwSIPIMEOnOffCompartmentSinkCookie = 0;
_msgWndHandle = nullptr;
_pContext = nullptr;
_refCount = 1;
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CSampleIME::~CSampleIME()
{
if (_pCandidateListUIPresenter)
{
delete _pCandidateListUIPresenter;
_pCandidateListUIPresenter = nullptr;
}
DllRelease();
}
//+---------------------------------------------------------------------------
//
// QueryInterface
//
//----------------------------------------------------------------------------
STDAPI CSampleIME::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
{
return E_INVALIDARG;
}
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_ITfTextInputProcessor))
{
*ppvObj = (ITfTextInputProcessor *)this;
}
else if (IsEqualIID(riid, IID_ITfTextInputProcessorEx))
{
*ppvObj = (ITfTextInputProcessorEx *)this;
}
else if (IsEqualIID(riid, IID_ITfThreadMgrEventSink))
{
*ppvObj = (ITfThreadMgrEventSink *)this;
}
else if (IsEqualIID(riid, IID_ITfTextEditSink))
{
*ppvObj = (ITfTextEditSink *)this;
}
else if (IsEqualIID(riid, IID_ITfKeyEventSink))
{
*ppvObj = (ITfKeyEventSink *)this;
}
else if (IsEqualIID(riid, IID_ITfActiveLanguageProfileNotifySink))
{
*ppvObj = (ITfActiveLanguageProfileNotifySink *)this;
}
else if (IsEqualIID(riid, IID_ITfCompositionSink))
{
*ppvObj = (ITfKeyEventSink *)this;
}
else if (IsEqualIID(riid, IID_ITfDisplayAttributeProvider))
{
*ppvObj = (ITfDisplayAttributeProvider *)this;
}
else if (IsEqualIID(riid, IID_ITfThreadFocusSink))
{
*ppvObj = (ITfThreadFocusSink *)this;
}
else if (IsEqualIID(riid, IID_ITfFunctionProvider))
{
*ppvObj = (ITfFunctionProvider *)this;
}
else if (IsEqualIID(riid, IID_ITfFunction))
{
*ppvObj = (ITfFunction *)this;
}
else if (IsEqualIID(riid, IID_ITfFnGetPreferredTouchKeyboardLayout))
{
*ppvObj = (ITfFnGetPreferredTouchKeyboardLayout *)this;
}
if (*ppvObj)
{
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
//+---------------------------------------------------------------------------
//
// AddRef
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CSampleIME::AddRef()
{
return ++_refCount;
}
//+---------------------------------------------------------------------------
//
// Release
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CSampleIME::Release()
{
LONG cr = --_refCount;
assert(_refCount >= 0);
if (_refCount == 0)
{
delete this;
}
return cr;
}
//+---------------------------------------------------------------------------
//
// ITfTextInputProcessorEx::ActivateEx
//
//----------------------------------------------------------------------------
STDAPI CSampleIME::ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClientId, DWORD dwFlags)
{
_pThreadMgr = pThreadMgr;
_pThreadMgr->AddRef();
_tfClientId = tfClientId;
_dwActivateFlags = dwFlags;
if (!_InitThreadMgrEventSink())
{
goto ExitError;
}
ITfDocumentMgr* pDocMgrFocus = nullptr;
if (SUCCEEDED(_pThreadMgr->GetFocus(&pDocMgrFocus)) && (pDocMgrFocus != nullptr))
{
_InitTextEditSink(pDocMgrFocus);
pDocMgrFocus->Release();
}
if (!_InitKeyEventSink())
{
goto ExitError;
}
if (!_InitActiveLanguageProfileNotifySink())
{
goto ExitError;
}
if (!_InitThreadFocusSink())
{
goto ExitError;
}
if (!_InitDisplayAttributeGuidAtom())
{
goto ExitError;
}
if (!_InitFunctionProviderSink())
{
goto ExitError;
}
if (!_AddTextProcessorEngine())
{
goto ExitError;
}
return S_OK;
ExitError:
Deactivate();
return E_FAIL;
}
//+---------------------------------------------------------------------------
//
// ITfTextInputProcessorEx::Deactivate
//
//----------------------------------------------------------------------------
STDAPI CSampleIME::Deactivate()
{
if (_pCompositionProcessorEngine)
{
delete _pCompositionProcessorEngine;
_pCompositionProcessorEngine = nullptr;
}
ITfContext* pContext = _pContext;
if (_pContext)
{
pContext->AddRef();
_EndComposition(_pContext);
}
if (_pCandidateListUIPresenter)
{
delete _pCandidateListUIPresenter;
_pCandidateListUIPresenter = nullptr;
if (pContext)
{
pContext->Release();
}
_candidateMode = CANDIDATE_NONE;
_isCandidateWithWildcard = FALSE;
}
_UninitFunctionProviderSink();
_UninitThreadFocusSink();
_UninitActiveLanguageProfileNotifySink();
_UninitKeyEventSink();
_UninitThreadMgrEventSink();
CCompartment CompartmentKeyboardOpen(_pThreadMgr, _tfClientId, GUID_COMPARTMENT_KEYBOARD_OPENCLOSE);
CompartmentKeyboardOpen._ClearCompartment();
CCompartment CompartmentDoubleSingleByte(_pThreadMgr, _tfClientId, Global::SampleIMEGuidCompartmentDoubleSingleByte);
CompartmentDoubleSingleByte._ClearCompartment();
CCompartment CompartmentPunctuation(_pThreadMgr, _tfClientId, Global::SampleIMEGuidCompartmentPunctuation);
CompartmentDoubleSingleByte._ClearCompartment();
if (_pThreadMgr != nullptr)
{
_pThreadMgr->Release();
}
_tfClientId = TF_CLIENTID_NULL;
if (_pDocMgrLastFocused)
{
_pDocMgrLastFocused->Release();
_pDocMgrLastFocused = nullptr;
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfFunctionProvider::GetType
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::GetType(__RPC__out GUID *pguid)
{
HRESULT hr = E_INVALIDARG;
if (pguid)
{
*pguid = Global::SampleIMECLSID;
hr = S_OK;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// ITfFunctionProvider::::GetDescription
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::GetDescription(__RPC__deref_out_opt BSTR *pbstrDesc)
{
HRESULT hr = E_INVALIDARG;
if (pbstrDesc != nullptr)
{
*pbstrDesc = nullptr;
hr = E_NOTIMPL;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// ITfFunctionProvider::::GetFunction
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::GetFunction(__RPC__in REFGUID rguid, __RPC__in REFIID riid, __RPC__deref_out_opt IUnknown **ppunk)
{
HRESULT hr = E_NOINTERFACE;
if ((IsEqualGUID(rguid, GUID_NULL))
&& (IsEqualGUID(riid, __uuidof(ITfFnSearchCandidateProvider))))
{
hr = _pITfFnSearchCandidateProvider->QueryInterface(riid, (void**)ppunk);
}
else if (IsEqualGUID(rguid, GUID_NULL))
{
hr = QueryInterface(riid, (void **)ppunk);
}
return hr;
}
//+---------------------------------------------------------------------------
//
// ITfFunction::GetDisplayName
//
//----------------------------------------------------------------------------
HRESULT CSampleIME::GetDisplayName(_Out_ BSTR *pbstrDisplayName)
{
HRESULT hr = E_INVALIDARG;
if (pbstrDisplayName != nullptr)
{
*pbstrDisplayName = nullptr;
hr = E_NOTIMPL;
}
return hr;
}
//+---------------------------------------------------------------------------
//
// ITfFnGetPreferredTouchKeyboardLayout::GetLayout
// The tkblayout will be Optimized layout.
//----------------------------------------------------------------------------
HRESULT CSampleIME::GetLayout(_Out_ TKBLayoutType *ptkblayoutType, _Out_ WORD *pwPreferredLayoutId)
{
HRESULT hr = E_INVALIDARG;
if ((ptkblayoutType != nullptr) && (pwPreferredLayoutId != nullptr))
{
*ptkblayoutType = TKBLT_OPTIMIZED;
*pwPreferredLayoutId = TKBL_OPT_SIMPLIFIED_CHINESE_PINYIN;
hr = S_OK;
}
return hr;
}
+7
View File
@@ -0,0 +1,7 @@
LIBRARY SampleIME.dll
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
+248
View File
@@ -0,0 +1,248 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "KeyHandlerEditSession.h"
#include "SampleIMEBaseStructure.h"
class CLangBarItemButton;
class CCandidateListUIPresenter;
class CCompositionProcessorEngine;
const DWORD WM_CheckGlobalCompartment = WM_USER;
LRESULT CALLBACK CSampleIME_WindowProc(HWND wndHandle, UINT uMsg, WPARAM wParam, LPARAM lParam);
class CSampleIME : public ITfTextInputProcessorEx,
public ITfThreadMgrEventSink,
public ITfTextEditSink,
public ITfKeyEventSink,
public ITfCompositionSink,
public ITfDisplayAttributeProvider,
public ITfActiveLanguageProfileNotifySink,
public ITfThreadFocusSink,
public ITfFunctionProvider,
public ITfFnGetPreferredTouchKeyboardLayout
{
public:
CSampleIME();
~CSampleIME();
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// ITfTextInputProcessor
STDMETHODIMP Activate(ITfThreadMgr *pThreadMgr, TfClientId tfClientId) {
return ActivateEx(pThreadMgr, tfClientId, 0);
}
// ITfTextInputProcessorEx
STDMETHODIMP ActivateEx(ITfThreadMgr *pThreadMgr, TfClientId tfClientId, DWORD dwFlags);
STDMETHODIMP Deactivate();
// ITfThreadMgrEventSink
STDMETHODIMP OnInitDocumentMgr(_In_ ITfDocumentMgr *pDocMgr);
STDMETHODIMP OnUninitDocumentMgr(_In_ ITfDocumentMgr *pDocMgr);
STDMETHODIMP OnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus, _In_ ITfDocumentMgr *pDocMgrPrevFocus);
STDMETHODIMP OnPushContext(_In_ ITfContext *pContext);
STDMETHODIMP OnPopContext(_In_ ITfContext *pContext);
// ITfTextEditSink
STDMETHODIMP OnEndEdit(__RPC__in_opt ITfContext *pContext, TfEditCookie ecReadOnly, __RPC__in_opt ITfEditRecord *pEditRecord);
// ITfKeyEventSink
STDMETHODIMP OnSetFocus(BOOL fForeground);
STDMETHODIMP OnTestKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten);
STDMETHODIMP OnKeyDown(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten);
STDMETHODIMP OnTestKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten);
STDMETHODIMP OnKeyUp(ITfContext *pContext, WPARAM wParam, LPARAM lParam, BOOL *pIsEaten);
STDMETHODIMP OnPreservedKey(ITfContext *pContext, REFGUID rguid, BOOL *pIsEaten);
// ITfCompositionSink
STDMETHODIMP OnCompositionTerminated(TfEditCookie ecWrite, _In_ ITfComposition *pComposition);
// ITfDisplayAttributeProvider
STDMETHODIMP EnumDisplayAttributeInfo(__RPC__deref_out_opt IEnumTfDisplayAttributeInfo **ppEnum);
STDMETHODIMP GetDisplayAttributeInfo(__RPC__in REFGUID guidInfo, __RPC__deref_out_opt ITfDisplayAttributeInfo **ppInfo);
// ITfActiveLanguageProfileNotifySink
STDMETHODIMP OnActivated(_In_ REFCLSID clsid, _In_ REFGUID guidProfile, _In_ BOOL isActivated);
// ITfThreadFocusSink
STDMETHODIMP OnSetThreadFocus();
STDMETHODIMP OnKillThreadFocus();
// ITfFunctionProvider
STDMETHODIMP GetType(__RPC__out GUID *pguid);
STDMETHODIMP GetDescription(__RPC__deref_out_opt BSTR *pbstrDesc);
STDMETHODIMP GetFunction(__RPC__in REFGUID rguid, __RPC__in REFIID riid, __RPC__deref_out_opt IUnknown **ppunk);
// ITfFunction
STDMETHODIMP GetDisplayName(_Out_ BSTR *pbstrDisplayName);
// ITfFnGetPreferredTouchKeyboardLayout, it is the Optimized layout feature.
STDMETHODIMP GetLayout(_Out_ TKBLayoutType *ptkblayoutType, _Out_ WORD *pwPreferredLayoutId);
// CClassFactory factory callback
static HRESULT CreateInstance(_In_ IUnknown *pUnkOuter, REFIID riid, _Outptr_ void **ppvObj);
// utility function for thread manager.
ITfThreadMgr* _GetThreadMgr() { return _pThreadMgr; }
TfClientId _GetClientId() { return _tfClientId; }
// functions for the composition object.
void _SetComposition(_In_ ITfComposition *pComposition);
void _TerminateComposition(TfEditCookie ec, _In_ ITfContext *pContext, BOOL isCalledFromDeactivate = FALSE);
void _SaveCompositionContext(_In_ ITfContext *pContext);
// key event handlers for composition/candidate/phrase common objects.
HRESULT _HandleComplete(TfEditCookie ec, _In_ ITfContext *pContext);
HRESULT _HandleCancel(TfEditCookie ec, _In_ ITfContext *pContext);
// key event handlers for composition object.
HRESULT _HandleCompositionInput(TfEditCookie ec, _In_ ITfContext *pContext, WCHAR wch);
HRESULT _HandleCompositionFinalize(TfEditCookie ec, _In_ ITfContext *pContext, BOOL fCandidateList);
HRESULT _HandleCompositionConvert(TfEditCookie ec, _In_ ITfContext *pContext, BOOL isWildcardSearch);
HRESULT _HandleCompositionBackspace(TfEditCookie ec, _In_ ITfContext *pContext);
HRESULT _HandleCompositionArrowKey(TfEditCookie ec, _In_ ITfContext *pContext, KEYSTROKE_FUNCTION keyFunction);
HRESULT _HandleCompositionPunctuation(TfEditCookie ec, _In_ ITfContext *pContext, WCHAR wch);
HRESULT _HandleCompositionDoubleSingleByte(TfEditCookie ec, _In_ ITfContext *pContext, WCHAR wch);
// key event handlers for candidate object.
HRESULT _HandleCandidateFinalize(TfEditCookie ec, _In_ ITfContext *pContext);
HRESULT _HandleCandidateConvert(TfEditCookie ec, _In_ ITfContext *pContext);
HRESULT _HandleCandidateArrowKey(TfEditCookie ec, _In_ ITfContext *pContext, _In_ KEYSTROKE_FUNCTION keyFunction);
HRESULT _HandleCandidateSelectByNumber(TfEditCookie ec, _In_ ITfContext *pContext, _In_ UINT uCode);
// key event handlers for phrase object.
HRESULT _HandlePhraseFinalize(TfEditCookie ec, _In_ ITfContext *pContext);
HRESULT _HandlePhraseArrowKey(TfEditCookie ec, _In_ ITfContext *pContext, _In_ KEYSTROKE_FUNCTION keyFunction);
HRESULT _HandlePhraseSelectByNumber(TfEditCookie ec, _In_ ITfContext *pContext, _In_ UINT uCode);
BOOL _IsSecureMode(void) { return (_dwActivateFlags & TF_TMAE_SECUREMODE) ? TRUE : FALSE; }
BOOL _IsComLess(void) { return (_dwActivateFlags & TF_TMAE_COMLESS) ? TRUE : FALSE; }
BOOL _IsStoreAppMode(void) { return (_dwActivateFlags & TF_TMF_IMMERSIVEMODE) ? TRUE : FALSE; };
CCompositionProcessorEngine* GetCompositionProcessorEngine() { return (_pCompositionProcessorEngine); };
// comless helpers
static HRESULT CSampleIME::CreateInstance(REFCLSID rclsid, REFIID riid, _Outptr_result_maybenull_ LPVOID* ppv, _Out_opt_ HINSTANCE* phInst, BOOL isComLessMode);
static HRESULT CSampleIME::ComLessCreateInstance(REFGUID rclsid, REFIID riid, _Outptr_result_maybenull_ void **ppv, _Out_opt_ HINSTANCE *phInst);
static HRESULT CSampleIME::GetComModuleName(REFGUID rclsid, _Out_writes_(cchPath)WCHAR* wchPath, DWORD cchPath);
private:
// functions for the composition object.
HRESULT _HandleCompositionInputWorker(_In_ CCompositionProcessorEngine *pCompositionProcessorEngine, TfEditCookie ec, _In_ ITfContext *pContext);
HRESULT _CreateAndStartCandidate(_In_ CCompositionProcessorEngine *pCompositionProcessorEngine, TfEditCookie ec, _In_ ITfContext *pContext);
HRESULT _HandleCandidateWorker(TfEditCookie ec, _In_ ITfContext *pContext);
void _StartComposition(_In_ ITfContext *pContext);
void _EndComposition(_In_opt_ ITfContext *pContext);
BOOL _IsComposing();
BOOL _IsKeyboardDisabled();
HRESULT _AddComposingAndChar(TfEditCookie ec, _In_ ITfContext *pContext, _In_ CStringRange *pstrAddString);
HRESULT _AddCharAndFinalize(TfEditCookie ec, _In_ ITfContext *pContext, _In_ CStringRange *pstrAddString);
BOOL _FindComposingRange(TfEditCookie ec, _In_ ITfContext *pContext, _In_ ITfRange *pSelection, _Outptr_result_maybenull_ ITfRange **ppRange);
HRESULT _SetInputString(TfEditCookie ec, _In_ ITfContext *pContext, _Out_opt_ ITfRange *pRange, _In_ CStringRange *pstrAddString, BOOL exist_composing);
HRESULT _InsertAtSelection(TfEditCookie ec, _In_ ITfContext *pContext, _In_ CStringRange *pstrAddString, _Outptr_ ITfRange **ppCompRange);
HRESULT _RemoveDummyCompositionForComposing(TfEditCookie ec, _In_ ITfComposition *pComposition);
// Invoke key handler edit session
HRESULT _InvokeKeyHandler(_In_ ITfContext *pContext, UINT code, WCHAR wch, DWORD flags, _KEYSTROKE_STATE keyState);
// function for the language property
BOOL _SetCompositionLanguage(TfEditCookie ec, _In_ ITfContext *pContext);
// function for the display attribute
void _ClearCompositionDisplayAttributes(TfEditCookie ec, _In_ ITfContext *pContext);
BOOL _SetCompositionDisplayAttributes(TfEditCookie ec, _In_ ITfContext *pContext, TfGuidAtom gaDisplayAttribute);
BOOL _InitDisplayAttributeGuidAtom();
BOOL _InitThreadMgrEventSink();
void _UninitThreadMgrEventSink();
BOOL _InitTextEditSink(_In_ ITfDocumentMgr *pDocMgr);
void _UpdateLanguageBarOnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus);
BOOL _InitKeyEventSink();
void _UninitKeyEventSink();
BOOL _InitActiveLanguageProfileNotifySink();
void _UninitActiveLanguageProfileNotifySink();
BOOL _IsKeyEaten(_In_ ITfContext *pContext, UINT codeIn, _Out_ UINT *pCodeOut, _Out_writes_(1) WCHAR *pwch, _Out_opt_ _KEYSTROKE_STATE *pKeyState);
BOOL _IsRangeCovered(TfEditCookie ec, _In_ ITfRange *pRangeTest, _In_ ITfRange *pRangeCover);
VOID _DeleteCandidateList(BOOL fForce, _In_opt_ ITfContext *pContext);
WCHAR ConvertVKey(UINT code);
BOOL _InitThreadFocusSink();
void _UninitThreadFocusSink();
BOOL _InitFunctionProviderSink();
void _UninitFunctionProviderSink();
BOOL _AddTextProcessorEngine();
BOOL VerifySampleIMECLSID(_In_ REFCLSID clsid);
friend LRESULT CALLBACK CSampleIME_WindowProc(HWND wndHandle, UINT uMsg, WPARAM wParam, LPARAM lParam);
private:
ITfThreadMgr* _pThreadMgr;
TfClientId _tfClientId;
DWORD _dwActivateFlags;
// The cookie of ThreadMgrEventSink
DWORD _threadMgrEventSinkCookie;
ITfContext* _pTextEditSinkContext;
DWORD _textEditSinkCookie;
// The cookie of ActiveLanguageProfileNotifySink
DWORD _activeLanguageProfileNotifySinkCookie;
// The cookie of ThreadFocusSink
DWORD _dwThreadFocusSinkCookie;
// Composition Processor Engine object.
CCompositionProcessorEngine* _pCompositionProcessorEngine;
// Language bar item object.
CLangBarItemButton* _pLangBarItem;
// the current composition object.
ITfComposition* _pComposition;
// guidatom for the display attibute.
TfGuidAtom _gaDisplayAttributeInput;
TfGuidAtom _gaDisplayAttributeConverted;
CANDIDATE_MODE _candidateMode;
CCandidateListUIPresenter *_pCandidateListUIPresenter;
BOOL _isCandidateWithWildcard : 1;
ITfDocumentMgr* _pDocMgrLastFocused;
ITfContext* _pContext;
ITfCompartment* _pSIPIMEOnOffCompartment;
DWORD _dwSIPIMEOnOffCompartmentSinkCookie;
HWND _msgWndHandle;
LONG _refCount;
// Support the search integration
ITfFnSearchCandidateProvider* _pITfFnSearchCandidateProvider;
};
+122
View File
@@ -0,0 +1,122 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
/////////////////////////////////////////////////////////////////////////////
// English (United States) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDIS_SAMPLEIME ICON "image\\SampleIme.ico"
IDI_IME_MODE_ON ICON "image\\ImeModeOn.ico"
IDI_IME_MODE_OFF ICON "image\\ImeModeOff.ico"
IDI_DOUBLE_SINGLE_BYTE_ON ICON "image\\DoubleSingleByteOn.ico"
IDI_DOUBLE_SINGLE_BYTE_OFF ICON "image\\DoubleSingleByteOff.ico"
IDI_PUNCTUATION_ON ICON "image\\PunctuationOn.ico"
IDI_PUNCTUATION_OFF ICON "image\\PunctuationOff.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
IDR_VERSION2 VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "MSFT"
VALUE "FileDescription", "The Sample code of Windows 8 IME"
VALUE "FileVersion", "1.0.0.1"
VALUE "InternalName", "SampleIM.dll"
VALUE "LegalCopyright", "Copyright (C)"
VALUE "OriginalFilename", "SampleIM.dll"
VALUE "ProductName", "SampleIME"
VALUE "ProductVersion", "1.0.0.1"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"\0"
END
3 TEXTINCLUDE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDIS_SAMPLEIME "Chinese Simplified QuanPin (version 6.0)"
IDS_DEFAULT_FONT "Microsoft YaHei UI"
END
STRINGTABLE
BEGIN
IDS_IME_MODE "Chinese/English input (Shift)"
IDS_DOUBLE_SINGLE_BYTE "Double/Single byte (Shift+Space)"
IDS_PUNCTUATION "Chinese/English punctuation (Ctrl+.)"
END
#endif // English (United States) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
+267
View File
@@ -0,0 +1,267 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<None Include="Dictionary\SampleIMESimplifiedQuanPin.txt" />
<None Include="image\DoubleSingleByteOff.ico" />
<None Include="image\DoubleSingleByteOn.ico" />
<None Include="image\ImeModeOff.ico" />
<None Include="image\ImeModeOn.ico" />
<None Include="image\PunctuationOff.ico" />
<None Include="image\PunctuationOn.ico" />
<None Include="image\SampleIme.ico" />
<None Include="SampleIME.def" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="BaseDictionaryEngine.h" />
<ClInclude Include="BaseWindow.h" />
<ClInclude Include="ButtonWindow.h" />
<ClInclude Include="CandidateListUIPresenter.h" />
<ClInclude Include="CandidateWindow.h" />
<ClInclude Include="Compartment.h" />
<ClInclude Include="CompositionProcessorEngine.h" />
<ClInclude Include="define.h" />
<ClInclude Include="EnumTfCandidates.h" />
<ClInclude Include="KeyStateCategory.h" />
<ClInclude Include="SampleIMEBaseStructure.h" />
<ClInclude Include="SearchCandidateProvider.h" />
<ClInclude Include="DictionaryParser.h" />
<ClInclude Include="DictionarySearch.h" />
<ClInclude Include="DisplayAttributeInfo.h" />
<ClInclude Include="EditSession.h" />
<ClInclude Include="EnumDisplayAttributeInfo.h" />
<ClInclude Include="File.h" />
<ClInclude Include="FileMapping.h" />
<ClInclude Include="GetTextExtentEditSession.h" />
<ClInclude Include="Globals.h" />
<ClInclude Include="KeyHandlerEditSession.h" />
<ClInclude Include="LanguageBar.h" />
<ClInclude Include="Private.h" />
<ClInclude Include="RegKey.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="SampleIME.h" />
<ClInclude Include="ScrollBarWindow.h" />
<ClInclude Include="ShadowWindow.h" />
<ClInclude Include="stdafx.h" />
<ClInclude Include="TableDictionaryEngine.h" />
<ClInclude Include="TfInputProcessorProfile.h" />
<ClInclude Include="TfTextLayoutSink.h" />
<ClInclude Include="TipCandidateList.h" />
<ClInclude Include="TipCandidateString.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ActiveLanguageProfileNotifySink.cpp" />
<ClCompile Include="BaseDictionaryEngine.cpp" />
<ClCompile Include="BaseWindow.cpp" />
<ClCompile Include="ButtonWindow.cpp" />
<ClCompile Include="CandidateListUIPresenter.cpp" />
<ClCompile Include="CandidateWindow.cpp" />
<ClCompile Include="Compartment.cpp" />
<ClCompile Include="Composition.cpp" />
<ClCompile Include="CompositionProcessorEngine.cpp" />
<ClCompile Include="EnumTfCandidates.cpp" />
<ClCompile Include="KeyStateCategory.cpp" />
<ClCompile Include="SampleIMEBaseStructure.cpp" />
<ClCompile Include="SearchCandidateProvider.cpp" />
<ClCompile Include="DictionaryParser.cpp" />
<ClCompile Include="DictionarySearch.cpp" />
<ClCompile Include="DisplayAttribute.cpp" />
<ClCompile Include="DisplayAttributeInfo.cpp" />
<ClCompile Include="DisplayAttributeProvider.cpp" />
<ClCompile Include="DllMain.cpp" />
<ClCompile Include="EditSession.cpp" />
<ClCompile Include="EndComposition.cpp" />
<ClCompile Include="EnumDisplayAttributeInfo.cpp" />
<ClCompile Include="File.cpp" />
<ClCompile Include="FileMapping.cpp" />
<ClCompile Include="FunctionProviderSink.cpp" />
<ClCompile Include="GetTextExtentEditSession.cpp" />
<ClCompile Include="Globals.cpp" />
<ClCompile Include="KeyEventSink.cpp" />
<ClCompile Include="KeyHandler.cpp" />
<ClCompile Include="KeyHandlerEditSession.cpp" />
<ClCompile Include="LanguageBar.cpp" />
<ClCompile Include="Register.cpp" />
<ClCompile Include="RegKey.cpp" />
<ClCompile Include="ScrollBarWindow.cpp" />
<ClCompile Include="Server.cpp" />
<ClCompile Include="ShadowWindow.cpp" />
<ClCompile Include="StartComposition.cpp" />
<ClCompile Include="TableDictionaryEngine.cpp" />
<ClCompile Include="SampleIME.cpp" />
<ClCompile Include="TextEditSink.cpp" />
<ClCompile Include="TfInputProcessorProfile.cpp" />
<ClCompile Include="TfTextLayoutSink.cpp" />
<ClCompile Include="ThreadFocusSink.cpp" />
<ClCompile Include="ThreadMgrEventSink.cpp" />
<ClCompile Include="TipCandidateList.cpp" />
<ClCompile Include="TipCandidateString.cpp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="SampleIME.rc" />
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{0C8FE010-5146-44D8-AF99-82702C15FEA5}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>SampleIME</RootNamespace>
<ProjectName>SampleIME</ProjectName>
<VCTargetsPath Condition="'$(VCTargetsPath11)' != '' and '$(VSVersion)' == '' and $(VisualStudioVersion) == ''">$(VCTargetsPath11)</VCTargetsPath>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SampleIME_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Windows Kits\8.0\Include\um;$(MSBuildProgramFiles32)\Windows Kits\8.0\Include\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(MSBuildProgramFiles32)\Windows Kits\8.0\Lib\win8\um\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>SampleIME.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;SampleIME_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Windows Kits\8.0\Include\um;$(MSBuildProgramFiles32)\Windows Kits\8.0\Include\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(MSBuildProgramFiles32)\Windows Kits\8.0\Lib\win8\um\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>SampleIME.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>Disabled</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SampleIME_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Windows Kits\8.0\Include\um;$(MSBuildProgramFiles32)\Windows Kits\8.0\Include\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BrowseInformation>false</BrowseInformation>
<TreatWarningAsError>true</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>false</EnableCOMDATFolding>
<OptimizeReferences>false</OptimizeReferences>
<AdditionalLibraryDirectories>$(MSBuildProgramFiles32)\Windows Kits\8.0\Lib\win8\um\x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>SampleIME.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SampleIME_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(MSBuildProgramFiles32)\Windows Kits\8.0\Include\um;$(MSBuildProgramFiles32)\Windows Kits\8.0\Include\shared;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<BrowseInformation>false</BrowseInformation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>false</EnableCOMDATFolding>
<OptimizeReferences>false</OptimizeReferences>
<AdditionalLibraryDirectories>$(MSBuildProgramFiles32)\Windows Kits\8.0\Lib\win8\um\x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>SampleIME.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+301
View File
@@ -0,0 +1,301 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Dictionary">
<UniqueIdentifier>{fe9b9e3e-f048-48b1-ae0b-718fc88cff49}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="SampleIME.def">
<Filter>Source Files</Filter>
</None>
<None Include="Dictionary\SampleIMESimplifiedQuanPin.txt">
<Filter>Dictionary</Filter>
</None>
<None Include="image\SampleIme.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="image\ImeModeOn.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="image\ImeModeOff.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="image\DoubleSingleByteOn.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="image\DoubleSingleByteOff.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="image\PunctuationOn.ico">
<Filter>Resource Files</Filter>
</None>
<None Include="image\PunctuationOff.ico">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="BaseDictionaryEngine.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="BaseWindow.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ButtonWindow.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CandidateWindow.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Compartment.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompositionProcessorEngine.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DictionaryParser.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DictionarySearch.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DisplayAttributeInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="EditSession.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="EnumDisplayAttributeInfo.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="File.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="FileMapping.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GetTextExtentEditSession.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Globals.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="KeyHandlerEditSession.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LanguageBar.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Private.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RegKey.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ScrollBarWindow.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ShadowWindow.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TableDictionaryEngine.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TfInputProcessorProfile.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TfTextLayoutSink.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SampleIME.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SearchCandidateProvider.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TipCandidateList.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="EnumTfCandidates.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="TipCandidateString.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="KeyStateCategory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CandidateListUIPresenter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SampleIMEBaseStructure.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="define.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ActiveLanguageProfileNotifySink.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="BaseDictionaryEngine.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="BaseWindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ButtonWindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CandidateWindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Compartment.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Composition.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CompositionProcessorEngine.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DictionaryParser.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DictionarySearch.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DisplayAttribute.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DisplayAttributeInfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DisplayAttributeProvider.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DllMain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="EditSession.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="EndComposition.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="EnumDisplayAttributeInfo.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="File.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FileMapping.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GetTextExtentEditSession.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Globals.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="KeyEventSink.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="KeyHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="KeyHandlerEditSession.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LanguageBar.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Register.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RegKey.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ScrollBarWindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Server.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ShadowWindow.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="StartComposition.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TableDictionaryEngine.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TextEditSink.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TfInputProcessorProfile.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TfTextLayoutSink.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ThreadFocusSink.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ThreadMgrEventSink.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SampleIME.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="FunctionProviderSink.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SearchCandidateProvider.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TipCandidateList.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="EnumTfCandidates.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="TipCandidateString.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="KeyStateCategory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CandidateListUIPresenter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SampleIMEBaseStructure.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="SampleIME.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>
+325
View File
@@ -0,0 +1,325 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Globals.h"
//---------------------------------------------------------------------
//
// CLSIDToString
//
//---------------------------------------------------------------------
const BYTE GuidSymbols[] = {
3, 2, 1, 0, '-', 5, 4, '-', 7, 6, '-', 8, 9, '-', 10, 11, 12, 13, 14, 15
};
const WCHAR HexDigits[] = L"0123456789ABCDEF";
BOOL CLSIDToString(REFGUID refGUID, _Out_writes_(39) WCHAR *pCLSIDString)
{
WCHAR* pTemp = pCLSIDString;
const BYTE* pBytes = (const BYTE *) &refGUID;
DWORD j = 0;
pTemp[j++] = L'{';
for (int i = 0; i < sizeof(GuidSymbols) && j < (CLSID_STRLEN - 2); i++)
{
if (GuidSymbols[i] == '-')
{
pTemp[j++] = L'-';
}
else
{
pTemp[j++] = HexDigits[ (pBytes[GuidSymbols[i]] & 0xF0) >> 4 ];
pTemp[j++] = HexDigits[ (pBytes[GuidSymbols[i]] & 0x0F) ];
}
}
pTemp[j++] = L'}';
pTemp[j] = L'\0';
return TRUE;
}
//---------------------------------------------------------------------
//
// SkipWhiteSpace
//
// dwBufLen - in character count
//
//---------------------------------------------------------------------
HRESULT SkipWhiteSpace(LCID locale, _In_ LPCWSTR pwszBuffer, DWORD_PTR dwBufLen, _Out_ DWORD_PTR *pdwIndex)
{
DWORD_PTR index = 0;
*pdwIndex = 0;
while (*pwszBuffer && IsSpace(locale, *pwszBuffer) && dwBufLen)
{
dwBufLen--;
pwszBuffer++;
index++;
}
if (*pwszBuffer && dwBufLen)
{
*pdwIndex = index;
return S_OK;
}
return E_FAIL;
}
//---------------------------------------------------------------------
//
// FindChar
//
// dwBufLen - in character count
//
//---------------------------------------------------------------------
HRESULT FindChar(WCHAR wch, _In_ LPCWSTR pwszBuffer, DWORD_PTR dwBufLen, _Out_ DWORD_PTR *pdwIndex)
{
DWORD_PTR index = 0;
*pdwIndex = 0;
while (*pwszBuffer && (*pwszBuffer != wch) && dwBufLen)
{
dwBufLen--;
pwszBuffer++;
index++;
}
if (*pwszBuffer && dwBufLen)
{
*pdwIndex = index;
return S_OK;
}
return E_FAIL;
}
//---------------------------------------------------------------------
//
// IsSpace
//
//---------------------------------------------------------------------
BOOL IsSpace(LCID locale, WCHAR wch)
{
WORD wCharType = 0;
GetStringTypeEx(locale, CT_CTYPE1, &wch, 1, &wCharType);
return (wCharType & C1_SPACE);
}
CStringRange::CStringRange()
{
_stringBufLen = 0;
_pStringBuf = nullptr;
}
CStringRange::~CStringRange()
{
}
const WCHAR *CStringRange::Get() const
{
return _pStringBuf;
}
const DWORD_PTR CStringRange::GetLength() const
{
return _stringBufLen;
}
void CStringRange::Clear()
{
_stringBufLen = 0;
_pStringBuf = nullptr;
}
void CStringRange::Set(const WCHAR *pwch, DWORD_PTR dwLength)
{
_stringBufLen = dwLength;
_pStringBuf = pwch;
}
void CStringRange::Set(CStringRange &sr)
{
*this = sr;
}
CStringRange& CStringRange::operator =(const CStringRange& sr)
{
_stringBufLen = sr._stringBufLen;
_pStringBuf = sr._pStringBuf;
return *this;
}
void CStringRange::CharNext(_Inout_ CStringRange* pCharNext)
{
if (!_stringBufLen)
{
pCharNext->_stringBufLen = 0;
pCharNext->_pStringBuf = nullptr;
}
else
{
pCharNext->_stringBufLen = _stringBufLen;
pCharNext->_pStringBuf = _pStringBuf;
while (pCharNext->_stringBufLen)
{
BOOL isSurrogate = (IS_HIGH_SURROGATE(*pCharNext->_pStringBuf) || IS_LOW_SURROGATE(*pCharNext->_pStringBuf));
pCharNext->_stringBufLen--;
pCharNext->_pStringBuf++;
if (!isSurrogate)
{
break;
}
}
}
}
int CStringRange::Compare(LCID locale, _In_ CStringRange* pString1, _In_ CStringRange* pString2)
{
return CompareString(locale,
NORM_IGNORECASE,
pString1->Get(),
(DWORD)pString1->GetLength(),
pString2->Get(),
(DWORD)pString2->GetLength());
}
BOOL CStringRange::WildcardCompare(LCID locale, _In_ CStringRange* stringWithWildcard, _In_ CStringRange* targetString)
{
if (stringWithWildcard->GetLength() == 0)
{
return targetString->GetLength() == 0 ? TRUE : FALSE;
}
CStringRange stringWithWildcard_next;
CStringRange targetString_next;
stringWithWildcard->CharNext(&stringWithWildcard_next);
targetString->CharNext(&targetString_next);
if (*stringWithWildcard->Get() == L'*')
{
return WildcardCompare(locale, &stringWithWildcard_next, targetString) || ((targetString->GetLength() != 0) && WildcardCompare(locale, stringWithWildcard, &targetString_next));
}
if (*stringWithWildcard->Get() == L'?')
{
return ((targetString->GetLength() != 0) && WildcardCompare(locale, &stringWithWildcard_next, &targetString_next));
}
BOOL isSurrogate1 = (IS_HIGH_SURROGATE(*stringWithWildcard->Get()) || IS_LOW_SURROGATE(*stringWithWildcard->Get()));
BOOL isSurrogate2 = (IS_HIGH_SURROGATE(*targetString->Get()) || IS_LOW_SURROGATE(*targetString->Get()));
return ((CompareString(locale,
NORM_IGNORECASE,
stringWithWildcard->Get(),
(isSurrogate1 ? 2 : 1),
targetString->Get(),
(isSurrogate2 ? 2 : 1)) == CSTR_EQUAL) && WildcardCompare(locale, &stringWithWildcard_next, &targetString_next));
}
CCandidateRange::CCandidateRange(void)
{
}
CCandidateRange::~CCandidateRange(void)
{
}
BOOL CCandidateRange::IsRange(UINT vKey)
{
DWORD value = vKey - L'0';
for (UINT i = 0; i < _CandidateListIndexRange.Count(); i++)
{
if (value == *_CandidateListIndexRange.GetAt(i))
{
return TRUE;
}
else if ((VK_NUMPAD0 <= vKey) && (vKey <= VK_NUMPAD9))
{
if ((vKey-VK_NUMPAD0) == *_CandidateListIndexRange.GetAt(i))
{
return TRUE;
}
}
}
return FALSE;
}
int CCandidateRange::GetIndex(UINT vKey)
{
DWORD value = vKey - L'0';
for (UINT i = 0; i < _CandidateListIndexRange.Count(); i++)
{
if (value == *_CandidateListIndexRange.GetAt(i))
{
return i;
}
else if ((VK_NUMPAD0 <= vKey) && (vKey <= VK_NUMPAD9))
{
if ((vKey-VK_NUMPAD0) == *_CandidateListIndexRange.GetAt(i))
{
return i;
}
}
}
return -1;
}
CPunctuationPair::CPunctuationPair()
{
_punctuation._Code = 0;
_punctuation._Punctuation = 0;
_pairPunctuation = 0;
_isPairToggle = FALSE;
}
CPunctuationPair::CPunctuationPair(WCHAR code, WCHAR punctuation, WCHAR pair)
{
_punctuation._Code = code;
_punctuation._Punctuation = punctuation;
_pairPunctuation = pair;
_isPairToggle = FALSE;
}
CPunctuationNestPair::CPunctuationNestPair()
{
_punctuation_begin._Code = 0;
_punctuation_begin._Punctuation = 0;
_pairPunctuation_begin = 0;
_punctuation_end._Code = 0;
_punctuation_end._Punctuation = 0;
_pairPunctuation_end = 0;
_nestCount = 0;
}
CPunctuationNestPair::CPunctuationNestPair(WCHAR codeBegin, WCHAR punctuationBegin, WCHAR pairBegin,
WCHAR codeEnd, WCHAR punctuationEnd, WCHAR pairEnd)
{
pairEnd;punctuationEnd;
_punctuation_begin._Code = codeBegin;
_punctuation_begin._Punctuation = punctuationBegin;
_pairPunctuation_begin = pairBegin;
_punctuation_end._Code = codeEnd;
_punctuation_end._Punctuation = punctuationBegin;
_pairPunctuation_end = pairBegin;
_nestCount = 0;
}
+271
View File
@@ -0,0 +1,271 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "stdafx.h"
#include <vector>
#include "assert.h"
#include <iostream>
using std::cout;
using std::endl;
//---------------------------------------------------------------------
// defined keyword
//---------------------------------------------------------------------
template<class VALUE>
struct _DEFINED_KEYWORD
{
LPCWSTR _pwszKeyword;
VALUE _value;
};
//---------------------------------------------------------------------
// enum
//---------------------------------------------------------------------
enum KEYSTROKE_CATEGORY
{
CATEGORY_NONE = 0,
CATEGORY_COMPOSING,
CATEGORY_CANDIDATE,
CATEGORY_PHRASE,
CATEGORY_PHRASEFROMKEYSTROKE,
CATEGORY_INVOKE_COMPOSITION_EDIT_SESSION
};
enum KEYSTROKE_FUNCTION
{
FUNCTION_NONE = 0,
FUNCTION_INPUT,
FUNCTION_CANCEL,
FUNCTION_FINALIZE_TEXTSTORE,
FUNCTION_FINALIZE_TEXTSTORE_AND_INPUT,
FUNCTION_FINALIZE_CANDIDATELIST,
FUNCTION_FINALIZE_CANDIDATELIST_AND_INPUT,
FUNCTION_CONVERT,
FUNCTION_CONVERT_WILDCARD,
FUNCTION_SELECT_BY_NUMBER,
FUNCTION_BACKSPACE,
FUNCTION_MOVE_LEFT,
FUNCTION_MOVE_RIGHT,
FUNCTION_MOVE_UP,
FUNCTION_MOVE_DOWN,
FUNCTION_MOVE_PAGE_UP,
FUNCTION_MOVE_PAGE_DOWN,
FUNCTION_MOVE_PAGE_TOP,
FUNCTION_MOVE_PAGE_BOTTOM,
// Function Double/Single byte
FUNCTION_DOUBLE_SINGLE_BYTE,
// Function Punctuation
FUNCTION_PUNCTUATION
};
//---------------------------------------------------------------------
// candidate list
//---------------------------------------------------------------------
enum CANDIDATE_MODE
{
CANDIDATE_NONE = 0,
CANDIDATE_ORIGINAL,
CANDIDATE_PHRASE,
CANDIDATE_INCREMENTAL,
CANDIDATE_WITH_NEXT_COMPOSITION
};
//---------------------------------------------------------------------
// structure
//---------------------------------------------------------------------
struct _KEYSTROKE_STATE
{
KEYSTROKE_CATEGORY Category;
KEYSTROKE_FUNCTION Function;
};
struct _PUNCTUATION
{
WCHAR _Code;
WCHAR _Punctuation;
};
BOOL CLSIDToString(REFGUID refGUID, _Out_writes_ (39) WCHAR *pCLSIDString);
HRESULT SkipWhiteSpace(LCID locale, _In_ LPCWSTR pwszBuffer, DWORD_PTR dwBufLen, _Out_ DWORD_PTR *pdwIndex);
HRESULT FindChar(WCHAR wch, _In_ LPCWSTR pwszBuffer, DWORD_PTR dwBufLen, _Out_ DWORD_PTR *pdwIndex);
BOOL IsSpace(LCID locale, WCHAR wch);
template<class T>
class CSampleImeArray
{
typedef typename std::vector<T> CSampleImeInnerArray;
typedef typename std::vector<T>::iterator CSampleImeInnerIter;
public:
CSampleImeArray(): _innerVect()
{
}
explicit CSampleImeArray(size_t count): _innerVect(count)
{
}
virtual ~CSampleImeArray()
{
}
inline T* GetAt(size_t index)
{
assert(index >= 0);
assert(index < _innerVect.size());
T& curT = _innerVect.at(index);
return &(curT);
}
inline const T* GetAt(size_t index) const
{
assert(index >= 0);
assert(index < _innerVect.size());
T& curT = _innerVect.at(index);
return &(curT);
}
void RemoveAt(size_t index)
{
assert(index >= 0);
assert(index < _innerVect.size());
CSampleImeInnerIter iter = _innerVect.begin();
_innerVect.erase(iter + index);
}
UINT Count() const
{
return static_cast<UINT>(_innerVect.size());
}
T* Append()
{
T newT;
_innerVect.push_back(newT);
T& backT = _innerVect.back();
return &(backT);
}
void reserve(size_t Count)
{
_innerVect.reserve(Count);
}
void Clear()
{
_innerVect.clear();
}
private:
CSampleImeInnerArray _innerVect;
};
class CCandidateRange
{
public:
CCandidateRange(void);
~CCandidateRange(void);
BOOL IsRange(UINT vKey);
int GetIndex(UINT vKey);
inline int Count() const
{
return _CandidateListIndexRange.Count();
}
inline DWORD *GetAt(int index)
{
return _CandidateListIndexRange.GetAt(index);
}
inline DWORD *Append()
{
return _CandidateListIndexRange.Append();
}
private:
CSampleImeArray<DWORD> _CandidateListIndexRange;
};
class CStringRange
{
public:
CStringRange();
~CStringRange();
const WCHAR *Get() const;
const DWORD_PTR GetLength() const;
void Clear();
void Set(const WCHAR *pwch, DWORD_PTR dwLength);
void Set(CStringRange &sr);
CStringRange& operator=(const CStringRange& sr);
void CharNext(_Inout_ CStringRange* pCharNext);
static int Compare(LCID locale, _In_ CStringRange* pString1, _In_ CStringRange* pString2);
static BOOL WildcardCompare(LCID locale, _In_ CStringRange* stringWithWildcard, _In_ CStringRange* targetString);
protected:
DWORD_PTR _stringBufLen; // Length is in character count.
const WCHAR *_pStringBuf; // Buffer which is not add zero terminate.
};
//---------------------------------------------------------------------
// CCandidateListItem
// _ItemString - candidate string
// _FindKeyCode - tailing string
//---------------------------------------------------------------------
struct CCandidateListItem
{
CStringRange _ItemString;
CStringRange _FindKeyCode;
CCandidateListItem& CCandidateListItem::operator =( const CCandidateListItem& rhs)
{
_ItemString = rhs._ItemString;
_FindKeyCode = rhs._FindKeyCode;
return *this;
}
};
class CPunctuationPair
{
public:
CPunctuationPair();
CPunctuationPair(WCHAR code, WCHAR punctuation, WCHAR pair);
struct _PUNCTUATION _punctuation;
WCHAR _pairPunctuation;
BOOL _isPairToggle;
};
class CPunctuationNestPair
{
public:
CPunctuationNestPair();
CPunctuationNestPair(WCHAR wchCode_begin, WCHAR wch_begin, WCHAR wchPair_begin,
WCHAR wchCode_end, WCHAR wch_end, WCHAR wchPair_end);
struct _PUNCTUATION _punctuation_begin;
WCHAR _pairPunctuation_begin;
struct _PUNCTUATION _punctuation_end;
WCHAR _pairPunctuation_end;
int _nestCount;
};
+80
View File
@@ -0,0 +1,80 @@
//////////////////////////////////////////////////////////////////////
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// CSampleIMESampleIMEStructureArray.h
//
// CSampleIMEStructureArray declaration.
//
//////////////////////////////////////////////////////////////////////
#pragma once
#include <vector>
template<class T>
class CSampleIMEStructureArray
{
typedef typename std::vector<T> value_type;
typedef const T& CONST_REF;
typedef typename value_type CSampleIMEArray;
typedef typename value_type::iterator CSampleIMEIter;
public:
CSampleIMEStructureArray(): _imeVector()
{
}
explicit CSampleIMEStructureArray(size_t iCount): _imeVector(iCount)
{
}
CSampleIMEStructureArray(size_t iCount, CONST_REF tVal): _imeVector(iCount, tVal)
{
}
virtual ~CSampleIMEStructureArray() {}
inline CONST_REF GetAt(size_t iIndex) const
{
assert(iIndex <= _imeVector.size());
assert(_imeVector.size() > 0);
return _imeVector[iIndex];
}
inline T& GetAt(size_t iIndex)
{
assert(iIndex <= _imeVector.size());
assert(_imeVector.size() > 0);
return _imeVector[iIndex];
}
void RemoveAt(size_t iIndex, size_t iElements)
{
assert(iIndex <= _imeVector.size());
assert(_imeVector.size() > 0);
CSampleIMEIter beginIter = _imeVector.begin() + iIndex;
CSampleIMEIter lastIter = beginIter + iElements - 1;
_imeVector.erase(beginIter, lastIter);
}
size_t Count() const { return _imeVector.size(); }
void Append(const T& tVal)
{
_imeVector.push_back(tVal);
}
void Clear()
{
_imeVector.clear();
}
private:
CSampleIMEArray _imeVector; // the actual array of data
CSampleIMEIter _imeIter;
};
+650
View File
@@ -0,0 +1,650 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
#include "BaseWindow.h"
#include "ScrollBarWindow.h"
//////////////////////////////////////////////////////////////////////
//
// CScrollBarWindowFactory class.
//
//////////////////////////////////////////////////////////////////////
CScrollBarWindowFactory* CScrollBarWindowFactory::_instance;
CScrollBarWindowFactory::CScrollBarWindowFactory()
{
_instance = nullptr;
}
CScrollBarWindowFactory* CScrollBarWindowFactory::Instance()
{
if (nullptr == _instance)
{
_instance = new (std::nothrow) CScrollBarWindowFactory();
}
return _instance;
}
CScrollBarWindow* CScrollBarWindowFactory::MakeScrollBarWindow(SHELL_MODE shellMode)
{
CScrollBarWindow* pScrollBarWindow = nullptr;
switch (shellMode)
{
case STOREAPP:
pScrollBarWindow = new (std::nothrow) CScrollBarWindow();
break;
case DESKTOP:
pScrollBarWindow = new (std::nothrow) CScrollBarNullWindow();
break;
default:
pScrollBarWindow = new (std::nothrow) CScrollBarNullWindow();
break;
}
return pScrollBarWindow;
}
void CScrollBarWindowFactory::Release()
{
if (_instance)
{
delete _instance;
_instance = nullptr;
}
}
//////////////////////////////////////////////////////////////////////
//
// CScrollBarWindow class.
//
//////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// ctor
//
//----------------------------------------------------------------------------
CScrollBarWindow::CScrollBarWindow()
{
_pBtnUp = nullptr;
_pBtnDn = nullptr;
_scrollDir = SCROLL_NONE_DIR;
_sizeOfScrollBtn.cx = GetSystemMetrics(SM_CXVSCROLL) * 2;
_sizeOfScrollBtn.cy = GetSystemMetrics(SM_CYVSCROLL) * 2;
}
//+---------------------------------------------------------------------------
//
// dtor
//
//----------------------------------------------------------------------------
CScrollBarWindow::~CScrollBarWindow()
{
if (_pBtnUp)
{
delete _pBtnUp;
_pBtnUp = nullptr;
}
if (_pBtnDn)
{
delete _pBtnDn;
_pBtnDn = nullptr;
}
}
//+---------------------------------------------------------------------------
//
// _Create
//
//----------------------------------------------------------------------------
BOOL CScrollBarWindow::_Create(ATOM atom, DWORD dwExStyle, DWORD dwStyle, CBaseWindow *pParent, int wndWidth, int wndHeight)
{
if (!CBaseWindow::_Create(atom, dwExStyle, dwStyle, pParent, wndWidth, wndHeight))
{
return FALSE;
}
_pBtnUp = new (std::nothrow) CScrollButtonWindow(dwStyle & WS_HSCROLL ? DFCS_SCROLLLEFT : DFCS_SCROLLUP);
if (_pBtnUp == nullptr)
{
return FALSE;
}
_pBtnUp->_Create(NULL, 0, 0, this);
_pBtnUp->_SetUIWnd(_GetUIWnd());
_pBtnDn = new (std::nothrow) CScrollButtonWindow(dwStyle & WS_HSCROLL ? DFCS_SCROLLRIGHT : DFCS_SCROLLDOWN);
if (_pBtnDn == nullptr)
{
delete _pBtnUp;
_pBtnUp = nullptr;
return FALSE;
}
_pBtnDn->_Create(NULL, 0, 0, this);
_pBtnDn->_SetUIWnd(_GetUIWnd());
return TRUE;
}
//+---------------------------------------------------------------------------
//
// _WindowProcCallback
//
// Scrollbar window proc.
//----------------------------------------------------------------------------
LRESULT CALLBACK CScrollBarWindow::_WindowProcCallback(_In_ HWND wndHandle, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
HDC dcHandle = nullptr;
PAINTSTRUCT ps;
dcHandle = BeginPaint(wndHandle, &ps);
// paint itself at first
_OnPaint(dcHandle, &ps);
// paint all children
_pBtnUp->_OnPaint(dcHandle, &ps);
_pBtnDn->_OnPaint(dcHandle, &ps);
EndPaint(wndHandle, &ps);
}
return 0;
}
return DefWindowProc(wndHandle, uMsg, wParam, lParam);
}
//+---------------------------------------------------------------------------
//
// _OnPaint
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_OnPaint(_In_ HDC dcHandle, _In_ PAINTSTRUCT *pps)
{
HBRUSH hBrush = nullptr;
CBaseWindow* pUIWnd = _GetUIWnd();
if (pUIWnd != nullptr && pUIWnd->_GetWnd())
{
hBrush = (HBRUSH)DefWindowProc(pUIWnd->_GetWnd(), WM_CTLCOLORSCROLLBAR, (WPARAM)dcHandle, (LPARAM)pUIWnd->_GetWnd());
}
if (hBrush == nullptr)
{
hBrush = GetSysColorBrush(COLOR_SCROLLBAR);
}
FillRect(dcHandle, &pps->rcPaint, hBrush);
}
//+---------------------------------------------------------------------------
//
// _OnLButtonDown
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_OnLButtonDown(POINT pt)
{
_StartCapture();
RECT rc = {0, 0, 0, 0};
_pBtnUp->_GetClientRect(&rc);
if (PtInRect(&rc, pt))
{
_pBtnUp->_OnLButtonDown(pt);
}
else
{
_pBtnDn->_GetClientRect(&rc);
if (PtInRect(&rc, pt))
{
_pBtnDn->_OnLButtonDown(pt);
}
}
}
//+---------------------------------------------------------------------------
//
// _OnLButtonUp
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_OnLButtonUp(POINT pt)
{
if (_IsCapture())
{
CBaseWindow* pUIWnd = _GetTopmostUIWnd();
if (pUIWnd)
{
CBaseWindow *pCapture = pUIWnd->_GetCaptureObject();
if (pCapture && pCapture != this)
{
pCapture->_OnLButtonUp(pt);
}
}
}
else
{
RECT rc = {0, 0, 0, 0};
_pBtnUp->_GetClientRect(&rc);
if (PtInRect(&rc, pt))
{
_pBtnUp->_OnLButtonUp(pt);
}
else
{
_pBtnDn->_GetClientRect(&rc);
if (PtInRect(&rc, pt))
{
_pBtnDn->_OnLButtonUp(pt);
}
}
}
if (_IsCapture())
{
_EndCapture();
}
if (_IsTimer())
{
_EndTimer();
}
_scrollDir = SCROLL_NONE_DIR;
_InvalidateRect();
}
//+---------------------------------------------------------------------------
//
// _OnMouseMove
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_OnMouseMove(POINT pt)
{
RECT rc = {0, 0, 0, 0};
_pBtnUp->_GetClientRect(&rc);
if (PtInRect(&rc, pt))
{
_pBtnUp->_OnMouseMove(pt);
}
else
{
_pBtnDn->_GetClientRect(&rc);
if (PtInRect(&rc, pt))
{
_pBtnDn->_OnMouseMove(pt);
}
}
}
//+---------------------------------------------------------------------------
//
// _OnOwnerWndMoved
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_OnOwnerWndMoved(BOOL isResized)
{
isResized;
if (IsWindow(_GetWnd()) && IsWindowVisible(_GetWnd()))
{
_AdjustWindowPos();
}
}
//+---------------------------------------------------------------------------
//
// _Resize
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_Resize(int x, int y, int cx, int cy)
{
CBaseWindow::_Resize(x, y, cx, cy);
RECT rc = {0, 0, 0, 0};
_GetBtnUpRect(&rc);
_pBtnUp->_Resize(rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
_GetBtnDnRect(&rc);
_pBtnDn->_Resize(rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
}
//+---------------------------------------------------------------------------
//
// _Show
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_Show(BOOL isShowWnd)
{
if (_IsWindowVisible() != isShowWnd)
{
CBaseWindow::_Show(isShowWnd);
_pBtnUp->_Show(isShowWnd);
_pBtnDn->_Show(isShowWnd);
}
}
//+---------------------------------------------------------------------------
//
// _Enable
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_Enable(BOOL isEnable)
{
if (_IsEnabled() != isEnable)
{
CBaseWindow::_Enable(isEnable);
_pBtnUp->_Enable(isEnable);
_pBtnDn->_Enable(isEnable);
}
}
//+---------------------------------------------------------------------------
//
// _AdjustWindowPos
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_AdjustWindowPos()
{
if (!IsWindow(_GetWnd()))
{
return;
}
RECT rc = {0, 0, 0, 0};
CBaseWindow* pParent = _GetParent();
if (pParent == nullptr)
{
return;
}
GetWindowRect(pParent->_GetWnd(), &rc);
SetWindowPos(_GetWnd(), pParent->_GetWnd(),
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
SWP_NOOWNERZORDER | SWP_NOACTIVATE);
}
//+---------------------------------------------------------------------------
//
// _SetScrollInfo
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_SetScrollInfo(_In_ CScrollInfo *lpsi)
{
_scrollInfo = *lpsi;
BOOL isEnable = (_scrollInfo.nMax > _scrollInfo.nPage);
_Enable(isEnable);
_scrollDir = SCROLL_NONE_DIR;
_SetCurPos(_scrollInfo.nPos, -1);
}
//+---------------------------------------------------------------------------
//
// _GetScrollInfo
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_GetScrollInfo(_Out_ CScrollInfo *lpsi)
{
*lpsi = _scrollInfo;
}
//+---------------------------------------------------------------------------
//
// _GetBtnUpRect
//
//----------------------------------------------------------------------------
BOOL CScrollBarWindow::_GetBtnUpRect(_Out_ RECT *prc)
{
RECT rc = {0, 0, 0, 0};
_GetClientRect(&rc);
if (prc == nullptr)
{
return FALSE;
}
prc->left = rc.left;
prc->top = rc.top;
prc->right = rc.right;
prc->bottom = rc.top + min(_sizeOfScrollBtn.cy, (rc.bottom - rc.top)/2);
return TRUE;
}
//+---------------------------------------------------------------------------
//
// _GetBtnDnRect
//
//----------------------------------------------------------------------------
BOOL CScrollBarWindow::_GetBtnDnRect(_Out_ RECT *prc)
{
RECT rc = {0, 0, 0, 0};
_GetClientRect(&rc);
if (prc == nullptr)
{
return FALSE;
}
prc->left = rc.left;
prc->top = rc.bottom - min(_sizeOfScrollBtn.cy, (rc.bottom - rc.top)/2);
prc->right = rc.right;
prc->bottom = rc.bottom;
return TRUE;
}
//+---------------------------------------------------------------------------
//
// _GetScrollArea
//
//----------------------------------------------------------------------------
void CScrollBarWindow::_GetScrollArea(_Out_ RECT *prc)
{
RECT rcBtnUp = {0, 0, 0, 0};
RECT rcBtnDn = {0, 0, 0, 0};
_GetBtnUpRect(&rcBtnUp);
_GetBtnDnRect(&rcBtnDn);
RECT rc = {0, 0, 0, 0};
_GetClientRect(&rc);
if (prc == nullptr)
{
return;
}
prc->left = rc.left;
prc->top = rc.top + (rcBtnUp.bottom - rcBtnUp.top);
prc->right = rc.right;
prc->bottom = rc.bottom - (rcBtnDn.bottom - rcBtnDn.top);
}
//+---------------------------------------------------------------------------
//
// _SetCurPos
//
// param: dwSB - SB_xxx for WM_VSCROLL or WM_HSCROLL.
// if -1 is specified, function doesn't send WM_xSCROLL message
//----------------------------------------------------------------------------
void CScrollBarWindow::_SetCurPos(int nPos, int dwSB)
{
int posMax = (_scrollInfo.nMax <= _scrollInfo.nPage) ? 0 : _scrollInfo.nMax - _scrollInfo.nPage;
nPos = min(nPos, posMax);
nPos = max(nPos, 0);
_scrollInfo.nPos = nPos;
if (_IsWindowVisible()) {
_InvalidateRect();
}
if ((_IsCapture() && dwSB != -1) || (dwSB == SB_THUMBPOSITION))
{
_NotifyCommand(WM_VSCROLL, dwSB, nPos);
}
}
//////////////////////////////////////////////////////////////////////
//
// CScrollButtonWindow class.
//
//////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// _OnPaint
//
//----------------------------------------------------------------------------
void CScrollButtonWindow::_OnPaint(_In_ HDC dcHandle, _In_ PAINTSTRUCT *pps)
{
pps;
RECT rc = {0, 0, 0, 0};
_GetClientRect(&rc);
DrawFrameControl(dcHandle, &rc, DFC_SCROLL, subTypeOfControl | typeOfControl | (!_IsEnabled() ? DFCS_INACTIVE : 0));
}
//+---------------------------------------------------------------------------
//
// _OnLButtonDown
//
//----------------------------------------------------------------------------
void CScrollButtonWindow::_OnLButtonDown(POINT pt)
{
CButtonWindow::_OnLButtonDown(pt);
CScrollBarWindow* pParent = (CScrollBarWindow*)_GetParent(); // more secure w/ dynamic_cast
if (pParent == nullptr)
{
return;
}
switch (subTypeOfControl)
{
case DFCS_SCROLLDOWN:
_NotifyCommand(WM_VSCROLL, SB_LINEDOWN, 0);
pParent->_ShiftLine(+1, FALSE);
break;
case DFCS_SCROLLUP:
_NotifyCommand(WM_VSCROLL, SB_LINEUP, 0);
pParent->_ShiftLine(-1, FALSE);
break;
}
_StartTimer(_GetScrollDelay());
}
//+---------------------------------------------------------------------------
//
// _OnLButtonUp
//
//----------------------------------------------------------------------------
void CScrollButtonWindow::_OnLButtonUp(POINT pt)
{
CButtonWindow::_OnLButtonUp(pt);
_InvalidateRect();
if (_IsTimer())
{
_EndTimer();
}
}
//+---------------------------------------------------------------------------
//
// _OnTimer : Speed up page Down/Up while holding Down/Up Button
//
//----------------------------------------------------------------------------
void CScrollButtonWindow::_OnTimer()
{
POINT pt = {0, 0};
CScrollBarWindow* pParent = (CScrollBarWindow*)_GetParent(); // more secure w/ dynamic_cast
if (pParent == nullptr)
{
return;
}
// start another faster timer
_StartTimer(_GetScrollSpeed());
GetCursorPos(&pt);
MapWindowPoints(HWND_DESKTOP, pParent->_GetWnd(), &pt, 1);
RECT rc = {0, 0, 0, 0};
_GetClientRect(&rc);
if (PtInRect(&rc, pt))
{
switch (subTypeOfControl)
{
case DFCS_SCROLLDOWN:
_NotifyCommand(WM_VSCROLL, SB_LINEDOWN, 0);
pParent->_ShiftLine(+1, FALSE);
break;
case DFCS_SCROLLUP:
_NotifyCommand(WM_VSCROLL, SB_LINEUP, 0);
pParent->_ShiftLine(-1, FALSE);
break;
}
}
}
+220
View File
@@ -0,0 +1,220 @@
//////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2005 Microsoft Corporation. All rights reserved.
//
// ScrollBarWindow.h
//
// CScrollBarWindow declaration.
//
//
//////////////////////////////////////////////////////////////////////
#pragma once
#include "BaseWindow.h"
#include "ButtonWindow.h"
class CScrollButtonWindow;
enum SCROLLBAR_DIRECTION
{
SCROLL_NONE_DIR,
SCROLL_PAGEDOWN, // or page left
SCROLL_PAGEUP // or page right
};
enum SHELL_MODE
{
STOREAPP,
DESKTOP,
};
struct CScrollInfo
{
CScrollInfo()
{
nMax = 0;
nPage = 0;
nPos = 0;
}
int nMax;
int nPage;
int nPos;
};
class CScrollBarWindow;
class CScrollBarWindowFactory
{
public:
static CScrollBarWindowFactory* Instance();
CScrollBarWindow* MakeScrollBarWindow(SHELL_MODE shellMode);
void Release();
protected:
CScrollBarWindowFactory();
private:
static CScrollBarWindowFactory* _instance;
};
//////////////////////////////////////////////////////////////////////
//
// CScrollBarWindow declaration.
//
//////////////////////////////////////////////////////////////////////
class CScrollBarWindow : public CBaseWindow
{
public:
CScrollBarWindow();
virtual ~CScrollBarWindow();
BOOL _Create(ATOM atom, DWORD dwExStyle, DWORD dwStyle, CBaseWindow *pParent = nullptr, int wndWidth = 0, int wndHeight = 0);
void _Resize(int x, int y, int cx, int cy);
void _Show(BOOL isShowWnd);
void _Enable(BOOL isEnable);
LRESULT CALLBACK _WindowProcCallback(_In_ HWND wndHandle, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam);
virtual void _OnPaint(_In_ HDC dcHandle, _In_ PAINTSTRUCT *pps);
virtual void _OnLButtonDown(POINT pt);
virtual void _OnLButtonUp(POINT pt);
virtual void _OnMouseMove(POINT pt);
virtual void _OnTimer() { };
virtual void _OnOwnerWndMoved(BOOL isResized);
virtual void _SetScrollInfo(_In_ CScrollInfo *lpsi);
virtual void _GetScrollInfo(_Out_ CScrollInfo *lpsi);
virtual BOOL _GetBtnUpRect(_Out_ RECT *prc);
virtual BOOL _GetBtnDnRect(_Out_ RECT *prc);
virtual void _ShiftLine(int nLine, BOOL isNotify)
{
DWORD dwSB = 0;
dwSB = (nLine > 0 ? SB_LINEDOWN :
nLine < 0 ? SB_LINEUP : 0);
_SetCurPos(_scrollInfo.nPos + nLine, isNotify ? dwSB : -1);
}
virtual void _ShiftPage(int nPage, BOOL isNotify)
{
DWORD dwSB = 0;
dwSB = (nPage > 0 ? SB_PAGEDOWN :
nPage < 0 ? SB_PAGEUP : 0);
_SetCurPos(_scrollInfo.nPos + _scrollInfo.nPage * nPage, isNotify ? dwSB : -1);
}
virtual void _ShiftPosition(int iPos, BOOL isNotify)
{
_SetCurPos(iPos, isNotify ? SB_THUMBPOSITION : -1);
}
virtual void _GetScrollArea(_Out_ RECT *prc);
virtual void _SetCurPos(int nPos, int dwSB);
private:
void _AdjustWindowPos();
CScrollButtonWindow* _pBtnUp;
CScrollButtonWindow* _pBtnDn;
CScrollInfo _scrollInfo;
SIZE _sizeOfScrollBtn;
SCROLLBAR_DIRECTION _scrollDir;
};
//////////////////////////////////////////////////////////////////////
//
// CScrollBarNullWindow declaration.
//
//////////////////////////////////////////////////////////////////////
class CScrollBarNullWindow : public CScrollBarWindow
{
public:
CScrollBarNullWindow() { };
virtual ~CScrollBarNullWindow() { };
virtual BOOL _Create(ATOM atom, DWORD dwExStyle, DWORD dwStyle, _In_opt_ CBaseWindow *pParent = nullptr, int wndWidth = 0, int wndHeight = 0)
{
atom; dwExStyle; dwStyle; pParent; wndWidth; wndHeight;
return TRUE;
};
virtual void _Destroy() { };
virtual void _Move(int x, int y) { x;y; };
virtual void _Resize(int x, int y, int cx, int cy) { x; y; cx; cy; };
virtual void _Show(BOOL isShowWnd) { isShowWnd; };
virtual BOOL _IsWindowVisible() { return TRUE; };
virtual void _Enable(BOOL isEnable) { isEnable; };
virtual BOOL _IsEnabled() { return TRUE; };
virtual void _InvalidateRect() { };
virtual BOOL _GetWindowRect(_Out_ LPRECT lpRect) { lpRect->bottom = 0; lpRect->left = 0; lpRect->right = 0; lpRect->top = 0; return TRUE; };
virtual BOOL _GetClientRect(_Out_ LPRECT lpRect) { lpRect->bottom = 0; lpRect->left = 0; lpRect->right = 0; lpRect->top = 0; return TRUE; };
virtual LRESULT CALLBACK _WindowProcCallback(_In_ HWND wndHandle, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
wndHandle; uMsg; wParam; lParam;
return 0;
};
virtual void _OnPaint(_In_ HDC dcHandle, _In_ PAINTSTRUCT *pps) { dcHandle;pps; };
virtual void _OnLButtonDown(POINT pt) { pt; };
virtual void _OnLButtonUp(POINT pt) { pt; };
virtual void _OnMouseMove(POINT pt) { pt; };
virtual void _OnTimer() { };
virtual void _OnOwnerWndMoved(BOOL isResized) { isResized; };
virtual void _SetScrollInfo(_In_ CScrollInfo *lpsi) { lpsi; };
virtual void _GetScrollInfo(_In_ CScrollInfo *lpsi) { lpsi; };
virtual BOOL _GetBtnUpRect(_Out_ RECT *prc) { prc->bottom = 0; prc->left = 0; prc->right = 0; prc->top = 0; return TRUE; };
virtual BOOL _GetBtnDnRect(_Out_ RECT *prc) { prc->bottom = 0; prc->left = 0; prc->right = 0; prc->top = 0; return TRUE; };
virtual void _ShiftLine(int nLine, BOOL isNotify) { nLine; isNotify; };
virtual void _ShiftPage(int nPage, BOOL isNotify) { nPage; isNotify; };
virtual void _ShiftPosition(int iPos, BOOL isNotify) { iPos; isNotify; };
virtual void _GetScrollArea(_Out_ RECT *prc) { prc->bottom = 0; prc->left = 0; prc->right = 0; prc->top = 0; };
virtual void _SetCurPos(int nPos, DWORD dwSB) { nPos; dwSB; };
};
//////////////////////////////////////////////////////////////////////
//
// CScrollButtonWondow declaration.
//
//////////////////////////////////////////////////////////////////////
class CScrollButtonWindow : public CButtonWindow
{
public:
CScrollButtonWindow(UINT uSubType)
{
subTypeOfControl = uSubType;
}
virtual ~CScrollButtonWindow()
{
}
LRESULT CALLBACK _WindowProcCallback(_In_ HWND wndHandle, UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam)
{
wndHandle;uMsg;wParam;lParam;
return 0;
}
virtual void _OnPaint(_In_ HDC dcHandle, _In_ PAINTSTRUCT *pps);
virtual void _OnLButtonDown(POINT pt);
virtual void _OnLButtonUp(POINT pt);
virtual void _OnTimer();
private:
UINT subTypeOfControl; // DFCS_SCROLLxxx for DrawFrameControl
};
+210
View File
@@ -0,0 +1,210 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "private.h"
#include "SearchCandidateProvider.h"
#include <new>
#include "SampleIME.h"
#include "CompositionProcessorEngine.h"
#include "TipCandidateList.h"
#include "TipCandidateString.h"
/*------------------------------------------------------------------------------
create instance of CSearchCandidateProvider
------------------------------------------------------------------------------*/
HRESULT CSearchCandidateProvider::CreateInstance(_Outptr_ ITfFnSearchCandidateProvider **ppobj, _In_ ITfTextInputProcessorEx *ptip)
{
if (ppobj == nullptr)
{
return E_INVALIDARG;
}
*ppobj = nullptr;
*ppobj = new (std::nothrow) CSearchCandidateProvider(ptip);
if (nullptr == *ppobj)
{
return E_OUTOFMEMORY;
}
return S_OK;
}
/*------------------------------------------------------------------------------
create instance of CSearchCandidateProvider
------------------------------------------------------------------------------*/
HRESULT CSearchCandidateProvider::CreateInstance(REFIID riid, _Outptr_ void **ppvObj, _In_ ITfTextInputProcessorEx *ptip)
{
if (ppvObj == nullptr)
{
return E_INVALIDARG;
}
*ppvObj = nullptr;
*ppvObj = new (std::nothrow) CSearchCandidateProvider(ptip);
if (nullptr == *ppvObj)
{
return E_OUTOFMEMORY;
}
return ((CSearchCandidateProvider*)(*ppvObj))->QueryInterface(riid, ppvObj);
}
/*------------------------------------------------------------------------------
constructor of CSearchCandidateProvider
------------------------------------------------------------------------------*/
CSearchCandidateProvider::CSearchCandidateProvider(_In_ ITfTextInputProcessorEx *ptip)
{
assert(ptip != nullptr);
_pTip = ptip;
_refCount = 0;
}
/*------------------------------------------------------------------------------
destructor of CSearchCandidateProvider
------------------------------------------------------------------------------*/
CSearchCandidateProvider::~CSearchCandidateProvider(void)
{
}
/*------------------------------------------------------------------------------
query interface
(IUnknown method)
------------------------------------------------------------------------------*/
STDMETHODIMP CSearchCandidateProvider::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
{
return E_POINTER;
}
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, __uuidof(ITfFnSearchCandidateProvider)))
{
*ppvObj = (ITfFnSearchCandidateProvider*)this;
}
else if (IsEqualIID(riid, IID_ITfFunction))
{
*ppvObj = (ITfFunction*)this;
}
if (*ppvObj == nullptr)
{
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
/*------------------------------------------------------------------------------
increment reference count
(IUnknown method)
------------------------------------------------------------------------------*/
STDMETHODIMP_(ULONG) CSearchCandidateProvider::AddRef()
{
return (ULONG)InterlockedIncrement(&_refCount);
}
/*------------------------------------------------------------------------------
decrement reference count and release object
(IUnknown method)
------------------------------------------------------------------------------*/
STDMETHODIMP_(ULONG) CSearchCandidateProvider::Release()
{
ULONG ref = (ULONG)InterlockedDecrement(&_refCount);
if (0 < ref)
{
return ref;
}
delete this;
return 0;
}
STDMETHODIMP CSearchCandidateProvider::GetDisplayName(_Out_ BSTR *pbstrName)
{
if (pbstrName == nullptr)
{
return E_INVALIDARG;
}
*pbstrName = SysAllocString(L"SearchCandidateProvider");
return S_OK;
}
STDMETHODIMP CSearchCandidateProvider::GetSearchCandidates(BSTR bstrQuery, BSTR bstrApplicationID, _Outptr_result_maybenull_ ITfCandidateList **pplist)
{
bstrApplicationID;bstrQuery;
HRESULT hr = E_FAIL;
*pplist = nullptr;
if (nullptr == _pTip)
{
return hr;
}
CCompositionProcessorEngine* pCompositionProcessorEngine = ((CSampleIME*)_pTip)->GetCompositionProcessorEngine();
if (nullptr == pCompositionProcessorEngine)
{
return hr;
}
CSampleImeArray<CCandidateListItem> candidateList;
pCompositionProcessorEngine->GetCandidateList(&candidateList, TRUE, FALSE);
int cCand = min(candidateList.Count(), FAKECANDIDATENUMBER);
if (0 < cCand)
{
hr = CTipCandidateList::CreateInstance(pplist, cCand);
if (FAILED(hr))
{
return hr;
}
for (int iCand = 0; iCand < cCand; iCand++)
{
ITfCandidateString* pCandStr = nullptr;
CTipCandidateString::CreateInstance(IID_ITfCandidateString, (void**)&pCandStr);
((CTipCandidateString*)pCandStr)->SetIndex(iCand);
((CTipCandidateString*)pCandStr)->SetString(candidateList.GetAt(iCand)->_ItemString.Get(), candidateList.GetAt(iCand)->_ItemString.GetLength());
((CTipCandidateList*)(*pplist))->SetCandidate(&pCandStr);
}
}
hr = S_OK;
return hr;
}
/*------------------------------------------------------------------------------
set result
(ITfFnSearchCandidateProvider method)
------------------------------------------------------------------------------*/
STDMETHODIMP CSearchCandidateProvider::SetResult(BSTR bstrQuery, BSTR bstrApplicationID, BSTR bstrResult)
{
bstrQuery;bstrApplicationID;bstrResult;
return E_NOTIMPL;
}
+50
View File
@@ -0,0 +1,50 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
//
// CSearchCandidateProvider
//
// TfFnSearchCandidateProvider is used for search integration feature, CSearchCandidateProvider
// implements this interface that can be called by search integration, and offer the candidate list
// as search integration suggestion.
//
#define FAKECANDIDATENUMBER (16)
class CSearchCandidateProvider : public ITfFnSearchCandidateProvider
{
protected:
// constructor/destructor
CSearchCandidateProvider(_In_ ITfTextInputProcessorEx *ptip);
virtual ~CSearchCandidateProvider();
public:
// create instance
static HRESULT CreateInstance(_Outptr_ ITfFnSearchCandidateProvider **ppobj, _In_ ITfTextInputProcessorEx *ptip);
static HRESULT CreateInstance(REFIID riid, _Outptr_ void **ppvObj, _In_ ITfTextInputProcessorEx *ptip);
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// ITfFunction methods
STDMETHODIMP GetDisplayName(_Out_ BSTR *pbstrName);
// ITfFnSearchCandidateProvider methods
//
// GetSearchCandidates is responsible for supporting the candidates to caller, search integration
// SetResult is not used
//
STDMETHODIMP GetSearchCandidates(BSTR bstrQuery, BSTR bstrApplicationID, _Outptr_result_maybenull_ ITfCandidateList **pplist);
STDMETHODIMP SetResult(BSTR bstrQuery, BSTR bstrApplicationID, BSTR bstrResult);
private:
LONG _refCount;
ITfTextInputProcessorEx* _pTip;
};
+285
View File
@@ -0,0 +1,285 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
#include "SampleIME.h"
// from Register.cpp
BOOL RegisterProfiles();
void UnregisterProfiles();
BOOL RegisterCategories();
void UnregisterCategories();
BOOL RegisterServer();
void UnregisterServer();
void FreeGlobalObjects(void);
class CClassFactory;
static CClassFactory* classFactoryObjects[1] = { nullptr };
//+---------------------------------------------------------------------------
//
// DllAddRef
//
//----------------------------------------------------------------------------
void DllAddRef(void)
{
InterlockedIncrement(&Global::dllRefCount);
}
//+---------------------------------------------------------------------------
//
// DllRelease
//
//----------------------------------------------------------------------------
void DllRelease(void)
{
if (InterlockedDecrement(&Global::dllRefCount) < 0)
{
EnterCriticalSection(&Global::CS);
if (nullptr != classFactoryObjects[0])
{
FreeGlobalObjects();
}
assert(Global::dllRefCount == -1);
LeaveCriticalSection(&Global::CS);
}
}
//+---------------------------------------------------------------------------
//
// CClassFactory declaration with IClassFactory Interface
//
//----------------------------------------------------------------------------
class CClassFactory : public IClassFactory
{
public:
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IClassFactory methods
STDMETHODIMP CreateInstance(_In_opt_ IUnknown *pUnkOuter, _In_ REFIID riid, _COM_Outptr_ void **ppvObj);
STDMETHODIMP LockServer(BOOL fLock);
// Constructor
CClassFactory(REFCLSID rclsid, HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, void **ppvObj))
: _rclsid(rclsid)
{
_pfnCreateInstance = pfnCreateInstance;
}
public:
REFCLSID _rclsid;
HRESULT (*_pfnCreateInstance)(IUnknown *pUnkOuter, REFIID riid, _COM_Outptr_ void **ppvObj);
private:
CClassFactory& operator=(const CClassFactory& rhn) {rhn;};
};
//+---------------------------------------------------------------------------
//
// CClassFactory::QueryInterface
//
//----------------------------------------------------------------------------
STDAPI CClassFactory::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (IsEqualIID(riid, IID_IClassFactory) || IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = this;
DllAddRef();
return NOERROR;
}
*ppvObj = nullptr;
return E_NOINTERFACE;
}
//+---------------------------------------------------------------------------
//
// CClassFactory::AddRef
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CClassFactory::AddRef()
{
DllAddRef();
return (Global::dllRefCount + 1);
}
//+---------------------------------------------------------------------------
//
// CClassFactory::Release
//
//----------------------------------------------------------------------------
STDAPI_(ULONG) CClassFactory::Release()
{
DllRelease();
return (Global::dllRefCount + 1);
}
//+---------------------------------------------------------------------------
//
// CClassFactory::CreateInstance
//
//----------------------------------------------------------------------------
STDAPI CClassFactory::CreateInstance(_In_opt_ IUnknown *pUnkOuter, _In_ REFIID riid, _COM_Outptr_ void **ppvObj)
{
return _pfnCreateInstance(pUnkOuter, riid, ppvObj);
}
//+---------------------------------------------------------------------------
//
// CClassFactory::LockServer
//
//----------------------------------------------------------------------------
STDAPI CClassFactory::LockServer(BOOL fLock)
{
if (fLock)
{
DllAddRef();
}
else
{
DllRelease();
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// BuildGlobalObjects
//
//----------------------------------------------------------------------------
void BuildGlobalObjects(void)
{
classFactoryObjects[0] = new (std::nothrow) CClassFactory(Global::SampleIMECLSID, CSampleIME::CreateInstance);
}
//+---------------------------------------------------------------------------
//
// FreeGlobalObjects
//
//----------------------------------------------------------------------------
void FreeGlobalObjects(void)
{
for (int i = 0; i < ARRAYSIZE(classFactoryObjects); i++)
{
if (nullptr != classFactoryObjects[i])
{
delete classFactoryObjects[i];
classFactoryObjects[i] = nullptr;
}
}
DeleteObject(Global::defaultlFontHandle);
}
//+---------------------------------------------------------------------------
//
// DllGetClassObject
//
//----------------------------------------------------------------------------
_Check_return_
STDAPI DllGetClassObject(
_In_ REFCLSID rclsid,
_In_ REFIID riid,
_Outptr_ void** ppv)
{
if (classFactoryObjects[0] == nullptr)
{
EnterCriticalSection(&Global::CS);
// need to check ref again after grabbing mutex
if (classFactoryObjects[0] == nullptr)
{
BuildGlobalObjects();
}
LeaveCriticalSection(&Global::CS);
}
if (IsEqualIID(riid, IID_IClassFactory) ||
IsEqualIID(riid, IID_IUnknown))
{
for (int i = 0; i < ARRAYSIZE(classFactoryObjects); i++)
{
if (nullptr != classFactoryObjects[i] &&
IsEqualGUID(rclsid, classFactoryObjects[i]->_rclsid))
{
*ppv = (void *)classFactoryObjects[i];
DllAddRef(); // class factory holds DLL ref count
return NOERROR;
}
}
}
*ppv = nullptr;
return CLASS_E_CLASSNOTAVAILABLE;
}
//+---------------------------------------------------------------------------
//
// DllCanUnloadNow
//
//----------------------------------------------------------------------------
STDAPI DllCanUnloadNow(void)
{
if (Global::dllRefCount >= 0)
{
return S_FALSE;
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// DllUnregisterServer
//
//----------------------------------------------------------------------------
STDAPI DllUnregisterServer(void)
{
UnregisterProfiles();
UnregisterCategories();
UnregisterServer();
return S_OK;
}
//+---------------------------------------------------------------------------
//
// DllRegisterServer
//
//----------------------------------------------------------------------------
STDAPI DllRegisterServer(void)
{
if ((!RegisterServer()) || (!RegisterProfiles()) || (!RegisterCategories()))
{
DllUnregisterServer();
return E_FAIL;
}
return S_OK;
}
+370
View File
@@ -0,0 +1,370 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
#include "BaseWindow.h"
#include "ShadowWindow.h"
#define SHADOW_ALPHANUMBER (5)
#define ALPHA(x) (255 - (x))
//// Gray scale values for the shadow grades
#define GS01 255
#define GS02 254
#define GS03 253
#define GS04 252
#define GS05 250
#define GS06 246
#define GS07 245
#define GS08 242
#define GS09 241
#define GS10 227
#define GS11 217
#define GS12 213
#define GS13 212
#define GS14 199
#define GS15 180
#define GS16 172
#define GS17 171
#define GS18 155
#define GS19 144
#define GS20 142
// pre-computed alpha values for the shadow
const BYTE AlphaTable[SHADOW_ALPHANUMBER] = {
ALPHA(GS04), ALPHA(GS09), ALPHA(GS13), ALPHA(GS17), ALPHA(GS20)
};
const BYTE CornerShadowAlphaMetric[SHADOW_ALPHANUMBER][SHADOW_ALPHANUMBER] = {
ALPHA(GS08), ALPHA(GS06), ALPHA(GS05), ALPHA(GS03), ALPHA(GS02),
ALPHA(GS11), ALPHA(GS10), ALPHA(GS09), ALPHA(GS05), ALPHA(GS02),
ALPHA(GS15), ALPHA(GS14), ALPHA(GS10), ALPHA(GS07), ALPHA(GS03),
ALPHA(GS18), ALPHA(GS15), ALPHA(GS11), ALPHA(GS08), ALPHA(GS03),
ALPHA(GS19), ALPHA(GS16), ALPHA(GS12), ALPHA(GS09), ALPHA(GS04),
};
//+---------------------------------------------------------------------------
//
// _Create
//
//----------------------------------------------------------------------------
BOOL CShadowWindow::_Create(ATOM atom, DWORD dwExStyle, DWORD dwStyle, _In_opt_ CBaseWindow *pParent, int wndWidth, int wndHeight)
{
if (!CBaseWindow::_Create(atom, dwExStyle, dwStyle, pParent, wndWidth, wndHeight))
{
return FALSE;
}
return _Initialize();
}
//+---------------------------------------------------------------------------
//
// _WindowProcCallback
//
// Shadow window proc.
//----------------------------------------------------------------------------
LRESULT CALLBACK CShadowWindow::_WindowProcCallback(_In_ HWND wndHandle, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_PAINT:
{
HDC dcHandle;
PAINTSTRUCT ps;
dcHandle = BeginPaint(wndHandle, &ps);
HBRUSH hBrush = CreateSolidBrush(_color);
FillRect(dcHandle, &ps.rcPaint, hBrush);
DeleteObject(hBrush);
EndPaint(wndHandle, &ps);
}
return 0;
case WM_SETTINGCHANGE:
_OnSettingChange();
break;
}
return DefWindowProc(wndHandle, uMsg, wParam, lParam);
}
//+---------------------------------------------------------------------------
//
// _OnSettingChange
//
//----------------------------------------------------------------------------
void CShadowWindow::_OnSettingChange()
{
_InitSettings();
DWORD dwWndStyleEx = GetWindowLong(_GetWnd(), GWL_EXSTYLE);
if (_isGradient)
{
SetWindowLong(_GetWnd(), GWL_EXSTYLE, (dwWndStyleEx | WS_EX_LAYERED));
}
else
{
SetWindowLong(_GetWnd(), GWL_EXSTYLE, (dwWndStyleEx & ~WS_EX_LAYERED));
}
_AdjustWindowPos();
_InitShadow();
}
//+---------------------------------------------------------------------------
//
// _OnOwnerWndMoved
//
//----------------------------------------------------------------------------
void CShadowWindow::_OnOwnerWndMoved(BOOL isResized)
{
if (IsWindow(_GetWnd()) && _IsWindowVisible())
{
_AdjustWindowPos();
if (isResized)
{
_InitShadow();
}
}
}
//+---------------------------------------------------------------------------
//
// _Show
//
//----------------------------------------------------------------------------
void CShadowWindow::_Show(BOOL isShowWnd)
{
_OnOwnerWndMoved(TRUE);
CBaseWindow::_Show(isShowWnd);
}
//+---------------------------------------------------------------------------
//
// _Initialize
//
//----------------------------------------------------------------------------
BOOL CShadowWindow::_Initialize()
{
_InitSettings();
return TRUE;
}
//+---------------------------------------------------------------------------
//
// _InitSettings
//
//----------------------------------------------------------------------------
void CShadowWindow::_InitSettings()
{
HDC dcHandle = GetDC(nullptr);
// device caps
int cBitsPixelScreen = GetDeviceCaps(dcHandle, BITSPIXEL);
_isGradient = cBitsPixelScreen > 8;
ReleaseDC(nullptr, dcHandle);
if (_isGradient)
{
_color = RGB(0, 0, 0);
_sizeShift.cx = SHADOW_ALPHANUMBER;
_sizeShift.cy = SHADOW_ALPHANUMBER;
}
else
{
_color = RGB(128, 128, 128);
_sizeShift.cx = 2;
_sizeShift.cy = 2;
}
}
//+---------------------------------------------------------------------------
//
// _AdjustWindowPos
//
//----------------------------------------------------------------------------
void CShadowWindow::_AdjustWindowPos()
{
if (!IsWindow(_GetWnd()))
{
return;
}
HWND hWndOwner = _pWndOwner->_GetWnd();
RECT rc = {0, 0, 0, 0};
GetWindowRect(hWndOwner, &rc);
SetWindowPos(_GetWnd(), hWndOwner,
rc.left + _sizeShift.cx,
rc.top + _sizeShift.cy,
rc.right - rc.left,
rc.bottom - rc.top,
SWP_NOOWNERZORDER | SWP_NOACTIVATE);
}
//+---------------------------------------------------------------------------
//
// _InitShadow
//
//----------------------------------------------------------------------------
#define GETRGBALPHA(_x_, _y_) ((RGBALPHA *)pDIBits + (_y_) * size.cx + (_x_))
void CShadowWindow::_InitShadow()
{
typedef struct _RGBAPLHA {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbAlpha;
} RGBALPHA;
HDC dcScreenHandle = nullptr;
HDC dcLayeredHandle = nullptr;
RECT rcWindow = {0, 0, 0, 0};
SIZE size = {0, 0};
BITMAPINFO bitmapInfo;
HBITMAP bitmapMemHandle = nullptr;
HBITMAP bitmapOldHandle = nullptr;
void* pDIBits = nullptr;
int i = 0;
int j = 0;
POINT ptSrc = {0, 0};
POINT ptDst = {0, 0};
BLENDFUNCTION Blend;
if (!_isGradient)
{
return;
}
SetWindowLong(_GetWnd(), GWL_EXSTYLE, (GetWindowLong(_GetWnd(), GWL_EXSTYLE) | WS_EX_LAYERED));
_GetWindowRect(&rcWindow);
size.cx = rcWindow.right - rcWindow.left;
size.cy = rcWindow.bottom - rcWindow.top;
dcScreenHandle = GetDC(nullptr);
if (dcScreenHandle == nullptr) {
return;
}
dcLayeredHandle = CreateCompatibleDC(dcScreenHandle);
if (dcLayeredHandle == nullptr) {
ReleaseDC(nullptr, dcScreenHandle);
return;
}
// create bitmap
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biWidth = size.cx;
bitmapInfo.bmiHeader.biHeight = size.cy;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32;
bitmapInfo.bmiHeader.biCompression = BI_RGB;
bitmapInfo.bmiHeader.biSizeImage = 0;
bitmapInfo.bmiHeader.biXPelsPerMeter = 100;
bitmapInfo.bmiHeader.biYPelsPerMeter = 100;
bitmapInfo.bmiHeader.biClrUsed = 0;
bitmapInfo.bmiHeader.biClrImportant = 0;
bitmapMemHandle = CreateDIBSection(dcScreenHandle, &bitmapInfo, DIB_RGB_COLORS, &pDIBits, nullptr, 0);
if (pDIBits == nullptr || bitmapMemHandle == nullptr) {
ReleaseDC(nullptr, dcScreenHandle);
DeleteDC(dcLayeredHandle);
return;
}
memset(pDIBits, 0, ((((32 * size.cx) + 31) & ~31) / 8) * size.cy);
// edges
for (i = 0; i < SHADOW_ALPHANUMBER; i++) {
RGBALPHA *ppxl;
BYTE bAlpha = AlphaTable[i];
// bottom
if (i <= (size.cy + 1)/2) {
for (j = SHADOW_ALPHANUMBER; j < size.cx - SHADOW_ALPHANUMBER; j++) {
ppxl = GETRGBALPHA(j, i);
ppxl->rgbAlpha = bAlpha;
}
}
// right
if (i <= (size.cx + 1)/2) {
for (j = SHADOW_ALPHANUMBER; j < size.cy - SHADOW_ALPHANUMBER; j++) {
ppxl = GETRGBALPHA(size.cx - 1 - i, j);
ppxl->rgbAlpha = bAlpha;
}
}
}
// corners
for (i = 0; i < SHADOW_ALPHANUMBER; i++) {
for (j = 0; j < SHADOW_ALPHANUMBER; j++) {
RGBALPHA *ppxl;
BYTE bAlpha;
bAlpha = CornerShadowAlphaMetric[i][SHADOW_ALPHANUMBER - j - 1];
// top-right
if ((i <= (size.cy + 1)/2) && (j <= (size.cx + 1)/2)) {
ppxl = GETRGBALPHA(size.cx - 1 - j, size.cy - 1 - i);
ppxl->rgbAlpha = bAlpha;
}
// bottom-left
if ((i <= (size.cy + 1)/2) && (j <= (size.cx + 1)/2)) {
ppxl = GETRGBALPHA(j, i + 1);
ppxl->rgbAlpha = bAlpha;
}
// bottom-right
if ((i <= (size.cy + 1)/2) && (j <= (size.cx + 1)/2)) {
ppxl = GETRGBALPHA(size.cx - 1 - j, i + 1);
ppxl->rgbAlpha = bAlpha;
}
}
}
ptSrc.x = 0;
ptSrc.y = 0;
ptDst.x = rcWindow.left;
ptDst.y = rcWindow.top;
Blend.BlendOp = AC_SRC_OVER;
Blend.BlendFlags = 0;
Blend.SourceConstantAlpha = 255;
Blend.AlphaFormat = AC_SRC_ALPHA;
bitmapOldHandle = (HBITMAP)SelectObject(dcLayeredHandle, bitmapMemHandle);
UpdateLayeredWindow(_GetWnd(), dcScreenHandle, nullptr, &size, dcLayeredHandle, &ptSrc, 0, &Blend, ULW_ALPHA);
SelectObject(dcLayeredHandle, bitmapOldHandle);
// done
ReleaseDC(nullptr, dcScreenHandle);
DeleteDC(dcLayeredHandle);
DeleteObject(bitmapMemHandle);
}
+47
View File
@@ -0,0 +1,47 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "BaseWindow.h"
class CShadowWindow : public CBaseWindow
{
public:
CShadowWindow(_In_ CBaseWindow *pWndOwner)
{
_pWndOwner = pWndOwner;
_color = RGB(0, 0, 0);
_sizeShift.cx = 0;
_sizeShift.cy = 0;
_isGradient = FALSE;
}
virtual ~CShadowWindow()
{
}
BOOL _Create(ATOM atom, DWORD dwExStyle, DWORD dwStyle, _In_opt_ CBaseWindow *pParent = nullptr, int wndWidth = 0, int wndHeight = 0);
void _Show(BOOL isShowWnd);
LRESULT CALLBACK _WindowProcCallback(_In_ HWND wndHandle, UINT uMsg, WPARAM wParam, LPARAM lParam);
void _OnSettingChange();
void _OnOwnerWndMoved(BOOL isResized);
private:
BOOL _Initialize();
void _InitSettings();
void _AdjustWindowPos();
void _InitShadow();
private:
CBaseWindow* _pWndOwner;
COLORREF _color;
SIZE _sizeShift;
BOOL _isGradient;
};
+133
View File
@@ -0,0 +1,133 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
#include "EditSession.h"
#include "SampleIME.h"
//+---------------------------------------------------------------------------
//
// CStartCompositinoEditSession
//
//----------------------------------------------------------------------------
class CStartCompositionEditSession : public CEditSessionBase
{
public:
CStartCompositionEditSession(_In_ CSampleIME *pTextService, _In_ ITfContext *pContext) : CEditSessionBase(pTextService, pContext)
{
}
// ITfEditSession
STDMETHODIMP DoEditSession(TfEditCookie ec);
};
//+---------------------------------------------------------------------------
//
// ITfEditSession::DoEditSession
//
//----------------------------------------------------------------------------
STDAPI CStartCompositionEditSession::DoEditSession(TfEditCookie ec)
{
ITfInsertAtSelection* pInsertAtSelection = nullptr;
ITfRange* pRangeInsert = nullptr;
ITfContextComposition* pContextComposition = nullptr;
ITfComposition* pComposition = nullptr;
if (FAILED(_pContext->QueryInterface(IID_ITfInsertAtSelection, (void **)&pInsertAtSelection)))
{
goto Exit;
}
if (FAILED(pInsertAtSelection->InsertTextAtSelection(ec, TF_IAS_QUERYONLY, NULL, 0, &pRangeInsert)))
{
goto Exit;
}
if (FAILED(_pContext->QueryInterface(IID_ITfContextComposition, (void **)&pContextComposition)))
{
goto Exit;
}
if (SUCCEEDED(pContextComposition->StartComposition(ec, pRangeInsert, _pTextService, &pComposition)) && (nullptr != pComposition))
{
_pTextService->_SetComposition(pComposition);
// set selection to the adjusted range
TF_SELECTION tfSelection;
tfSelection.range = pRangeInsert;
tfSelection.style.ase = TF_AE_NONE;
tfSelection.style.fInterimChar = FALSE;
_pContext->SetSelection(ec, 1, &tfSelection);
_pTextService->_SaveCompositionContext(_pContext);
}
Exit:
if (nullptr != pContextComposition)
{
pContextComposition->Release();
}
if (nullptr != pRangeInsert)
{
pRangeInsert->Release();
}
if (nullptr != pInsertAtSelection)
{
pInsertAtSelection->Release();
}
return S_OK;
}
//////////////////////////////////////////////////////////////////////
//
// CSampleIME class
//
//////////////////////////////////////////////////////////////////////
//+---------------------------------------------------------------------------
//
// _StartComposition
//
// this starts the new (std::nothrow) composition at the selection of the current
// focus context.
//----------------------------------------------------------------------------
void CSampleIME::_StartComposition(_In_ ITfContext *pContext)
{
CStartCompositionEditSession* pStartCompositionEditSession = new (std::nothrow) CStartCompositionEditSession(this, pContext);
if (nullptr != pStartCompositionEditSession)
{
HRESULT hr = S_OK;
pContext->RequestEditSession(_tfClientId, pStartCompositionEditSession, TF_ES_SYNC | TF_ES_READWRITE, &hr);
pStartCompositionEditSession->Release();
}
}
//+---------------------------------------------------------------------------
//
// _SaveCompositionContext
//
// this saves the context _pComposition belongs to; we need this to clear
// text attribute in case composition has not been terminated on
// deactivation
//----------------------------------------------------------------------------
void CSampleIME::_SaveCompositionContext(_In_ ITfContext *pContext)
{
assert(_pContext == nullptr);
pContext->AddRef();
_pContext = pContext;
}
+120
View File
@@ -0,0 +1,120 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "TableDictionaryEngine.h"
#include "DictionarySearch.h"
//+---------------------------------------------------------------------------
//
// CollectWord
//
//----------------------------------------------------------------------------
VOID CTableDictionaryEngine::CollectWord(_In_ CStringRange *pKeyCode, _Inout_ CSampleImeArray<CStringRange> *pWordStrings)
{
CDictionaryResult* pdret = nullptr;
CDictionarySearch dshSearch(_locale, _pDictionaryFile, pKeyCode);
while (dshSearch.FindPhrase(&pdret))
{
for (UINT index = 0; index < pdret->_FindPhraseList.Count(); index++)
{
CStringRange* pPhrase = nullptr;
pPhrase = pWordStrings->Append();
if (pPhrase)
{
*pPhrase = *pdret->_FindPhraseList.GetAt(index);
}
}
delete pdret;
pdret = nullptr;
}
}
VOID CTableDictionaryEngine::CollectWord(_In_ CStringRange *pKeyCode, _Inout_ CSampleImeArray<CCandidateListItem> *pItemList)
{
CDictionaryResult* pdret = nullptr;
CDictionarySearch dshSearch(_locale, _pDictionaryFile, pKeyCode);
while (dshSearch.FindPhrase(&pdret))
{
for (UINT iIndex = 0; iIndex < pdret->_FindPhraseList.Count(); iIndex++)
{
CCandidateListItem* pLI = nullptr;
pLI = pItemList->Append();
if (pLI)
{
pLI->_ItemString.Set(*pdret->_FindPhraseList.GetAt(iIndex));
pLI->_FindKeyCode.Set(pdret->_FindKeyCode.Get(), pdret->_FindKeyCode.GetLength());
}
}
delete pdret;
pdret = nullptr;
}
}
//+---------------------------------------------------------------------------
//
// CollectWordForWildcard
//
//----------------------------------------------------------------------------
VOID CTableDictionaryEngine::CollectWordForWildcard(_In_ CStringRange *pKeyCode, _Inout_ CSampleImeArray<CCandidateListItem> *pItemList)
{
CDictionaryResult* pdret = nullptr;
CDictionarySearch dshSearch(_locale, _pDictionaryFile, pKeyCode);
while (dshSearch.FindPhraseForWildcard(&pdret))
{
for (UINT iIndex = 0; iIndex < pdret->_FindPhraseList.Count(); iIndex++)
{
CCandidateListItem* pLI = nullptr;
pLI = pItemList->Append();
if (pLI)
{
pLI->_ItemString.Set(*pdret->_FindPhraseList.GetAt(iIndex));
pLI->_FindKeyCode.Set(pdret->_FindKeyCode.Get(), pdret->_FindKeyCode.GetLength());
}
}
delete pdret;
pdret = nullptr;
}
}
//+---------------------------------------------------------------------------
//
// CollectWordFromConvertedStringForWildcard
//
//----------------------------------------------------------------------------
VOID CTableDictionaryEngine::CollectWordFromConvertedStringForWildcard(_In_ CStringRange *pString, _Inout_ CSampleImeArray<CCandidateListItem> *pItemList)
{
CDictionaryResult* pdret = nullptr;
CDictionarySearch dshSearch(_locale, _pDictionaryFile, pString);
while (dshSearch.FindConvertedStringForWildcard(&pdret)) // TAIL ALL CHAR MATCH
{
for (UINT index = 0; index < pdret->_FindPhraseList.Count(); index++)
{
CCandidateListItem* pLI = nullptr;
pLI = pItemList->Append();
if (pLI)
{
pLI->_ItemString.Set(*pdret->_FindPhraseList.GetAt(index));
pLI->_FindKeyCode.Set(pdret->_FindKeyCode.Get(), pdret->_FindKeyCode.GetLength());
}
}
delete pdret;
pdret = nullptr;
}
}
+30
View File
@@ -0,0 +1,30 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "BaseDictionaryEngine.h"
class CTableDictionaryEngine : public CBaseDictionaryEngine
{
public:
CTableDictionaryEngine(LCID locale, _In_ CFile *pDictionaryFile) : CBaseDictionaryEngine(locale, pDictionaryFile) { }
virtual ~CTableDictionaryEngine() { }
// Collect word from phrase string.
// param
// [in] psrgKeyCode - Specified key code pointer
// [out] pasrgWordString - Specified returns pointer of word as CStringRange.
// returns
// none.
VOID CollectWord(_In_ CStringRange *pKeyCode, _Inout_ CSampleImeArray<CStringRange> *pWordStrings);
VOID CollectWord(_In_ CStringRange *pKeyCode, _Inout_ CSampleImeArray<CCandidateListItem> *pItemList);
VOID CollectWordForWildcard(_In_ CStringRange *psrgKeyCode, _Inout_ CSampleImeArray<CCandidateListItem> *pItemList);
VOID CollectWordFromConvertedStringForWildcard(_In_ CStringRange *pString, _Inout_ CSampleImeArray<CCandidateListItem> *pItemList);
};
+134
View File
@@ -0,0 +1,134 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "globals.h"
#include "SampleIME.h"
//+---------------------------------------------------------------------------
//
// ITfTextEditSink::OnEndEdit
//
// Called by the system whenever anyone releases a write-access document lock.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnEndEdit(__RPC__in_opt ITfContext *pContext, TfEditCookie ecReadOnly, __RPC__in_opt ITfEditRecord *pEditRecord)
{
BOOL isSelectionChanged;
//
// did the selection change?
// The selection change includes the movement of caret as well.
// The caret position is represent as the empty selection range when
// there is no selection.
//
if (pEditRecord == nullptr)
{
return E_INVALIDARG;
}
if (SUCCEEDED(pEditRecord->GetSelectionStatus(&isSelectionChanged)) &&
isSelectionChanged)
{
// If the selection is moved to out side of the current composition,
// we terminate the composition. This TextService supports only one
// composition in one context object.
if (_IsComposing())
{
TF_SELECTION tfSelection;
ULONG fetched = 0;
if (pContext == nullptr)
{
return E_INVALIDARG;
}
if (FAILED(pContext->GetSelection(ecReadOnly, TF_DEFAULT_SELECTION, 1, &tfSelection, &fetched)) || fetched != 1)
{
return S_FALSE;
}
ITfRange* pRangeComposition = nullptr;
if (SUCCEEDED(_pComposition->GetRange(&pRangeComposition)))
{
if (!_IsRangeCovered(ecReadOnly, tfSelection.range, pRangeComposition))
{
_EndComposition(pContext);
}
pRangeComposition->Release();
}
tfSelection.range->Release();
}
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// _InitTextEditSink
//
// Init a text edit sink on the topmost context of the document.
// Always release any previous sink.
//----------------------------------------------------------------------------
BOOL CSampleIME::_InitTextEditSink(_In_ ITfDocumentMgr *pDocMgr)
{
ITfSource* pSource = nullptr;
BOOL ret = TRUE;
// clear out any previous sink first
if (_textEditSinkCookie != TF_INVALID_COOKIE)
{
if (SUCCEEDED(_pTextEditSinkContext->QueryInterface(IID_ITfSource, (void **)&pSource)))
{
pSource->UnadviseSink(_textEditSinkCookie);
pSource->Release();
}
_pTextEditSinkContext->Release();
_pTextEditSinkContext = nullptr;
_textEditSinkCookie = TF_INVALID_COOKIE;
}
if (pDocMgr == nullptr)
{
return TRUE; // caller just wanted to clear the previous sink
}
if (FAILED(pDocMgr->GetTop(&_pTextEditSinkContext)))
{
return FALSE;
}
if (_pTextEditSinkContext == nullptr)
{
return TRUE; // empty document, no sink possible
}
ret = FALSE;
if (SUCCEEDED(_pTextEditSinkContext->QueryInterface(IID_ITfSource, (void **)&pSource)))
{
if (SUCCEEDED(pSource->AdviseSink(IID_ITfTextEditSink, (ITfTextEditSink *)this, &_textEditSinkCookie)))
{
ret = TRUE;
}
else
{
_textEditSinkCookie = TF_INVALID_COOKIE;
}
pSource->Release();
}
if (ret == FALSE)
{
_pTextEditSinkContext->Release();
_pTextEditSinkContext = nullptr;
}
return ret;
}
+54
View File
@@ -0,0 +1,54 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "TfInputProcessorProfile.h"
CTfInputProcessorProfile::CTfInputProcessorProfile()
{
_pInputProcessorProfile = nullptr;
}
CTfInputProcessorProfile::~CTfInputProcessorProfile()
{
if (_pInputProcessorProfile) {
_pInputProcessorProfile->Release();
_pInputProcessorProfile = nullptr;
}
}
HRESULT CTfInputProcessorProfile::CreateInstance()
{
HRESULT hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, nullptr, CLSCTX_INPROC_SERVER,
IID_ITfInputProcessorProfiles, (void**)&_pInputProcessorProfile);
return hr;
}
HRESULT CTfInputProcessorProfile::GetCurrentLanguage(_Out_ LANGID *plangid)
{
if (_pInputProcessorProfile)
{
return _pInputProcessorProfile->GetCurrentLanguage(plangid);
}
else
{
return E_FAIL;
}
}
HRESULT CTfInputProcessorProfile::GetDefaultLanguageProfile(LANGID langid, REFGUID catid, _Out_ CLSID *pclsid, _Out_ GUID *pguidProfile)
{
if (_pInputProcessorProfile)
{
return _pInputProcessorProfile->GetDefaultLanguageProfile(langid, catid, pclsid, pguidProfile);
}
else
{
return E_FAIL;
}
}
+22
View File
@@ -0,0 +1,22 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
class CTfInputProcessorProfile
{
public:
CTfInputProcessorProfile();
~CTfInputProcessorProfile();
HRESULT CreateInstance();
HRESULT GetCurrentLanguage(_Out_ LANGID *plangid);
HRESULT GetDefaultLanguageProfile(LANGID langid, REFGUID catid, _Out_ CLSID *pclsid, _Out_ GUID *pguidProfile);
private:
ITfInputProcessorProfiles* _pInputProcessorProfile;
};
+220
View File
@@ -0,0 +1,220 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "TfTextLayoutSink.h"
#include "SampleIME.h"
#include "GetTextExtentEditSession.h"
CTfTextLayoutSink::CTfTextLayoutSink(_In_ CSampleIME *pTextService)
{
_pTextService = pTextService;
_pTextService->AddRef();
_pRangeComposition = nullptr;
_pContextDocument = nullptr;
_tfEditCookie = TF_INVALID_EDIT_COOKIE;
_dwCookieTextLayoutSink = TF_INVALID_COOKIE;
_refCount = 1;
DllAddRef();
}
CTfTextLayoutSink::~CTfTextLayoutSink()
{
if (_pTextService)
{
_pTextService->Release();
}
DllRelease();
}
STDAPI CTfTextLayoutSink::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
{
return E_INVALIDARG;
}
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown) ||
IsEqualIID(riid, IID_ITfTextLayoutSink))
{
*ppvObj = (ITfTextLayoutSink *)this;
}
if (*ppvObj)
{
AddRef();
return S_OK;
}
return E_NOINTERFACE;
}
STDAPI_(ULONG) CTfTextLayoutSink::AddRef()
{
return ++_refCount;
}
STDAPI_(ULONG) CTfTextLayoutSink::Release()
{
LONG cr = --_refCount;
assert(_refCount >= 0);
if (_refCount == 0)
{
delete this;
}
return cr;
}
//+---------------------------------------------------------------------------
//
// ITfTextLayoutSink::OnLayoutChange
//
//----------------------------------------------------------------------------
STDAPI CTfTextLayoutSink::OnLayoutChange(_In_ ITfContext *pContext, TfLayoutCode lcode, _In_ ITfContextView *pContextView)
{
// we're interested in only document context.
if (pContext != _pContextDocument)
{
return S_OK;
}
switch (lcode)
{
case TF_LC_CHANGE:
{
CGetTextExtentEditSession* pEditSession = nullptr;
pEditSession = new (std::nothrow) CGetTextExtentEditSession(_pTextService, pContext, pContextView, _pRangeComposition, this);
if (nullptr != (pEditSession))
{
HRESULT hr = S_OK;
pContext->RequestEditSession(_pTextService->_GetClientId(), pEditSession, TF_ES_SYNC | TF_ES_READ, &hr);
pEditSession->Release();
}
}
break;
case TF_LC_DESTROY:
_LayoutDestroyNotification();
break;
}
return S_OK;
}
HRESULT CTfTextLayoutSink::_StartLayout(_In_ ITfContext *pContextDocument, TfEditCookie ec, _In_ ITfRange *pRangeComposition)
{
_pContextDocument = pContextDocument;
_pContextDocument->AddRef();
_pRangeComposition = pRangeComposition;
_pRangeComposition->AddRef();
_tfEditCookie = ec;
return _AdviseTextLayoutSink();
}
VOID CTfTextLayoutSink::_EndLayout()
{
if (_pRangeComposition)
{
_pRangeComposition->Release();
_pRangeComposition = nullptr;
}
if (_pContextDocument)
{
_UnadviseTextLayoutSink();
_pContextDocument->Release();
_pContextDocument = nullptr;
}
}
HRESULT CTfTextLayoutSink::_AdviseTextLayoutSink()
{
HRESULT hr = S_OK;
ITfSource* pSource = nullptr;
hr = _pContextDocument->QueryInterface(IID_ITfSource, (void **)&pSource);
if (FAILED(hr))
{
return hr;
}
hr = pSource->AdviseSink(IID_ITfTextLayoutSink, (ITfTextLayoutSink *)this, &_dwCookieTextLayoutSink);
if (FAILED(hr))
{
pSource->Release();
return hr;
}
pSource->Release();
return hr;
}
HRESULT CTfTextLayoutSink::_UnadviseTextLayoutSink()
{
HRESULT hr = S_OK;
ITfSource* pSource = nullptr;
if (nullptr == _pContextDocument)
{
return E_FAIL;
}
hr = _pContextDocument->QueryInterface(IID_ITfSource, (void **)&pSource);
if (FAILED(hr))
{
return hr;
}
hr = pSource->UnadviseSink(_dwCookieTextLayoutSink);
if (FAILED(hr))
{
pSource->Release();
return hr;
}
pSource->Release();
return hr;
}
HRESULT CTfTextLayoutSink::_GetTextExt(_Out_ RECT *lpRect)
{
HRESULT hr = S_OK;
BOOL isClipped = TRUE;
ITfContextView* pContextView = nullptr;
hr = _pContextDocument->GetActiveView(&pContextView);
if (FAILED(hr))
{
return hr;
}
if (FAILED(hr = pContextView->GetTextExt(_tfEditCookie, _pRangeComposition, lpRect, &isClipped)))
{
return hr;
}
pContextView->Release();
return S_OK;
}
+46
View File
@@ -0,0 +1,46 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
class CSampleIME;
class CTfTextLayoutSink : public ITfTextLayoutSink
{
public:
CTfTextLayoutSink(_In_ CSampleIME *pTextService);
virtual ~CTfTextLayoutSink();
// IUnknown methods
STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// ITfTextLayoutSink
STDMETHODIMP OnLayoutChange(_In_ ITfContext *pContext, TfLayoutCode lcode, _In_ ITfContextView *pContextView);
HRESULT _StartLayout(_In_ ITfContext *pContextDocument, TfEditCookie ec, _In_ ITfRange *pRangeComposition);
VOID _EndLayout();
HRESULT _GetTextExt(_Out_ RECT *lpRect);
ITfContext* _GetContextDocument() { return _pContextDocument; };
virtual VOID _LayoutChangeNotification(_In_ RECT *lpRect) = 0;
virtual VOID _LayoutDestroyNotification() = 0;
private:
HRESULT _AdviseTextLayoutSink();
HRESULT _UnadviseTextLayoutSink();
private:
ITfRange* _pRangeComposition;
ITfContext* _pContextDocument;
TfEditCookie _tfEditCookie;
CSampleIME* _pTextService;
DWORD _dwCookieTextLayoutSink;
LONG _refCount;
};
+106
View File
@@ -0,0 +1,106 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "SampleIME.h"
#include "CandidateListUIPresenter.h"
//+---------------------------------------------------------------------------
//
// ITfTextLayoutSink::OnSetThreadFocus
//
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnSetThreadFocus()
{
if (_pCandidateListUIPresenter)
{
ITfDocumentMgr* pCandidateListDocumentMgr = nullptr;
ITfContext* pTfContext = _pCandidateListUIPresenter->_GetContextDocument();
if ((nullptr != pTfContext) && SUCCEEDED(pTfContext->GetDocumentMgr(&pCandidateListDocumentMgr)))
{
if (pCandidateListDocumentMgr == _pDocMgrLastFocused)
{
_pCandidateListUIPresenter->OnSetThreadFocus();
}
pCandidateListDocumentMgr->Release();
}
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfTextLayoutSink::OnKillThreadFocus
//
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnKillThreadFocus()
{
if (_pCandidateListUIPresenter)
{
ITfDocumentMgr* pCandidateListDocumentMgr = nullptr;
ITfContext* pTfContext = _pCandidateListUIPresenter->_GetContextDocument();
if ((nullptr != pTfContext) && SUCCEEDED(pTfContext->GetDocumentMgr(&pCandidateListDocumentMgr)))
{
if (_pDocMgrLastFocused)
{
_pDocMgrLastFocused->Release();
_pDocMgrLastFocused = nullptr;
}
_pDocMgrLastFocused = pCandidateListDocumentMgr;
if (_pDocMgrLastFocused)
{
_pDocMgrLastFocused->AddRef();
}
}
_pCandidateListUIPresenter->OnKillThreadFocus();
}
return S_OK;
}
BOOL CSampleIME::_InitThreadFocusSink()
{
ITfSource* pSource = nullptr;
if (FAILED(_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource)))
{
return FALSE;
}
if (FAILED(pSource->AdviseSink(IID_ITfThreadFocusSink, (ITfThreadFocusSink *)this, &_dwThreadFocusSinkCookie)))
{
pSource->Release();
return FALSE;
}
pSource->Release();
return TRUE;
}
void CSampleIME::_UninitThreadFocusSink()
{
ITfSource* pSource = nullptr;
if (FAILED(_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource)))
{
return;
}
if (FAILED(pSource->UnadviseSink(_dwThreadFocusSinkCookie)))
{
pSource->Release();
return;
}
pSource->Release();
}
+178
View File
@@ -0,0 +1,178 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "Private.h"
#include "Globals.h"
#include "SampleIME.h"
#include "CandidateListUIPresenter.h"
//+---------------------------------------------------------------------------
//
// ITfThreadMgrEventSink::OnInitDocumentMgr
//
// Sink called by the framework just before the first context is pushed onto
// a document.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnInitDocumentMgr(_In_ ITfDocumentMgr *pDocMgr)
{
pDocMgr;
return E_NOTIMPL;
}
//+---------------------------------------------------------------------------
//
// ITfThreadMgrEventSink::OnUninitDocumentMgr
//
// Sink called by the framework just after the last context is popped off a
// document.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnUninitDocumentMgr(_In_ ITfDocumentMgr *pDocMgr)
{
pDocMgr;
return E_NOTIMPL;
}
//+---------------------------------------------------------------------------
//
// ITfThreadMgrEventSink::OnSetFocus
//
// Sink called by the framework when focus changes from one document to
// another. Either document may be NULL, meaning previously there was no
// focus document, or now no document holds the input focus.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnSetFocus(_In_ ITfDocumentMgr *pDocMgrFocus, _In_ ITfDocumentMgr *pDocMgrPrevFocus)
{
pDocMgrPrevFocus;
_InitTextEditSink(pDocMgrFocus);
_UpdateLanguageBarOnSetFocus(pDocMgrFocus);
//
// We have to hide/unhide candidate list depending on whether they are
// associated with pDocMgrFocus.
//
if (_pCandidateListUIPresenter)
{
ITfDocumentMgr* pCandidateListDocumentMgr = nullptr;
ITfContext* pTfContext = _pCandidateListUIPresenter->_GetContextDocument();
if ((nullptr != pTfContext) && SUCCEEDED(pTfContext->GetDocumentMgr(&pCandidateListDocumentMgr)))
{
if (pCandidateListDocumentMgr != pDocMgrFocus)
{
_pCandidateListUIPresenter->OnKillThreadFocus();
}
else
{
_pCandidateListUIPresenter->OnSetThreadFocus();
}
pCandidateListDocumentMgr->Release();
}
}
if (_pDocMgrLastFocused)
{
_pDocMgrLastFocused->Release();
_pDocMgrLastFocused = nullptr;
}
_pDocMgrLastFocused = pDocMgrFocus;
if (_pDocMgrLastFocused)
{
_pDocMgrLastFocused->AddRef();
}
return S_OK;
}
//+---------------------------------------------------------------------------
//
// ITfThreadMgrEventSink::OnPushContext
//
// Sink called by the framework when a context is pushed.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnPushContext(_In_ ITfContext *pContext)
{
pContext;
return E_NOTIMPL;
}
//+---------------------------------------------------------------------------
//
// ITfThreadMgrEventSink::OnPopContext
//
// Sink called by the framework when a context is popped.
//----------------------------------------------------------------------------
STDAPI CSampleIME::OnPopContext(_In_ ITfContext *pContext)
{
pContext;
return E_NOTIMPL;
}
//+---------------------------------------------------------------------------
//
// _InitThreadMgrEventSink
//
// Advise our sink.
//----------------------------------------------------------------------------
BOOL CSampleIME::_InitThreadMgrEventSink()
{
ITfSource* pSource = nullptr;
BOOL ret = FALSE;
if (FAILED(_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource)))
{
return ret;
}
if (FAILED(pSource->AdviseSink(IID_ITfThreadMgrEventSink, (ITfThreadMgrEventSink *)this, &_threadMgrEventSinkCookie)))
{
_threadMgrEventSinkCookie = TF_INVALID_COOKIE;
goto Exit;
}
ret = TRUE;
Exit:
pSource->Release();
return ret;
}
//+---------------------------------------------------------------------------
//
// _UninitThreadMgrEventSink
//
// Unadvise our sink.
//----------------------------------------------------------------------------
void CSampleIME::_UninitThreadMgrEventSink()
{
ITfSource* pSource = nullptr;
if (_threadMgrEventSinkCookie == TF_INVALID_COOKIE)
{
return;
}
if (SUCCEEDED(_pThreadMgr->QueryInterface(IID_ITfSource, (void **)&pSource)))
{
pSource->UnadviseSink(_threadMgrEventSinkCookie);
pSource->Release();
}
_threadMgrEventSinkCookie = TF_INVALID_COOKIE;
}
+185
View File
@@ -0,0 +1,185 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "private.h"
#include "TipCandidateList.h"
#include "EnumTfCandidates.h"
#include "TipCandidateString.h"
HRESULT CTipCandidateList::CreateInstance(_Outptr_ ITfCandidateList **ppobj, size_t candStrReserveSize)
{
if (ppobj == nullptr)
{
return E_INVALIDARG;
}
*ppobj = nullptr;
*ppobj = new (std::nothrow) CTipCandidateList(candStrReserveSize);
if (*ppobj == nullptr)
{
return E_OUTOFMEMORY;
}
return S_OK;
}
HRESULT CTipCandidateList::CreateInstance(REFIID riid, _Outptr_ void **ppvObj, size_t candStrReserveSize)
{
if (ppvObj == nullptr)
{
return E_INVALIDARG;
}
*ppvObj = nullptr;
*ppvObj = new (std::nothrow) CTipCandidateList(candStrReserveSize);
if (*ppvObj == nullptr)
{
return E_OUTOFMEMORY;
}
return ((CTipCandidateList*)(*ppvObj))->QueryInterface(riid, ppvObj);
}
CTipCandidateList::CTipCandidateList(size_t candStrReserveSize)
{
_refCount = 0;
if (0 < candStrReserveSize)
{
_tfCandStrList.reserve(candStrReserveSize);
}
}
CTipCandidateList::~CTipCandidateList()
{
}
STDMETHODIMP CTipCandidateList::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
{
return E_POINTER;
}
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (ITfCandidateList*)this;
}
else if (IsEqualIID(riid, IID_ITfCandidateList))
{
*ppvObj = (ITfCandidateList*)this;
}
if (*ppvObj == nullptr)
{
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) CTipCandidateList::AddRef()
{
return (ULONG)InterlockedIncrement((LONG*)&_refCount);
}
STDMETHODIMP_(ULONG) CTipCandidateList::Release()
{
ULONG cRefT = (ULONG)InterlockedDecrement((LONG*)&_refCount);
if (0 < cRefT)
{
return cRefT;
}
delete this;
return 0;
}
STDMETHODIMP CTipCandidateList::EnumCandidates(_Outptr_ IEnumTfCandidates **ppEnum)
{
return CEnumTfCandidates::CreateInstance(IID_IEnumTfCandidates, (void**)ppEnum, _tfCandStrList);
}
STDMETHODIMP CTipCandidateList::GetCandidate(ULONG nIndex, _Outptr_result_maybenull_ ITfCandidateString **ppCandStr)
{
if (ppCandStr == nullptr)
{
return E_POINTER;
}
*ppCandStr = nullptr;
ULONG sizeCandStr = (ULONG)_tfCandStrList.Count();
if (sizeCandStr <= nIndex)
{
return E_FAIL;
}
for (UINT i = 0; i < _tfCandStrList.Count(); i++)
{
ITfCandidateString** ppCandStrCur = _tfCandStrList.GetAt(i);
ULONG indexCur = 0;
if ((nullptr != ppCandStrCur) && (SUCCEEDED((*ppCandStrCur)->GetIndex(&indexCur))))
{
if (nIndex == indexCur)
{
BSTR bstr;
CTipCandidateString* pTipCandidateStrCur = (CTipCandidateString*)(*ppCandStrCur);
pTipCandidateStrCur->GetString(&bstr);
CTipCandidateString::CreateInstance(IID_ITfCandidateString, (void**)ppCandStr);
if (nullptr != (*ppCandStr))
{
CTipCandidateString* pTipCandidateStr = (CTipCandidateString*)(*ppCandStr);
pTipCandidateStr->SetString((LPCWSTR)bstr, SysStringLen(bstr));
}
SysFreeString(bstr);
break;
}
}
}
return S_OK;
}
STDMETHODIMP CTipCandidateList::GetCandidateNum(_Out_ ULONG *pnCnt)
{
if (pnCnt == nullptr)
{
return E_POINTER;
}
*pnCnt = (ULONG)(_tfCandStrList.Count());
return S_OK;
}
STDMETHODIMP CTipCandidateList::SetResult(ULONG nIndex, TfCandidateResult imcr)
{
nIndex;imcr;
return E_NOTIMPL;
}
STDMETHODIMP CTipCandidateList::SetCandidate(_In_ ITfCandidateString **ppCandStr)
{
if (ppCandStr == nullptr)
{
return E_POINTER;
}
ITfCandidateString** ppCandLast = _tfCandStrList.Append();
if (ppCandLast)
{
*ppCandLast = *ppCandStr;
}
return S_OK;
}
+43
View File
@@ -0,0 +1,43 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "SampleIMEBaseStructure.h"
//
// CTipCandidateList
//
class CTipCandidateList : public ITfCandidateList
{
protected:
CTipCandidateList(size_t candStrReserveSize);
virtual ~CTipCandidateList();
public:
static HRESULT CreateInstance(_Outptr_ ITfCandidateList **ppobj, size_t candStrReserveSize = 0);
static HRESULT CreateInstance(REFIID riid, _Outptr_ void **ppvObj, size_t candStrReserveSize = 0);
// IUnknown methods
virtual STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
virtual STDMETHODIMP_(ULONG) AddRef();
virtual STDMETHODIMP_(ULONG) Release();
// ITfCandidateList methods
virtual STDMETHODIMP EnumCandidates(_Outptr_ IEnumTfCandidates **ppEnum);
virtual STDMETHODIMP GetCandidate(ULONG nIndex, _Outptr_result_maybenull_ ITfCandidateString **ppCandStr);
virtual STDMETHODIMP GetCandidateNum(_Out_ ULONG *pnCnt);
virtual STDMETHODIMP SetResult(ULONG nIndex, TfCandidateResult imcr);
virtual STDMETHODIMP SetCandidate(_In_ ITfCandidateString **ppCandStr);
protected:
long _refCount;
CSampleImeArray<ITfCandidateString*> _tfCandStrList;
};
+128
View File
@@ -0,0 +1,128 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#include "private.h"
#include "TipCandidateString.h"
HRESULT CTipCandidateString::CreateInstance(_Outptr_ CTipCandidateString **ppobj)
{
if (ppobj == nullptr)
{
return E_INVALIDARG;
}
*ppobj = nullptr;
*ppobj = new (std::nothrow) CTipCandidateString();
if (*ppobj == nullptr)
{
return E_OUTOFMEMORY;
}
return S_OK;
}
HRESULT CTipCandidateString::CreateInstance(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
{
return E_INVALIDARG;
}
*ppvObj = nullptr;
*ppvObj = new (std::nothrow) CTipCandidateString();
if (*ppvObj == nullptr)
{
return E_OUTOFMEMORY;
}
return ((CTipCandidateString*)(*ppvObj))->QueryInterface(riid, ppvObj);
}
CTipCandidateString::CTipCandidateString(void)
{
_refCount = 0;
_index = 0;
}
CTipCandidateString::~CTipCandidateString()
{
}
// IUnknown methods
STDMETHODIMP CTipCandidateString::QueryInterface(REFIID riid, _Outptr_ void **ppvObj)
{
if (ppvObj == nullptr)
{
return E_POINTER;
}
*ppvObj = nullptr;
if (IsEqualIID(riid, IID_IUnknown))
{
*ppvObj = (CTipCandidateString*)this;
}
else if (IsEqualIID(riid, IID_ITfCandidateString))
{
*ppvObj = (CTipCandidateString*)this;
}
if (*ppvObj == nullptr)
{
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
STDMETHODIMP_(ULONG) CTipCandidateString::AddRef(void)
{
return (ULONG)InterlockedIncrement((LONG*)&_refCount);
}
STDMETHODIMP_(ULONG) CTipCandidateString::Release(void)
{
ULONG refT = (ULONG)InterlockedDecrement((LONG*)&_refCount);
if (0 < refT)
{
return refT;
}
delete this;
return 0;
}
// ITfCandidateString methods
STDMETHODIMP CTipCandidateString::GetString(BSTR *pbstr)
{
*pbstr = SysAllocString(_candidateStr.c_str());
return S_OK;
}
STDMETHODIMP CTipCandidateString::GetIndex(_Out_ ULONG *pnIndex)
{
if (pnIndex == nullptr)
{
return E_POINTER;
}
*pnIndex = _index;
return S_OK;
}
STDMETHODIMP CTipCandidateString::SetIndex(ULONG uIndex)
{
_index = uIndex;
return S_OK;
}
STDMETHODIMP CTipCandidateString::SetString(_In_ const WCHAR *pch, DWORD_PTR length)
{
_candidateStr.assign(pch, 0, length);
return S_OK;
}
+39
View File
@@ -0,0 +1,39 @@
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved
#pragma once
#include "private.h"
#include <string>
class CTipCandidateString : public ITfCandidateString
{
protected:
CTipCandidateString();
virtual ~CTipCandidateString();
public:
static HRESULT CreateInstance(_Outptr_ CTipCandidateString **ppobj);
static HRESULT CreateInstance(REFIID riid, _Outptr_ void **ppvObj);
// IUnknown methods
virtual STDMETHODIMP QueryInterface(REFIID riid, _Outptr_ void **ppvObj);
virtual STDMETHODIMP_(ULONG) AddRef();
virtual STDMETHODIMP_(ULONG) Release();
// ITfCandidateString methods
virtual STDMETHODIMP GetString(BSTR *pbstr);
virtual STDMETHODIMP GetIndex(_Out_ ULONG *pnIndex);
virtual STDMETHODIMP SetIndex(ULONG uIndex);
virtual STDMETHODIMP SetString(_In_ const WCHAR *pch, DWORD_PTR length);
protected:
long _refCount;
int _index;
std::wstring _candidateStr;
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Loaded 100 of 103 files, more files were not shown because too many files have changed in this diff. Show more