°¡. ij·µ ó¸®

¾Õ¿¡¼­ ¸¸µé¾ú´ø Ime1 ¿¹Á¦´Â ÇѱÛÀ» Àß ÀԷ¹ޱâ´Â ÇÏÁö¸¸ ¹«Á¶°Ç ÀԷ¸¸ ¹ÞÀ» ¼ö ÀÖÀ» »Ó À§Ä¡¸¦ ¿Å±ä´Ù°Å³ª »ðÀÔ, »èÁ¦°¡ ºÒ°¡´ÉÇÏ´Ù. ´Ù¸¸ Á¶¸³ÁßÀÎ Çѱۿ¡ ´ëÇؼ­¸¸ <BS>Å°·Î À½¼Ò¸¦ »èÁ¦ÇÒ ¼ö Àִµ¥ ÀÌ°ÍÀº Ime1ÀÌ Ã³¸®ÇÏ´Â °ÍÀÌ ¾Æ´Ï¶ó µðÆúÆ® IME°¡ <BS>Å°¸¦ Ưº°È÷ Ãë±ÞÇϱ⠶§¹®ÀÌ´Ù. ÀÌ ¿¹Á¦¸¦ È®ÀåÇÏ¿© ¹®ÀåÀ» ÀÚÀ¯·Ó°Ô ÆíÁýÇÒ ¼ö ÀÖ´Â ¿¡µðÆ® ÄÁÆ®·ÑÀ» ¸¸µé¾î º¸ÀÚ.

ÆíÁý À§Ä¡¸¦ ¿Å±â°í ¿øÇÏ´Â À§Ä¡ÀÇ ¹®ÀÚ¸¦ »èÁ¦Çϰųª ¶Ç´Â »ðÀÔÇÏ·Á¸é ¸ÕÀú ÇöÀç À§Ä¡°¡ ¾îµðÀÎÁö¸¦ º¸¿©ÁÙ ¹æ¹ýÀÌ ÀÖ¾î¾ß ÇÑ´Ù. À©µµ¿ìÁî¿¡¼­´Â ÀÌ·± ¿ëµµ·Î ij·µÀ̶ó´Â ÁÁÀº ÀåÄ¡¸¦ Á¦°øÇϹǷΠij·µÀ» ´Þ¾Æ º¸µµ·Ï ÇÏÀÚ. ´ÙÀ½ ´Ü°è¸¦ µû¶ó ¿¹Á¦ÀÇ Äڵ带 Á¶±Ý¾¿ ¼öÁ¤ÇÑ´Ù.

 

 ¸ÕÀú ÇÁ·ÎÁ§Æ®¸¦ ¸¸µç´Ù. Ime1 ÇÁ·ÎÁ§Æ®¸¦ º¹»çÇÏ¿© Ime2 ÇÁ·ÎÁ§Æ®¸¦ ¸¸µé±â¸¸ ÇÏ¸é µÈ´Ù. ±×´ë·Î »çº»À» ¶¹À¸¹Ç·Î imm32.lib¸¦ ´Ù½Ã ¿¬°áÇϰųª ÇÒ ÇÊ¿ä´Â ¾ø´Ù. Ime2 ¿¹Á¦¸¦ ¸¸µç ÈÄ À©µµ¿ì Ŭ·¡½º À̸§¸¸ ´ÙÀ½°ú °°ÀÌ º¯°æÇÑ´Ù.

 

LPCTSTR lpszClass=TEXT("Ime2");

 

ÀüüÀûÀÎ ¿Ï¼º ÄÚµå´Â º¸ÀÌÁö ¾Ê°í ½Ç½À °úÁ¤À» º¸À̹ǷΠ¹Ýµå½Ã ÇÁ·ÎÁ§Æ®¸¦ ¸¸µç ÈÄ ½Ç½ÀÇغ¸±â ¹Ù¶õ´Ù. ±×·¡¾ß ¾î¶² Äڵ忡 ÀÇÇØ ¾î¶² ±â´ÉÀÌ Ãß°¡µÇ´ÂÁö »ìÆì º¸°í ¶ÇÇÑ ¹®Á¦Á¡µéÀ» Á÷Á¢ È®ÀÎÇϸ鼭 Ç®¾î³ª°¥ ¼ö ÀÖ´Ù.

 Ä³·µÀº ÇöÀç ÆíÁýÁßÀÎ À§Ä¡°¡ ¾îµðÀΰ¡¸¦ º¸¿©ÁÖ´Â °ÍÀÌ¸ç ¹®ÀÚÀÇ »ðÀÔ, »èÁ¦ µ¿ÀÛÀº Ç×»ó ÇöÀç ij·µ À§Ä¡¿¡¼­ ÀϾ´Ù. ÇöÀç À§Ä¡°¡ ¾îµðÀΰ¡´Â °ð ¹®¼­ ¹öÆÛÀÎ buf¿¡¼­ÀÇ ¿ÀÇÁ¼ÂÀ¸·Î Ç¥ÇöµÇ´Âµ¥ ÀÌ À§Ä¡¸¦ ±â¾ïÇϱâ À§ÇØ off Àü¿ªº¯¼ö¸¦ Ãß°¡ÇÏ¿´´Ù.

 

