#include <imm.h>
#pragma comment(lib, "imm32")
int GetCharWidth(HDC hdc, TCHAR *ch, int len)
{
SIZE sz;
GetTextExtentPoint32(hdc, ch, len, &sz);
return sz.cx;
}
static BOOL bComp;
static TCHAR *buf;
static int off;
static int FontHeight;
void SetCaret(HWND hWnd)
{
SIZE sz;
HDC hdc;
int toff;
int caretwidth;
hdc=GetDC(hWnd);
if (bComp) {
toff=off-2;
caretwidth=GetCharWidth(hdc,buf+toff,2);
} else {
toff=off;
caretwidth=2;
}
GetTextExtentPoint32(hdc,buf,toff,&sz);
ReleaseDC(hWnd,hdc);
CreateCaret(hWnd,NULL,caretwidth,FontHeight);
ShowCaret(hWnd);
SetCaretPos(sz.cx,0);
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
switch (iMessage) {
case WM_CREATE: {
HDC hdc;
TEXTMETRIC tm;
bComp=FALSE;
buf=(TCHAR *)malloc(65536);
memset(buf,0,65536);
off=0;
hdc=GetDC(hWnd);
GetTextMetrics(hdc,&tm);
FontHeight=tm.tmHeight;
ReleaseDC(hWnd,hdc);
}
return 0;
case WM_DESTROY:
PostQuitMessage(0);
free(buf);
return 0;
case WM_SETFOCUS:
SetCaret(hWnd);
return 0;
case WM_KILLFOCUS:
DestroyCaret();
return 0;
case WM_IME_COMPOSITION: {
if (lParam & GCS_COMPSTR) {
TCHAR szChar[3];
szChar[0]=HIBYTE(LOWORD(wParam));
szChar[1]=LOBYTE(LOWORD(wParam));
szChar[2]=0;
if (bComp) {
off-=2;
buf[lstrlen(buf)-2]=0;
}
if (lstrlen(szChar) == 0) {
bComp=FALSE;
} else {
bComp=TRUE;
}
lstrcat(buf,szChar);
off+=lstrlen(szChar);
}
if (lParam & GCS_RESULTSTR) {
HIMC hImc;
int len;
TCHAR *szComp;
hImc=ImmGetContext(hWnd);
len=ImmGetCompositionString(hImc,GCS_RESULTSTR,NULL,0);
szComp=(TCHAR *)malloc(len+1);
ImmGetCompositionString(hImc,GCS_RESULTSTR,szComp,len);
szComp[len]=0;
ImmReleaseContext(hWnd,hImc);
if (bComp) {
off-=2;
buf[lstrlen(buf)-2]=0;
}
lstrcat(buf,szComp);
off+=lstrlen(szComp);
free(szComp);
bComp=FALSE;
}
InvalidateRect(hWnd,NULL,TRUE);
SetCaret(hWnd);
}
if (lParam & GCS_COMPSTR) {
break;
} else {
return 0;
}
case WM_CHAR: {
TCHAR szChar[3];
int i;
/* int len;
if (wParam == 8) // BS는 KEYDOWN에서 처리
return 0;
*/
szChar[0]=(BYTE)wParam;
szChar[1]=0;
for (i=0;i<LOWORD(lParam);i++) {
lstrcat(buf,szChar);
off+=lstrlen(szChar);
}
bComp=FALSE;
/*
// 오프셋 위치에 문자를 삽입한다.
len=lstrlen(str);
for (i=len+1;i>=off;i--)
str[i]=str[i-1];
str[off++]=wParam;
*/
InvalidateRect(hWnd,NULL,TRUE);
SetCaret(hWnd);
}
return 0;
/*
case WM_KEYDOWN: {
int len,i;
switch (wParam) {
case VK_LEFT:
if (off > 0) {
off--;
MySetCaretPos();
}
break;
case VK_RIGHT:
if (off < (int)lstrlen(str)) {
off++;
MySetCaretPos();
}
break;
case VK_HOME:
off=0;
MySetCaretPos();
break;
case VK_END:
off=lstrlen(str);
MySetCaretPos();
break;
case VK_BACK: // 한칸 뒤로 간 후 Delete
if (off > 0) {
off--;
SendMessage(hWnd,WM_KEYDOWN,VK_DELETE,0);
MySetCaretPos();
}
break;
case VK_DELETE:
len=lstrlen(str);
for (i=off;i<len;i++) {
str[i]=str[i+1];
}
InvalidateRect(hWnd,NULL,TRUE);
break;
}
}
return 0;
*/
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc;
hdc=BeginPaint(hWnd, &ps);
TextOut(hdc,0,0,buf,lstrlen(buf));
// TextOut(hdc,0,0,str,lstrlen(str));
EndPaint(hWnd, &ps);
}
return 0;
}
return(DefWindowProc(hWnd,iMessage,wParam,lParam));
}