Skip to content

Commit f77f85d

Browse files
committed
Enable IME text reconversion in editor view
1 parent 7bbd512 commit f77f85d

File tree

2 files changed

+127
-0
lines changed

2 files changed

+127
-0
lines changed

Externals/crystaledit/editlib/ccrystaltextview.cpp

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,7 @@ ON_COMMAND (ID_EDIT_MARK, OnEditMark)
183183
ON_WM_MOUSEWHEEL ()
184184
ON_WM_MOUSEHWHEEL ()
185185
ON_MESSAGE (WM_IME_STARTCOMPOSITION, OnImeStartComposition) /* IME */
186+
ON_MESSAGE (WM_IME_REQUEST, OnImeRequest) /* IME */
186187
//}}AFX_MSG_MAP
187188
ON_COMMAND (ID_EDIT_CHAR_LEFT, OnCharLeft)
188189
ON_COMMAND (ID_EDIT_EXT_CHAR_LEFT, OnExtCharLeft)
@@ -6800,6 +6801,129 @@ LRESULT CCrystalTextView::OnImeStartComposition(WPARAM wParam, LPARAM lParam) /*
68006801
return DefWindowProc(WM_IME_STARTCOMPOSITION, wParam, lParam);
68016802
}
68026803

6804+
LRESULT CCrystalTextView::BuildReconvertString(
6805+
RECONVERTSTRING* pReconv, int nLineIndex, DWORD dwTargetCharOffset, DWORD dwTargetCharLen)
6806+
{
6807+
int nLineLen = GetLineLength(nLineIndex);
6808+
const tchar_t* pszLine = GetLineChars(nLineIndex);
6809+
if (pszLine == nullptr || nLineLen <= 0)
6810+
return 0;
6811+
6812+
DWORD dwStrLen = static_cast<DWORD>(nLineLen);
6813+
6814+
// clamp
6815+
dwTargetCharOffset = (std::min)(dwTargetCharOffset, dwStrLen);
6816+
if (dwTargetCharOffset + dwTargetCharLen > dwStrLen)
6817+
dwTargetCharLen = dwStrLen - dwTargetCharOffset;
6818+
6819+
DWORD dwSize = sizeof(RECONVERTSTRING) + (dwStrLen + 1) * sizeof(tchar_t);
6820+
6821+
if (pReconv == nullptr)
6822+
return static_cast<LRESULT>(dwSize);
6823+
6824+
if (pReconv->dwSize < dwSize)
6825+
return 0;
6826+
6827+
pReconv->dwSize = dwSize;
6828+
pReconv->dwVersion = 0;
6829+
pReconv->dwStrLen = dwStrLen;
6830+
pReconv->dwStrOffset = sizeof(RECONVERTSTRING);
6831+
pReconv->dwCompStrLen = dwTargetCharLen;
6832+
pReconv->dwCompStrOffset = dwTargetCharOffset * sizeof(tchar_t);
6833+
pReconv->dwTargetStrLen = dwTargetCharLen;
6834+
pReconv->dwTargetStrOffset = dwTargetCharOffset * sizeof(tchar_t);
6835+
6836+
tchar_t* pszDest = reinterpret_cast<tchar_t*>(
6837+
reinterpret_cast<BYTE*>(pReconv) + pReconv->dwStrOffset);
6838+
6839+
memcpy(pszDest, pszLine, dwStrLen * sizeof(tchar_t));
6840+
pszDest[dwStrLen] = _T('\0');
6841+
6842+
return static_cast<LRESULT>(dwSize);
6843+
}
6844+
6845+
LRESULT CCrystalTextView::OnImeRequest(WPARAM wParam, LPARAM lParam)
6846+
{
6847+
if (wParam != IMR_RECONVERTSTRING &&
6848+
wParam != IMR_CONFIRMRECONVERTSTRING &&
6849+
wParam != IMR_DOCUMENTFEED)
6850+
return DefWindowProc(WM_IME_REQUEST, wParam, lParam);
6851+
6852+
switch (wParam)
6853+
{
6854+
case IMR_RECONVERTSTRING:
6855+
{
6856+
CEPoint ptCursor = GetCursorPos();
6857+
int nLineIndex = ptCursor.y;
6858+
DWORD dwOffset = static_cast<DWORD>(ptCursor.x);
6859+
DWORD dwLen = 0;
6860+
6861+
if (IsSelection())
6862+
{
6863+
CEPoint s, e;
6864+
GetSelection(s, e);
6865+
if (s.y != e.y)
6866+
return 0;
6867+
nLineIndex = s.y;
6868+
dwOffset = static_cast<DWORD>(s.x);
6869+
dwLen = static_cast<DWORD>(e.x - s.x);
6870+
}
6871+
6872+
return BuildReconvertString(
6873+
reinterpret_cast<RECONVERTSTRING*>(lParam), nLineIndex, dwOffset, dwLen);
6874+
}
6875+
6876+
case IMR_CONFIRMRECONVERTSTRING:
6877+
{
6878+
RECONVERTSTRING* pReconv = reinterpret_cast<RECONVERTSTRING*>(lParam);
6879+
if (pReconv == nullptr)
6880+
return FALSE;
6881+
6882+
DWORD dwCompCharOffset = pReconv->dwCompStrOffset / sizeof(tchar_t);
6883+
DWORD dwCompCharLen = pReconv->dwCompStrLen;
6884+
6885+
CEPoint ptCursor = GetCursorPos();
6886+
int nLineIndex = ptCursor.y;
6887+
6888+
if (IsSelection())
6889+
{
6890+
CEPoint ptSelStart, ptSelEnd;
6891+
GetSelection(ptSelStart, ptSelEnd);
6892+
if (ptSelStart.y != ptSelEnd.y)
6893+
return FALSE; // Multi-line selection not supported
6894+
nLineIndex = ptSelStart.y;
6895+
}
6896+
6897+
// IME adjusted the range but resulted in zero length - reject this
6898+
int nLineLen = GetLineLength(nLineIndex);
6899+
if (dwCompCharLen == 0)
6900+
return FALSE;
6901+
if (dwCompCharOffset >= static_cast<DWORD>(nLineLen))
6902+
return FALSE;
6903+
if (dwCompCharOffset + dwCompCharLen > static_cast<DWORD>(nLineLen))
6904+
return FALSE;
6905+
6906+
CEPoint ptNewStart(static_cast<int>(dwCompCharOffset), nLineIndex);
6907+
CEPoint ptNewEnd(static_cast<int>(dwCompCharOffset + dwCompCharLen), nLineIndex);
6908+
SetSelection(ptNewStart, ptNewEnd);
6909+
SetCursorPos(ptNewStart);
6910+
EnsureVisible(ptNewStart);
6911+
UpdateCompositionWindowPos();
6912+
6913+
return TRUE;
6914+
}
6915+
6916+
case IMR_DOCUMENTFEED:
6917+
{
6918+
CEPoint ptCursor = GetCursorPos();
6919+
return BuildReconvertString(
6920+
reinterpret_cast<RECONVERTSTRING*>(lParam), ptCursor.y, static_cast<DWORD>(ptCursor.x), 0);
6921+
}
6922+
}
6923+
6924+
return 0; // Should not reach here
6925+
}
6926+
68036927
void CCrystalTextView::OnEditDeleteBack()
68046928
{
68056929
if( !m_bIncrementalSearchForward && !m_bIncrementalSearchBackward )

Externals/crystaledit/editlib/ccrystaltextview.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class CFindTextDlg;
5353
struct LastSearchInfos;
5454
class CCrystalTextMarkers;
5555
class CEditReplaceDlg;
56+
struct tagRECONVERTSTRING;
5657

5758
////////////////////////////////////////////////////////////////////////////
5859
// CCrystalTextView class declaration
@@ -875,6 +876,8 @@ protected :
875876
afx_msg BOOL OnMouseWheel (UINT nFlags, short zDelta, CPoint pt);
876877
afx_msg void OnMouseHWheel (UINT nFlags, short zDelta, CPoint pt);
877878
LRESULT OnImeStartComposition(WPARAM wParam, LPARAM lParam);
879+
LRESULT BuildReconvertString(struct tagRECONVERTSTRING* pReconv, int nLineIndex, DWORD dwTargetCharOffset, DWORD dwTargetCharLen);
880+
LRESULT OnImeRequest(WPARAM wParam, LPARAM lParam);
878881
//}}AFX_MSG
879882
afx_msg void OnFilePageSetup ();
880883

0 commit comments

Comments
 (0)