#include <imm.h>

TCHAR *buf;

BOOL bComp;

int off;

int FontHeight;

 

ij·µÀÇ ³ôÀÌ´Â ÇöÀç ¼±ÅÃµÈ ÆùÆ®ÀÇ ³ôÀÌ°¡ µÇ´Âµ¥ ÀÌ °ªÀ» ±â¾ïÇϱâ À§ÇØ FontHeight¶ó´Â Àü¿ªº¯¼öµµ Ãß°¡ÇÏ¿´´Ù. ÀÌ µÎ º¯¼ö´Â WM_CREATE¿¡¼­ ÃʱâÈ­µÇ´Âµ¥ offÀÇ ÃʱⰪÀº 0ÀÌ°í FontHeightÀÇ ÃʱⰪÀº ÆùÆ® ¸ÞÆ®¸¯½º·Î Á¶»çÇÑ ÆùÆ® ³ôÀÌÀÌ´Ù.

 

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

{

    TEXTMETRIC tm;

     ...

     switch(iMessage) {

     case WM_CREATE:

          bComp=FALSE;

          buf=(char *)malloc(65536);

          memset(buf,0,65536);

        hWndMain=hWnd;

        off=0;

        hdc=GetDC(hWnd);

        GetTextMetrics(hdc,&tm);

        FontHeight=tm.tmHeight;

        ReleaseDC(hWnd,hdc);

          return 0;

 

¸ÞÀÎ À©µµ¿ìÀÇ ÇÚµéÀÎ hWndMainµµ ¹Ì¸® ±¸Çسõ¾Ò´Ù. Åë»ó WinMain¿¡¼­ ¸ÞÀÎ À©µµ¿ì »ý¼º ÈÄ ÀÌ Àü¿ªº¯¼ö°ªÀ» ´ëÀÔÇϴµ¥ ÀÌ ¿¹Á¦ÀÇ °æ¿ì À©µµ¿ì°¡ »ý¼ºµÉ ¶§ º¸³»Áö´Â WM_SETFOCUS¿¡¼­ ÀÌ ÇÚµéÀ» ÂüÁ¶ÇϹǷΠ¹Ì¸® ´ëÀԵǾî ÀÖ¾î¾ß ÇÑ´Ù.

 Ä³·µÀÇ À§Ä¡´Â ¹®¼­ÆíÁýÁß¿¡ ¼ö½Ã·Î º¯°æµÇ¾î¾ß ÇÑ´Ù. ±×·¡¼­ WndProc¿¡¼­ ij·µÀÇ À§Ä¡¸¦ ÀÏÀÏÀÌ ¿Å°ÜÁÖ´Â °Íº¸´Ù´Â ij·µÀÇ ¸ð¾ç°ú À§Ä¡¸¦ º¯°æÇÏ´Â SetCaret ÀϹÝÇÔ¼ö¸¦ ¸¸µé°í ÇÊ¿äÇÒ ¶§ ÀÌ ÇÔ¼ö¸¦ È£ÃâÇϵµ·Ï ÇÏ¿´´Ù. ´ÙÀ½ µÎ ÇÔ¼ö¸¦ WndProc ÀÌÀü¿¡ ÀÔ·ÂÇÑ´Ù.

 

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);

}

 

GetCharWidth ÇÔ¼ö´Â ch ¹øÁö¿¡ ÀÖ´Â ±æÀÌ len ¹®ÀÚÀÇ ÆøÀ» ±¸Çϴµ¥ °¡º¯Æø ±Û²ÃÀÇ °æ¿ì °¢ ¹®ÀÚ¸¶´Ù ÆøÀÌ ´Þ¶óÁú ¼ö ÀÖÀ¸¹Ç·Î ij·µµµ ÇöÀç À§Ä¡ÀÇ ¹®ÀÚÆø¿¡ ¸Â°Ô ´Þ¶óÁ®¾ß ÇÑ´Ù. ¹®ÀÚ¿­ÀÇ ±æÀ̸¦ °è»êÇÒ ¶§´Â GetTextExtentPoint32 ÇÔ¼ö°¡ »ç¿ëµÈ´Ù. ±Û²ÃÀº ¹®ÀÚ¸¶´Ù ÆøÀÌ ´Ù¸£Áö¸¸ ³ôÀÌ´Â ÀÏÁ¤ÇϹǷΠ³ôÀÌ´Â µû·Î ±¸ÇÏÁö ¾ÊÀ¸¸ç WM_CREATE¿¡¼­ µü ÇÑ ¹ø¸¸ Á¶»çÇÏ¿© FontHeight Àü¿ªº¯¼ö¿¡ ´ëÀÔÇصξú´Ù.

