Ignore:
Timestamp:
Jul 18, 2008, 11:05:40 PM (16 years ago)
Author:
イグトランス (egtra)
Message:

再変換の実装

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ab5.0/abdev/abdev/TextEditor_ImeEvent.cpp

    r655 r691  
    3232}
    3333
     34namespace
     35{
     36    void SetNextCompositionWindowPos(HIMC himc, int WndNum){
     37        int iControlTabSpace;
     38        iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace;
     39        COMPOSITIONFORM CompForm;
     40        CompForm.dwStyle=CFS_POINT;
     41        POINT pos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
     42        GetScrollBaseCaretPos(MdiInfo[WndNum],(int *)&pos.x,(int *)&pos.y);
     43        CompForm.ptCurrentPos.x=pos.x*font_width+iControlTabSpace;
     44        CompForm.ptCurrentPos.y=pos.y*font_height;
     45        ImmSetCompositionWindow(himc, &CompForm);
     46    }
     47}
     48
    3449BOOL TextEditEvent_IME_Composition(HWND hwnd,LPARAM lParam){
    3550    if(lParam&GCS_RESULTSTR){
    3651        int WndNum;
    3752        WndNum=GetWndNum(GetParent(hwnd));
    38 
    39         int iControlTabSpace;
    40         iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace;
    4153
    4254        ////////////////////
     
    5971
    6072        //コンポジションをセット(立て続けにIME入力が行われる場合を考慮)
    61         POINT pos;
    62         COMPOSITIONFORM CompForm;
    63         CompForm.dwStyle=CFS_POINT;
    64         pos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
    65         GetScrollBaseCaretPos(MdiInfo[WndNum],(int *)&pos.x,(int *)&pos.y);
    66         CompForm.ptCurrentPos.x=pos.x*font_width+iControlTabSpace;
    67         CompForm.ptCurrentPos.y=pos.y*font_height;
    68         ImmSetCompositionWindow(hIMC, &CompForm);
     73        SetNextCompositionWindowPos(hIMC, WndNum);
    6974
    7075        //コンテキストを解放
    7176        ImmReleaseContext(hwnd,hIMC);
     77
     78        return 0; //DefWindowProcへ渡さないようTextEditProcへ指示
    7279    }
    7380
    7481    return 1;
    7582}
     83
     84namespace
     85{
     86    //PCSTRを受け渡すようにした_mbschrのラッパ
     87    inline PCSTR cmbschr(PCSTR p, UINT c)
     88    {
     89        return reinterpret_cast<PCSTR>(_mbschr(reinterpret_cast<UCHAR const*>(p), c));
     90    }
     91
     92    //chPos文字目が含まれる行の先頭へのオフセットを返す。
     93    ptrdiff_t FindLineStartPos(PCSTR pBufStart, LONG CharPos)
     94    {
     95        //行頭を探す
     96        PCSTR pBufLineStart = pBufStart+CharPos;
     97        for(;;){
     98            PCSTR p = CharPrev(pBufStart, pBufLineStart);
     99            if (*p=='\n' || pBufLineStart==pBufStart)
     100                break;
     101            pBufLineStart = p;
     102        }
     103        return pBufLineStart-pBufStart;
     104    }
     105}
     106
     107LRESULT TextEditEvent_IME_RecomvertString(HWND hwnd, RECONVERTSTRING* prcs){
     108    int WndNum = GetWndNum(GetParent(hwnd));
     109    CHARRANGE SelRange;
     110    TextEdit_GetSel(WndNum, &SelRange);
     111    //選択範囲(キャレット)を含む行を探す(その行全体を返すため)
     112    PCSTR pBufStart = MdiInfo[WndNum]->pMdiTextEdit->buffer;
     113    ptrdiff_t LineStartPos = FindLineStartPos(pBufStart, SelRange.cpMin);
     114
     115    ptrdiff_t LineEndPos;
     116    //行末を探す
     117    if(PCSTR pEnd = cmbschr(pBufStart+SelRange.cpMax,'\r')){
     118        LineEndPos = pEnd-pBufStart;
     119    }
     120    else{
     121        LineEndPos = static_cast<ptrdiff_t>(strlen(pBufStart));
     122    }
     123    ptrdiff_t SelStrLen = LineEndPos-LineStartPos; //選択部分の長さ(選択範囲がなければそのまま0で良い)
     124    LRESULT lr = sizeof (RECONVERTSTRING)+SelStrLen+1;
     125    if(prcs){
     126        //必要な情報の設定
     127        //1行分の文字列と変換部分のオフセットを渡すようにしている
     128        PSTR pszBuf = reinterpret_cast<LPSTR>(&prcs[1]);
     129        memcpy(pszBuf, pBufStart+LineStartPos, static_cast<size_t>(SelStrLen));
     130        pszBuf[SelStrLen] = '\0';
     131
     132        DWORD StrLen = SelRange.cpMax-SelRange.cpMin;
     133        DWORD StrOffset = SelRange.cpMin-LineStartPos;
     134        prcs->dwStrLen = SelStrLen;
     135        prcs->dwStrOffset = sizeof(*prcs);
     136        prcs->dwCompStrLen = StrLen;
     137        prcs->dwCompStrOffset = StrOffset;
     138        prcs->dwTargetStrLen = StrLen;
     139        prcs->dwTargetStrOffset = StrOffset;
     140    }
     141    return lr;
     142}
     143
     144BOOL TextEditEvent_IME_ConfirmRecomvertString(HWND hwnd, RECONVERTSTRING* prcs){
     145    int WndNum = GetWndNum(GetParent(hwnd));
     146    CHARRANGE SelRange;
     147    TextEdit_GetSel(WndNum, &SelRange);
     148    //選択範囲(キャレット)を含む行を探す(その行全体を返すため)
     149    PCSTR pBufStart = MdiInfo[WndNum]->pMdiTextEdit->buffer;
     150    ptrdiff_t LineStartPos = FindLineStartPos(pBufStart, SelRange.cpMin);
     151
     152    //再変換部分が通知されるので、そこを選択状態にする。
     153    int ReconvStartPos = static_cast<int>(LineStartPos+prcs->dwCompStrOffset);
     154    TextEdit_SetSel(WndNum, ReconvStartPos, ReconvStartPos+static_cast<int>(prcs->dwCompStrLen));
     155    //候補ウィンドウの位置の設定
     156    if (HIMC himc = ImmGetContext(hwnd)){
     157        SetNextCompositionWindowPos(himc, WndNum);
     158        ImmReleaseContext(hwnd, himc);
     159    }
     160    return TRUE;
     161}
Note: See TracChangeset for help on using the changeset viewer.