Index: trunk/ab5.0/abdev/abdev/TextEditor_ImeEvent.cpp
===================================================================
--- trunk/ab5.0/abdev/abdev/TextEditor_ImeEvent.cpp	(revision 655)
+++ trunk/ab5.0/abdev/abdev/TextEditor_ImeEvent.cpp	(revision 691)
@@ -32,11 +32,23 @@
 }
 
+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));
-
-		int iControlTabSpace;
-		iControlTabSpace=MdiInfo[WndNum]->pMdiTextEdit->iWidth_ControlTabSpace;
 
 		////////////////////
@@ -59,17 +71,91 @@
 
 		//コンポジションをセット（立て続けにIME入力が行われる場合を考慮）
-		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);
+		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<PCSTR>(_mbschr(reinterpret_cast<UCHAR const*>(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<ptrdiff_t>(strlen(pBufStart));
+	}
+	ptrdiff_t SelStrLen = LineEndPos-LineStartPos; //選択部分の長さ（選択範囲がなければそのまま0で良い）
+	LRESULT lr = sizeof (RECONVERTSTRING)+SelStrLen+1;
+	if(prcs){
+		//必要な情報の設定
+		//1行分の文字列と変換部分のオフセットを渡すようにしている
+		PSTR pszBuf = reinterpret_cast<LPSTR>(&prcs[1]);
+		memcpy(pszBuf, pBufStart+LineStartPos, static_cast<size_t>(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<int>(LineStartPos+prcs->dwCompStrOffset);
+	TextEdit_SetSel(WndNum, ReconvStartPos, ReconvStartPos+static_cast<int>(prcs->dwCompStrLen));
+	//候補ウィンドウの位置の設定
+	if (HIMC himc = ImmGetContext(hwnd)){
+		SetNextCompositionWindowPos(himc, WndNum);
+		ImmReleaseContext(hwnd, himc);
+	}
+	return TRUE;
+}