SetCaret ÇÔ¼ö´Â ÇöÀç »óÅ¿¡ µû¶ó ij·µÀÇ ¸ð¾ç°ú À§Ä¡¸¦ °áÁ¤ÇÑ´Ù. ij·µÀÇ ¸ð¾çÀº ÇѱÛÀ» ÀÔ·ÂÁßÀÏ ¶§ »ç°¢Çü ¸ð¾çÀÌ µÇ¸ç ±× ¿ÜÀÇ °æ¿ì´Â 2Çȼ¿ µÎ²²¸¦ °¡Áö´Âµ¥ ¸Þ¸ðÀåÀ» º¸¸é ÀÌ·¸°Ô µÇ¾î ÀÖ´Ù. ÇÑ±Û ÀÔ·ÂÁßÀΰ¡ ¾Æ´Ñ°¡´Â bComp º¯¼ö¸¦ ÂüÁ¶ÇÏ¸é ½±°Ô ¾Ë ¼ö ÀÖÀ¸¸ç ÀÌ º¯¼ö°ª¿¡ µû¶ó ij·µÀÇ Æø°ú ³ôÀ̸¦ °áÁ¤ÇÑ´Ù. ij·µÀÇ ³ôÀÌ´Â Ç×»ó ÆùÆ®ÀÇ ³ôÀÌ¿Í °°À¸¸ç ÆøÀº 2Çȼ¿ ¶Ç´Â ÇöÀç À§Ä¡¿¡ ÀÖ´Â ¹®ÀÚÀÇ Æø°ú °°´Ù. ij·µÀÇ ¸ð¾çÀÌ °áÁ¤µÇ¸é CreateCaret ÇÔ¼ö·Î ij·µÀ» ¸¸µç´Ù. ÀÌ ÇÔ¼ö´Â ±âÁ¸¿¡ ¸¸µé¾îÁ® Àִ ij·µÀ» Æı«ÇÑ ÈÄ »õ ij·µÀ» ¸¸µêÀ¸·Î ÀϺη¯ DestroyCaretÀ» È£ÃâÇÒ ÇÊ¿ä´Â ¾ø´Ù.

 

ij·µÀÇ À§Ä¡´Â off º¯¼ö°¡ °¡¸®Å°´Â ÇöÀç À§Ä¡±îÁöÀÇ ¹®ÀÚ¿­ ÆøÀ» ±¸ÇÏ¸é µÈ´Ù. ´Ü, ÇÑ±Û ÀÔ·ÂÁßÀÏ ¶§´Â ÇöÀç À§Ä¡º¸´Ù µÎ Ä­ ´õ ¾ÕÀ¸·Î À̵¿ÇÑ À§Ä¡¿¡ ij·µÀ» ³õ¾Æ¾ß ÇÑ´Ù. ±×·¡¾ß ÀÔ·ÂÁßÀÎ ÇÑ±Û À½ÀýÀÌ Ä³·µÀ¸·Î °¨½ÎÁø´Ù.

 Ä³·µÀº ½Ã½ºÅÛ¿¡ Àü¿ªÀûÀ¸·Î Çϳª¹Û¿¡ ¾ø´Â ÀÚ¿øÀ̹ǷΠÆ÷Ä¿½º¸¦ ¹Þ¾ÒÀ» ¶§¸¸ »ý¼ºÇÏ°í ±×·¸Áö ¾ÊÀ» °æ¿ì´Â Æı«ÇØ¾ß ÇÑ´Ù. ´ÙÀ½ µÎ ¸Þ½ÃÁö¸¦ ó¸®ÇÏ¸é µÈ´Ù.

 

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

