#include "stdafx.h" #include "common.h" extern HFONT hFont_TextEdit,hFont_HyperLink_TextEdit; extern int font_width,font_height; void TextEditEvent_IME_StartComposition(HWND hwnd){ int WndNum; WndNum=GetWndNum(GetParent(hwnd)); int iControlTabSpace; iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace; HIMC hIMC; hIMC=ImmGetContext(hwnd); //コンポジションをセット POINT pos; COMPOSITIONFORM CompForm; CompForm.dwStyle=CFS_POINT; pos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos; GetScrollBaseCaretPos(MdiInfo[WndNum],(int *)&pos.x,(int *)&pos.y); CompForm.ptCurrentPos.x=pos.x*font_width+iControlTabSpace; CompForm.ptCurrentPos.y=pos.y*font_height; ImmSetCompositionWindow(hIMC, &CompForm); //フォントをセット ImmSetCompositionFont(hIMC,&pobj_nv->lf); ImmReleaseContext(hwnd,hIMC); } namespace { void SetNextCompositionWindowPos(HIMC himc, int WndNum){ int iControlTabSpace; iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace; COMPOSITIONFORM CompForm; CompForm.dwStyle=CFS_POINT; POINT pos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos; GetScrollBaseCaretPos(MdiInfo[WndNum],(int *)&pos.x,(int *)&pos.y); CompForm.ptCurrentPos.x=pos.x*font_width+iControlTabSpace; CompForm.ptCurrentPos.y=pos.y*font_height; ImmSetCompositionWindow(himc, &CompForm); } } BOOL TextEditEvent_IME_Composition(HWND hwnd,LPARAM lParam){ if(lParam&GCS_RESULTSTR){ int WndNum; WndNum=GetWndNum(GetParent(hwnd)); //////////////////// // 確定文字列を取得 //////////////////// //コンテキストを取得 HIMC hIMC; hIMC=ImmGetContext(hwnd); int i; char temporary[4096]; i=ImmGetCompositionString(hIMC, GCS_RESULTSTR, temporary,4096); if(i==0) return 0; temporary[i]=0; //バッファをリプレイス TextEdit_ReplaceUpdateUndoData(WndNum,temporary,0,1); UpdateWindow(hwnd); //コンポジションをセット(立て続けにIME入力が行われる場合を考慮) SetNextCompositionWindowPos(hIMC, WndNum); //コンテキストを解放 ImmReleaseContext(hwnd,hIMC); return 0; //DefWindowProcへ渡さないようTextEditProcへ指示 } return 1; } namespace { //PCSTRを受け渡すようにした_mbschrのラッパ inline PCSTR cmbschr(PCSTR p, UINT c) { return reinterpret_cast(_mbschr(reinterpret_cast(p), c)); } //chPos文字目が含まれる行の先頭へのオフセットを返す。 ptrdiff_t FindLineStartPos(PCSTR pBufStart, LONG CharPos) { //行頭を探す PCSTR pBufLineStart = pBufStart+CharPos; for(;;){ PCSTR p = CharPrev(pBufStart, pBufLineStart); if (*p=='\n' || pBufLineStart==pBufStart) break; pBufLineStart = p; } return pBufLineStart-pBufStart; } } LRESULT TextEditEvent_IME_RecomvertString(HWND hwnd, RECONVERTSTRING* prcs){ int WndNum = GetWndNum(GetParent(hwnd)); CHARRANGE SelRange; TextEdit_GetSel(WndNum, &SelRange); //選択範囲(キャレット)を含む行を探す(その行全体を返すため) PCSTR pBufStart = MdiInfo[WndNum]->pMdiTextEdit->buffer; ptrdiff_t LineStartPos = FindLineStartPos(pBufStart, SelRange.cpMin); ptrdiff_t LineEndPos; //行末を探す if(PCSTR pEnd = cmbschr(pBufStart+SelRange.cpMax,'\r')){ LineEndPos = pEnd-pBufStart; } else{ LineEndPos = static_cast(strlen(pBufStart)); } ptrdiff_t SelStrLen = LineEndPos-LineStartPos; //選択部分の長さ(選択範囲がなければそのまま0で良い) LRESULT lr = sizeof (RECONVERTSTRING)+SelStrLen+1; if(prcs){ //必要な情報の設定 //1行分の文字列と変換部分のオフセットを渡すようにしている PSTR pszBuf = reinterpret_cast(&prcs[1]); memcpy(pszBuf, pBufStart+LineStartPos, static_cast(SelStrLen)); pszBuf[SelStrLen] = '\0'; DWORD StrLen = SelRange.cpMax-SelRange.cpMin; DWORD StrOffset = SelRange.cpMin-LineStartPos; prcs->dwStrLen = SelStrLen; prcs->dwStrOffset = sizeof(*prcs); prcs->dwCompStrLen = StrLen; prcs->dwCompStrOffset = StrOffset; prcs->dwTargetStrLen = StrLen; prcs->dwTargetStrOffset = StrOffset; } return lr; } BOOL TextEditEvent_IME_ConfirmRecomvertString(HWND hwnd, RECONVERTSTRING* prcs){ int WndNum = GetWndNum(GetParent(hwnd)); CHARRANGE SelRange; TextEdit_GetSel(WndNum, &SelRange); //選択範囲(キャレット)を含む行を探す(その行全体を返すため) PCSTR pBufStart = MdiInfo[WndNum]->pMdiTextEdit->buffer; ptrdiff_t LineStartPos = FindLineStartPos(pBufStart, SelRange.cpMin); //再変換部分が通知されるので、そこを選択状態にする。 int ReconvStartPos = static_cast(LineStartPos+prcs->dwCompStrOffset); TextEdit_SetSel(WndNum, ReconvStartPos, ReconvStartPos+static_cast(prcs->dwCompStrLen)); //候補ウィンドウの位置の設定 if (HIMC himc = ImmGetContext(hwnd)){ SetNextCompositionWindowPos(himc, WndNum); ImmReleaseContext(hwnd, himc); } return TRUE; }