source: dev/trunk/ab5.0/abdev/abdev/TextEditor_ImeEvent.cpp

Last change on this file was 829, checked in by イグトランス (egtra), 11 years ago

svn:eol-styleとsvn:mime-type(文字コード指定含む)の設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/plain; charset=Shift_JIS
File size: 4.6 KB
Line 
1#include "stdafx.h"
2
3#include "common.h"
4
5extern HFONT hFont_TextEdit,hFont_HyperLink_TextEdit;
6extern int font_width,font_height;
7
8void TextEditEvent_IME_StartComposition(HWND hwnd){
9    int WndNum;
10    WndNum=GetWndNum(GetParent(hwnd));
11
12    int iControlTabSpace;
13    iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace;
14
15    HIMC hIMC;
16    hIMC=ImmGetContext(hwnd);
17
18    //コンポジションをセット
19    POINT pos;
20    COMPOSITIONFORM CompForm;
21    CompForm.dwStyle=CFS_POINT;
22    pos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
23    GetScrollBaseCaretPos(MdiInfo[WndNum],(int *)&pos.x,(int *)&pos.y);
24    CompForm.ptCurrentPos.x=pos.x*font_width+iControlTabSpace;
25    CompForm.ptCurrentPos.y=pos.y*font_height;
26    ImmSetCompositionWindow(hIMC, &CompForm);
27
28    //フォントをセット
29    ImmSetCompositionFont(hIMC,&pobj_nv->lf);
30
31    ImmReleaseContext(hwnd,hIMC);
32}
33
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
49BOOL TextEditEvent_IME_Composition(HWND hwnd,LPARAM lParam){
50    if(lParam&GCS_RESULTSTR){
51        int WndNum;
52        WndNum=GetWndNum(GetParent(hwnd));
53
54        ////////////////////
55        // 確定文字列を取得
56        ////////////////////
57
58        //コンテキストを取得
59        HIMC hIMC;
60        hIMC=ImmGetContext(hwnd);
61
62        int i;
63        char temporary[4096];
64        i=ImmGetCompositionString(hIMC, GCS_RESULTSTR, temporary,4096);
65        if(i==0) return 0;
66        temporary[i]=0;
67
68        //バッファをリプレイス
69        TextEdit_ReplaceUpdateUndoData(WndNum,temporary,0,1);
70        UpdateWindow(hwnd);
71
72        //コンポジションをセット(立て続けにIME入力が行われる場合を考慮)
73        SetNextCompositionWindowPos(hIMC, WndNum);
74
75        //コンテキストを解放
76        ImmReleaseContext(hwnd,hIMC);
77
78        return 0; //DefWindowProcへ渡さないようTextEditProcへ指示
79    }
80
81    return 1;
82}
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 TracBrowser for help on using the repository browser.