{

     ....

     case WM_SETFOCUS:

          SetCaret();

          return 0;

     case WM_KILLFOCUS:

          DestroyCaret();

          return 0;

 

Æ÷Ä¿½º¸¦ ¹Þ¾ÒÀ» ¶§ SetCaret ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ij·µÀ» ÇöÀç À§Ä¡¿¡ Àû´çÇÑ ¸ð¾çÀ¸·Î º¸À̵µ·Ï ÇÏ¿´À¸¸ç Æ÷Ä¿½º¸¦ ÀÒ¾úÀ» ¶§ DestroyCaretÀ¸·Î ij·µÀ» Æı«ÇÏ¿´´Ù.

 Ä³·µÀÇ ¸ð¾ç°ú À§Ä¡¸¦ º¯°æÇÏ´Â ÇÔ¼ö°¡ Á¦´ë·Î µ¿ÀÛÇϱâ À§Çؼ­´Â ¹®ÀÚ°¡ ÀÔ·ÂµÉ ¶§ off º¯¼ö°¡ ÇöÀç À§Ä¡¸¦ Á¤È®ÇÏ°Ô °¡¸®Å°µµ·Ï °ü¸®ÇØ¾ß ÇÑ´Ù. ¿µ¹®ÀÚ°¡ ÀÔ·ÂµÉ ¶§ÀÎ WM_CHAR ¸Þ½ÃÁö¿¡ ´ÙÀ½ Äڵ带 Ãß°¡ÇÑ´Ù.

 

     case WM_CHAR:

          szChar[0]=(BYTE)wParam;

          szChar[1]=0;

          for (i=0;i<LOWORD(lParam);i++) {

               lstrcat(buf,szChar);

            off+=lstrlen(szChar);

          }

          bComp=FALSE;

          InvalidateRect(hWnd,NULL,TRUE);

        SetCaret();

          return 0;

 

ÀÔ·ÂµÈ ¹®ÀÚ ±æÀ̸¸Å­ off¸¦ Áõ°¡½ÃÅ°°í »õ off °ªÀ¸·Î ij·µ À§Ä¡¸¦ °»½ÅÇϱâ À§ÇØ SetCaret ÇÔ¼ö¸¦ È£ÃâÇÏ¿´´Ù. ´ÙÀ½Àº ÇѱÛÀÌ Á¶¸³µÉ ¶§ ij·µÀÇ À§Ä¡¸¦ ¿Å°Üº¸ÀÚ.

 

     case WM_IME_COMPOSITION:

          if (lParam & GCS_COMPSTR) {

               hImc=ImmGetContext(hWnd);

               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;

                   buf[lstrlen(buf)-2]=0;

               }

               if (len == 0) {

                   bComp=FALSE;

               } else {

                   bComp=TRUE;

               }

               lstrcat(buf,szComp);

            off+=len;

               ImmReleaseContext(hWnd,hImc);

               free(szComp);

               InvalidateRect(hWnd,NULL,TRUE);

            SetCaret();

          }

          break;

     case WM_IME_CHAR:

          if (IsDBCSLeadByte((BYTE)(wParam >> 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;

               buf[lstrlen(buf)-2]=0;

          }

          lstrcat(buf,szChar);

        off+=lstrlen(szChar);

          bComp=FALSE;

          InvalidateRect(hWnd,NULL,TRUE);

        SetCaret();

 

ÇÑ À½ÀýÀÌ ÀÔ·ÂµÈ ÈÄ off¸¦ len¸¸Å­ Áõ°¡½ÃÅ°µµ·Ï ÇÏ¿´´Ù. ´Ü, Á¶¸³ÁßÀÎ ¹®ÀÚ¸¦ »èÁ¦ÇÒ ¶§´Â ¿ÀÈ÷·Á off¸¦ 2 °¨¼Ò½ÃÄÑ¾ß ÇÑ´Ù. ±×·¡¼­ ÇѱÛÀÌ Á¶¸³µÉ ¶§´Â off°¡ 2 °¨¼ÒÇß´Ù°¡ ´Ù½Ã 2 Áõ°¡ÇϹǷΠij·µÀÌ ±× ÀÚ¸®¿¡ ¸Ó¹°·¯ ÀÖ°Ô µÇ¸ç À½ÀýÀÌ ¿Ï¼ºµÇ¸é ÇÑ Ä­ ¿À¸¥ÂÊÀ¸·Î À̵¿ÇÑ´Ù. ¿©±â±îÁö Äڵ带 ÄÄÆÄÀÏÇÑ ÈÄ ¿¹Á¦¸¦ ½ÇÇàÇغ¸ÀÚ.

½ÇÇàÇغ¸¸é ¹®ÀÚ¸¦ ÀÔ·ÂÇÒ ¶§ ÇöÀç À§Ä¡¿¡ ij·µÀÌ ³ªÅ¸³¯ °ÍÀÌ¸ç °¡¸¸È÷ ÀÖÀ» ¶§´Â ij·µÀÌ È¥ÀÚ ±ô¹Ú°Å¸®°í ÀÖÀ» °ÍÀÌ´Ù. ±â´É»ó ´õ ³ª¾ÆÁø °ÍÀº ¾øÁö¸¸ ij·µÀÌ º¸ÀÌ´Ï ¹®ÀÚ°¡ »ðÀ﵃ À§Ä¡¸¦ È®½ÇÇÏ°Ô º¸¿©ÁÙ ¼ö ÀÖÀ¸¸ç Á» ¸ÚÀÖ¾î º¸À̱⵵ ÇÑ´Ù.