#include #include #include #include LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM); HINSTANCE g_hInst; HWND hWndMain; LPCTSTR lpszClass=TEXT("Ime4"); // Àü¿ª º¯¼ö TCHAR *buf; BOOL bComp; int off; int FontHeight; // ÇÔ¼ö ¿øÇü BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct); void OnChar(HWND hWnd, TCHAR ch, int cRepeat); void OnKey(HWND hWnd, UINT vk, BOOL fDown, int cRepeat, UINT flags); void OnPaint(HWND hWnd); void OnSetFocus(HWND hWnd, HWND hwndOldFocus); void OnKillFocus(HWND hWnd, HWND hwndNewFocus); void OnDestroy(HWND hWnd); LRESULT OnImeComposition(HWND hWnd, WPARAM wParam, LPARAM lParam); LRESULT OnImeChar(HWND hWnd, WPARAM wParam, LPARAM lParam); void OnLButtonDown(HWND hWnd, BOOL fDoubleClick, int x, int y, UINT keyFlags); void OnMouseMove(HWND hWnd, int x, int y, UINT keyFlags); void OnLButtonUp(HWND hWnd, int x, int y, UINT keyFlags); void OnTimer(HWND hWnd, UINT id); void OnSize(HWND hWnd, UINT state, int cx, int cy); void OnHScroll(HWND hWnd, HWND hwndCtl, UINT code, int pos); void OnVScroll(HWND hWnd, HWND hwndCtl, UINT code, int pos); void OnContextMenu(HWND hWnd, HWND hwndContext, UINT xPos, UINT yPos); void OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify); BOOL OnSetCursor(HWND hWnd, HWND hwndCursor, UINT codeHitTest, UINT msg); UINT OnGetDlgCode(HWND hWnd, LPMSG lpmsg); int GetCharWidth(HDC hdc, TCHAR *ch, int len); void SetCaret(); inline BOOL IsDBCS(int nPos); int GetPrevOff(int nPos); int GetNextOff(int nPos); void Insert(int nPos, TCHAR *str); void Delete(int nPos, int nCount); int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance ,LPSTR lpszCmdParam,int nCmdShow) { HWND hWnd; MSG Message; WNDCLASS WndClass; g_hInst=hInstance; WndClass.cbClsExtra=0; WndClass.cbWndExtra=0; WndClass.hbrBackground=(HBRUSH)(COLOR_WINDOW+1); WndClass.hCursor=LoadCursor(NULL,IDC_IBEAM); WndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION); WndClass.hInstance=hInstance; WndClass.lpfnWndProc=(WNDPROC)WndProc; WndClass.lpszClassName=lpszClass; WndClass.lpszMenuName=NULL; WndClass.style=CS_HREDRAW | CS_VREDRAW; RegisterClass(&WndClass); hWnd=CreateWindow(lpszClass,lpszClass,WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT, NULL,(HMENU)NULL,hInstance,NULL); ShowWindow(hWnd,nCmdShow); while(GetMessage(&Message,0,0,0)) { TranslateMessage(&Message); DispatchMessage(&Message); } return (int)Message.wParam; } LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam) { switch(iMessage) { HANDLE_MSG(hWnd, WM_CREATE, OnCreate); HANDLE_MSG(hWnd, WM_DESTROY, OnDestroy); HANDLE_MSG(hWnd, WM_CHAR, OnChar); HANDLE_MSG(hWnd, WM_KEYDOWN, OnKey); HANDLE_MSG(hWnd, WM_KEYUP, OnKey); HANDLE_MSG(hWnd, WM_PAINT, OnPaint); HANDLE_MSG(hWnd, WM_SETFOCUS, OnSetFocus); HANDLE_MSG(hWnd, WM_KILLFOCUS, OnKillFocus); HANDLE_MSG(hWnd, WM_LBUTTONDOWN, OnLButtonDown); HANDLE_MSG(hWnd, WM_LBUTTONDBLCLK, OnLButtonDown); HANDLE_MSG(hWnd, WM_MOUSEMOVE, OnMouseMove); HANDLE_MSG(hWnd, WM_LBUTTONUP, OnLButtonUp); HANDLE_MSG(hWnd, WM_TIMER, OnTimer); HANDLE_MSG(hWnd, WM_SIZE, OnSize); HANDLE_MSG(hWnd, WM_HSCROLL, OnHScroll); HANDLE_MSG(hWnd, WM_VSCROLL, OnVScroll); HANDLE_MSG(hWnd, WM_CONTEXTMENU, OnContextMenu); HANDLE_MSG(hWnd, WM_COMMAND, OnCommand); HANDLE_MSG(hWnd, WM_SETCURSOR, OnSetCursor); HANDLE_MSG(hWnd, WM_GETDLGCODE, OnGetDlgCode); case WM_IME_COMPOSITION: return OnImeComposition(hWnd, wParam, lParam); case WM_IME_CHAR: return OnImeChar(hWnd, wParam, lParam); case WM_IME_STARTCOMPOSITION: return 0; } return(DefWindowProc(hWnd,iMessage,wParam,lParam)); } /////////////////////////////////////////////////////////////////////////////////// // ¸Þ½ÃÁö Çڵ鷯 BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct) { HDC hdc; TEXTMETRIC tm; bComp=FALSE; buf=(TCHAR *)malloc(65536); memset(buf,0,65536); hWndMain=hWnd; off=0; hdc=GetDC(hWnd); GetTextMetrics(hdc,&tm); FontHeight=tm.tmHeight; ReleaseDC(hWnd,hdc); return TRUE; } void OnDestroy(HWND hWnd) { PostQuitMessage(0); free(buf); } void OnSize(HWND hWnd, UINT state, int cx, int cy) { } void OnKey(HWND hWnd, UINT vk, BOOL fDown, int cRepeat, UINT flags) { if (fDown==FALSE) return; switch (vk) { case VK_LEFT: if (off > 0) { off=GetPrevOff(off); SetCaret(); } return; case VK_RIGHT: if (off < (int)strlen(buf)) { off=GetNextOff(off); SetCaret(); } return; case VK_HOME: off=0; SetCaret(); return; case VK_END: off=lstrlen(buf); SetCaret(); return; case VK_DELETE: if (IsDBCS(off)) { Delete(off, 2); } else { Delete(off, 1); } InvalidateRect(hWnd,NULL,TRUE); return; case VK_BACK: if (off == 0) return; off=GetPrevOff(off); SendMessage(hWnd,WM_KEYDOWN,VK_DELETE,0); SetCaret(); return; } } void OnPaint(HWND hWnd) { HDC hdc; PAINTSTRUCT ps; hdc=BeginPaint(hWnd,&ps); TextOut(hdc,0,0,buf,lstrlen(buf)); //MessageBox(hWnd, buf, "Test", MB_OK); EndPaint(hWnd,&ps); } void OnSetFocus(HWND hWnd, HWND hwndOldFocus) { SetCaret(); } void OnKillFocus(HWND hWnd, HWND hwndNewFocus) { DestroyCaret(); } void OnChar(HWND hWnd, TCHAR ch, int cRepeat) { TCHAR szChar[3]; int i; if (ch == 8) return; szChar[0]=ch; szChar[1]=0; for (i=0;i> 8))) { szChar[0]=HIBYTE(LOWORD(wParam)); szChar[1]=LOBYTE(LOWORD(wParam)); szChar[2]=0; } else { szChar[0]=(BYTE)wParam; szChar[1]=0; } if (bComp) { off-=2; Delete(off,2); } Insert(off,szChar); off+=lstrlen(szChar); bComp=FALSE; InvalidateRect(hWnd,NULL,TRUE); SetCaret(); return 0; } LRESULT OnImeComposition(HWND hWnd, WPARAM wParam, LPARAM lParam) { HIMC hImc; TCHAR *szComp; int len; hImc=ImmGetContext(hWnd); if (lParam & GCS_COMPSTR) { len=ImmGetCompositionString(hImc,GCS_COMPSTR,NULL,0); szComp=(TCHAR *)malloc(len+1); ImmGetCompositionString(hImc,GCS_COMPSTR,szComp,len); szComp[len]=0; if (bComp) { off-=2; Delete(off,2); } if (len == 0) { bComp=FALSE; } else { bComp=TRUE; } Insert(off,szComp); off+=len; ImmReleaseContext(hWnd,hImc); free(szComp); InvalidateRect(hWnd,NULL,TRUE); SetCaret(); } return DefWindowProc(hWnd,WM_IME_COMPOSITION,wParam,lParam); } void OnHScroll(HWND hWnd, HWND hwndCtl, UINT code, int pos) { } void OnVScroll(HWND hWnd, HWND hwndCtl, UINT code, int pos) { } void OnContextMenu(HWND hWnd, HWND hwndContext, UINT xPos, UINT yPos) { } void OnCommand(HWND hWnd, int id, HWND hwndCtl, UINT codeNotify) { } void OnLButtonDown(HWND hWnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) { } void OnMouseMove(HWND hWnd, int x, int y, UINT keyFlags) { } void OnLButtonUp(HWND hWnd, int x, int y, UINT keyFlags) { } void OnTimer(HWND hWnd, UINT id) { } BOOL OnSetCursor(HWND hWnd, HWND hwndCursor, UINT codeHitTest, UINT msg) { return FORWARD_WM_SETCURSOR(hWnd,hwndCursor,codeHitTest,msg,DefWindowProc); } UINT OnGetDlgCode(HWND hWnd, LPMSG lpmsg) { return 0; } /////////////////////////////////////////////////////////////////////////////////// // ÀÏ¹Ý ÇÔ¼öµé int GetCharWidth(HDC hdc, TCHAR *ch, int len) { SIZE sz; GetTextExtentPoint32(hdc, ch, len, &sz); return sz.cx; } void SetCaret() { SIZE sz; HDC hdc; int toff; int caretwidth; hdc=GetDC(hWndMain); if (bComp) { toff=off-2; caretwidth=GetCharWidth(hdc,buf+toff,2); } else { toff=off; caretwidth=2; } CreateCaret(hWndMain,NULL,caretwidth,FontHeight); ShowCaret(hWndMain); GetTextExtentPoint32(hdc,buf,toff,&sz); SetCaretPos(sz.cx,0); ReleaseDC(hWndMain,hdc); } inline BOOL IsDBCS(int nPos) { return (IsDBCSLeadByte(buf[nPos])); } int GetPrevOff(int nPos) { int n, size; if (nPos==0) { return 0; } for (n=0;;) { if (IsDBCS(n)) { size=2; } else { size=1; } n+=size; if (n >= nPos) break; } return n-size; } int GetNextOff(int nPos) { if (IsDBCS(nPos)) { return nPos+2; } else { return nPos+1; } } void Insert(int nPos, TCHAR *str) { int len; int movelen; len=lstrlen(str); if (len==0) return; movelen=lstrlen(buf+nPos)+1; memmove(buf+nPos+len,buf+nPos,movelen); memcpy(buf+nPos,str,len); } void Delete(int nPos, int nCount) { int movelen; if (nCount == 0) return; if (lstrlen(buf) < nPos+nCount) return; movelen=lstrlen(buf+nPos+nCount)+1; memmove(buf+nPos, buf+nPos+nCount, movelen); }