[475] | 1 | #include "stdafx.h"
|
---|
| 2 |
|
---|
[3] | 3 | #include "common.h"
|
---|
| 4 |
|
---|
| 5 | extern HFONT hFont_TextEdit,hFont_HyperLink_TextEdit;
|
---|
| 6 | extern int font_width,font_height;
|
---|
| 7 |
|
---|
| 8 | void TextEditEvent_IME_StartComposition(HWND hwnd){
|
---|
| 9 | int WndNum;
|
---|
| 10 | WndNum=GetWndNum(GetParent(hwnd));
|
---|
| 11 |
|
---|
| 12 | int iControlTabSpace;
|
---|
[629] | 13 | iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace;
|
---|
[3] | 14 |
|
---|
| 15 | HIMC hIMC;
|
---|
| 16 | hIMC=ImmGetContext(hwnd);
|
---|
| 17 |
|
---|
| 18 | //コンポジションをセット
|
---|
| 19 | POINT pos;
|
---|
| 20 | COMPOSITIONFORM CompForm;
|
---|
| 21 | CompForm.dwStyle=CFS_POINT;
|
---|
[629] | 22 | pos=MdiInfo[WndNum]->pMdiTextEdit->StartCaretPos;
|
---|
[655] | 23 | GetScrollBaseCaretPos(MdiInfo[WndNum],(int *)&pos.x,(int *)&pos.y);
|
---|
[3] | 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 |
|
---|
[691] | 34 | namespace
|
---|
| 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 |
|
---|
[3] | 49 | BOOL 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入力が行われる場合を考慮)
|
---|
[691] | 73 | SetNextCompositionWindowPos(hIMC, WndNum);
|
---|
[3] | 74 |
|
---|
| 75 | //コンテキストを解放
|
---|
| 76 | ImmReleaseContext(hwnd,hIMC);
|
---|
[691] | 77 |
|
---|
| 78 | return 0; //DefWindowProcへ渡さないようTextEditProcへ指示
|
---|
[3] | 79 | }
|
---|
| 80 |
|
---|
| 81 | return 1;
|
---|
| 82 | }
|
---|
[691] | 83 |
|
---|
| 84 | namespace
|
---|
| 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 |
|
---|
| 107 | LRESULT 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 |
|
---|
| 144 | BOOL 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 | }
|
---|