Files
msime-windows/windows/src/Key/KeyStateCategory.h
T
Jia Sui 2576986881 feat(windows): Ctrl+左右键按分词移动光标
组词中 Ctrl+Left/Right 按一个字的拼音(音节段)移动光标,
与 Ctrl+Backspace 的删除粒度共用同一套引擎分段边界。

- 闸门归纳为 SegmentEditFunction(code, modifiers):Ctrl-only + 组词存在,
  VK_BACK/LEFT/RIGHT 分别映射到 segment 函数;三处判据与延迟投影共用
- 新增 FUNCTION_MOVE_LEFT_SEGMENT / FUNCTION_MOVE_RIGHT_SEGMENT,
  编辑会话只按 CompositionRestored 的 caret 移动本地光标,不重建 buffer
- Server 用 segment_raw_boundaries() 取前/后边界,能力位与非 UiLess 时回包;
  非拼音/本地模式/UiLess/旧端仍按单字符 ±1 回退

Refs #187
2026-09-17 23:36:34 +08:00

287 lines
8.5 KiB
C++

#pragma once
#include "Globals.h"
#include "Private.h"
#include "MetasequoiaIME.h"
#include <cstdint>
#include <string>
class CKeyStateCategory;
class CKeyStateCategoryFactory
{
public:
static CKeyStateCategoryFactory *Instance();
CKeyStateCategory *MakeKeyStateCategory(KEYSTROKE_CATEGORY keyCategory, _In_ CMetasequoiaIME *pTextService);
void Release();
protected:
CKeyStateCategoryFactory();
private:
static thread_local CKeyStateCategoryFactory *_instance;
};
typedef struct KeyHandlerEditSessionDTO
{
KeyHandlerEditSessionDTO::KeyHandlerEditSessionDTO(TfEditCookie tFEC, _In_ ITfContext *pTfContext, UINT virualCode,
WCHAR inputChar, KEYSTROKE_FUNCTION arrowKeyFunction,
uint64_t pipeRequestId,
const std::wstring &sessionPrefetchedText)
{
ec = tFEC;
pContext = pTfContext;
code = virualCode;
wch = inputChar;
arrowKey = arrowKeyFunction;
requestId = pipeRequestId;
prefetchedText = sessionPrefetchedText;
}
TfEditCookie ec;
ITfContext *pContext;
UINT code;
WCHAR wch;
KEYSTROKE_FUNCTION arrowKey;
uint64_t requestId;
std::wstring prefetchedText;
} KeyHandlerEditSessionDTO;
class CKeyStateCategory
{
public:
CKeyStateCategory(_In_ CMetasequoiaIME *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);
// HandleKeyFinalizeCandidatelist
virtual HRESULT HandleKeyFinalizeCandidatelistForVKReturn(KeyHandlerEditSessionDTO dto);
// HandleKeyConvert
virtual HRESULT HandleKeyConvert(KeyHandlerEditSessionDTO dto);
// HandleKeyConvertWild
virtual HRESULT HandleKeyConvertWildCard(KeyHandlerEditSessionDTO dto);
// HandleKeyCancel
virtual HRESULT HandleKeyCancel(KeyHandlerEditSessionDTO dto);
// _HandleKeyToogleIMEMode
virtual HRESULT HandleKeyToogleIMEMode(KeyHandlerEditSessionDTO dto);
// HandleKeyBackspace
virtual HRESULT HandleKeyBackspace(KeyHandlerEditSessionDTO dto);
// HandleKeySegmentBackspace (Ctrl+Backspace: one input unit)
virtual HRESULT HandleKeySegmentBackspace(KeyHandlerEditSessionDTO dto);
// HandleKeyDelete
virtual HRESULT HandleKeyDelete(KeyHandlerEditSessionDTO dto);
// HandleKeyArrow
virtual HRESULT HandleKeyArrow(KeyHandlerEditSessionDTO dto);
// HandleKeyArrowSegment (Ctrl+Left / Ctrl+Right: one input unit)
virtual HRESULT HandleKeyArrowSegment(KeyHandlerEditSessionDTO dto);
// HandleKeyDoubleSingleByte
virtual HRESULT HandleKeyDoubleSingleByte(KeyHandlerEditSessionDTO dto);
// HandleKeyPunctuation
virtual HRESULT HandleKeyPunctuation(KeyHandlerEditSessionDTO dto);
// HandleKeySelectByNumber
virtual HRESULT HandleKeySelectByNumber(KeyHandlerEditSessionDTO dto);
protected:
CMetasequoiaIME *_pTextService;
};
class CKeyStateComposing : public CKeyStateCategory
{
public:
CKeyStateComposing(_In_ CMetasequoiaIME *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);
// HandleKeyToogleIMEMode
HRESULT HandleKeyToogleIMEMode(KeyHandlerEditSessionDTO dto);
// HandleCompositionBackspace
HRESULT HandleKeyBackspace(KeyHandlerEditSessionDTO dto);
// HandleCompositionBackspaceSegment
HRESULT HandleKeySegmentBackspace(KeyHandlerEditSessionDTO dto);
// HandleCompositionDelete
HRESULT HandleKeyDelete(KeyHandlerEditSessionDTO dto);
// HandleArrowKey
HRESULT HandleKeyArrow(KeyHandlerEditSessionDTO dto);
// HandleKeyArrowSegment (Ctrl+Left / Ctrl+Right: one input unit)
HRESULT HandleKeyArrowSegment(KeyHandlerEditSessionDTO dto);
// HandleKeyDoubleSingleByte
HRESULT HandleKeyDoubleSingleByte(KeyHandlerEditSessionDTO dto);
// HandleKeyCompositionPunctuation
HRESULT HandleKeyPunctuation(KeyHandlerEditSessionDTO dto);
};
class CKeyStateCandidate : public CKeyStateCategory
{
public:
CKeyStateCandidate(_In_ CMetasequoiaIME *pTextService);
protected:
// HandleKeyFinalizeCandidatelist
HRESULT HandleKeyFinalizeCandidatelist(KeyHandlerEditSessionDTO dto);
HRESULT HandleKeyFinalizeCandidatelistForVKReturn(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);
};
// degeneration class
class CKeyStateNull : public CKeyStateCategory
{
public:
CKeyStateNull(_In_ CMetasequoiaIME *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);
};
};