³ª. µ¤¾î¾²±â ¸ðµå

µ¤¾î¾²±â ¸ðµå´Â ij·µ À§Ä¡ÀÇ ¹®ÀÚ¸¦ »èÁ¦ÇÏ°í »õ·Î ÀÔ·ÂÇÑ ¹®ÀÚ¸¦ ±× À§¿¡ ´ëüÇÏ´Â ÀÔ·Â ¹æ¹ýÀÌ´Ù. º¸ÅëÀº »õ·Î ÀÔ·ÂÇÑ ¹®ÀÚ°¡ »ðÀԵǴ ¹æ½ÄÀ¸·Î ÆíÁýÀ» ÇÏ°í ¹®ÀÚ¿­À» ´ëüÇÒ ¶§´Â »ðÀÔ ÈÄ »èÁ¦ÇÏ´Â °ÍÀÌ ÀϹÝÀûÀÌ´Ù. ÇÏÁö¸¸ ¸¹Àº ³»¿ëÀ» ÇѲ¨¹ø¿¡ º¯°æÇÒ ¶§´Â µ¤¾î¾²±â ¸ðµå¿¡¼­ ÀÛ¾÷ÇÏ´Â °ÍÀÌ Æí¸®ÇÏ´Ù. µ¤¾î¾²±â ¸ðµå Áö¿øÀ» À§ÇØ Àü¿ªº¯¼ö¸¦ ¼±¾ðÇÏ°í ÀÌ º¯¼ö¸¦ ÃʱâÈ­ÇÑ´Ù.

 

BOOL bOvr;

 

BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)

{

     ....

     bOvr=FALSE;

 

     return TRUE;

}

 

µðÆúÆ® ¸ðµå´Â »ðÀÔ ¸ðµå·Î ½ÃÀ۵ǹǷΠbOvrº¯¼öÀÇ ÃʱⰪÀº FALSEÀÌ´Ù. ÀÌ º¯¼öÀÇ °ªÀº ÆíÁýÁß¿¡ ¾ðÁ¦µçÁö InsÅ°¸¦ ´­·¯ º¯°æÇÒ ¼ö ÀÖ´Ù. VK_INSERT¿¡¼­ ÀÌ º¯¼ö¸¦ Åä±Û½ÃÅ°µµ·Ï Äڵ带 ÀÛ¼ºÇÑ´Ù.

 

     case VK_INSERT:

          if (bShift) {

              SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(IDM_PASTE,0),0);

          } else if (bControl) {

              SendMessage(hWnd,WM_COMMAND,MAKEWPARAM(IDM_COPY,0),0);

        } else {

           bOvr = !bOvr;

           SetCaret();

        }

          return;

 

bOvrº¯¼ö¸¦ ¹Ù²Ù¾î ³õÀ¸¸é ÀÌÈÄ ÆíÁýÄڵ忡¼­ ÀÌ º¯¼ö°ª¿¡ µû¶ó ¹®ÀÚ¿­À» »ðÀÔÇÏ´Â ¹æ¹ýÀÌ ´Þ¶óÁø´Ù. µ¤¾î¾²±â ¸ðµå¿¡¼­ ij·µÀº ¹®ÀÚµé »çÀÌ¿¡ À§Ä¡ÇÏÁö ¾ÊÀ¸¸ç ´ÙÀ½ »èÁ¦µÉ ¹®ÀÚ¸¦ °¡¸®Å°µµ·Ï º¯°æµÇ¾î¾ß ÇϹǷΠSetCaretÀ» È£ÃâÇÏ¿© ij·µ ¸ð¾çÀ» º¯°æÇϵµ·Ï ÇÏ¿´´Ù. ÀÌ º¯¼ö°ª¿¡ ¿µÇâÀ» ¹Þ´Â ºÎºÐÀº ³× ±ºµ¥°¡ ÀÖ´Ù. ¿ì¼± ¿µ¹®ÀÚ¸¦ ÀԷ¹޴ OnChar ÇÔ¼ö¸¦ ¼öÁ¤Çϵµ·Ï ÇÏÀÚ.

 

void OnChar(HWND hWnd, TCHAR ch, int cRepeat)

{

    BOOL bPrevSel;

     ....

    bPrevSel=DeleteSelection();

    for (i=0;i<cRepeat;i++) {

        if (bOvr && bPrevSel==FALSE && ch!=¡®\r¡¯) {

           if (IsDBCS(off)) {

               if (buf[off] != ¡®\r¡¯) {

                   Delete(off,2);

               }

           } else {

               Delete(off,1);

           }

        }

          Insert(off,szChar);

          off+=lstrlen(szChar);

     }

     bComp=FALSE;

     Invalidate(FindParaStart(off-lstrlen(szChar)));

     SetCaret();

}

 

µ¤¾î¾²±â ¸ðµåÀ̸é ÇöÀç ij·µ À§Ä¡ÀÇ ¹®ÀÚ¸¦ ¸ÕÀú »èÁ¦ÇÑ ÈÄ »õ·Î ÀÔ·ÂµÈ ¹®ÀÚ¸¦ »ðÀÔÇϵµ·Ï ÇÏ¿´´Ù. »èÁ¦ ÈÄ »ðÀÔÇϹǷΠµ¤¾î¾²±â¸¦ ÇÏ´Â °Í°ú µ¿ÀÏÇÏ´Ù. ±×·¯³ª µ¤¾î ¾´´Ù°í Çؼ­ bufÀÇ ¹®ÀÚÄڵ带 Á÷Á¢ ¹Ù·Î ±³Ã¼Çؼ­´Â ¾ÈµÇ´Âµ¥ ¿Ö³ÄÇÏ¸é »èÁ¦µÉ ¹®ÀÚ¿Í »õ·Î »ðÀ﵃ ¹®ÀÚÀÇ ±æÀÌ°¡ Ç×»ó °°Áö ¾Ê±â ¶§¹®ÀÌ´Ù. ¿µ¹®ÀÚ°¡ Çѱۿ¡ ÀÇÇØ µ¤À̰ųª ¹Ý´ë·Î ÇѱÛÀÌ ¿µ¹®ÀÚ¿¡ ÀÇÇØ µ¤ÀÏ ¶§ ¹®¼­ ±æÀÌ¿¡ º¯È­°¡ »ý±â°Ô µÇ°í µû¶ó¼­ ¹®¼­¸¦ ÀçÁ¤·ÄÇØ¾ß ÇÑ´Ù. ÀÌ·± ó¸®¿Í ¹®¼­º¯°æÀÇ ÀÏ°ü¼ºÀ» À§ÇØ »èÁ¦ ÈÄ »ðÀÔ µ¿ÀÛÀº ¹Ýµå½Ã Delete¿Í InsertÀÇ ¿¬¼Ó È£ÃâÀ̾î¾ß ÇÑ´Ù.

¿©±â¿¡ ¸î °¡Áö Á¶°ÇÀÌ µé¾î°¡´Âµ¥ ¼±Åÿµ¿ªÀÌ ÀÖ¾úÀ» ¶§´Â ÇöÀç ij·µ À§Ä¡ÀÇ ¹®ÀÚ¸¦ »èÁ¦ÇÏ´Â °ÍÀÌ ¾Æ´Ï¶ó ¼±Åÿµ¿ªÀÌ ´ë½Å »èÁ¦µÇ¹Ç·Î ij·µ À§Ä¡ÀÇ ¹®ÀÚ¸¦ »èÁ¦ÇÒ ÇÊ¿ä°¡ ¾ø´Ù. ±×·¡¼­ DeleteSelection ÇÔ¼öÀÇ Ã³¸® °á°ú¸¦ bPrevSel·Î ´ëÀÔ¹Þ¾Ò´Ù°¡ ÀÌ °ªÀÌ TRUEÀÌ¸é ¼³»ç µ¤¾î¾²±â ¸ðµåÀÌ´õ¶óµµ Æò»ó½Ã¿Í ¸¶Âù°¡Áö·Î »ðÀÔ¸¸ ÇÑ´Ù.

°³ÇàÄÚµå´Â µ¤¾î¾²±â ¸ðµå¿¡¼­ Ưº°ÇÏ°Ô °ü¸®µÇ´Â ´ë»óÀÌ´Ù. ¿Ö³ÄÇÏ¸é µ¤¾î¾²±â¶õ ÀԷµǾî ÀÖ´Â ¹®ÀÚ¸¦ ´ë»óÀ¸·Î ÇÏ´Â °ÍÀÌÁö ¹®´Ü ±¸¼ºÀ» ¹Ù²Ù¾î¼­´Â ¾ÈµÇ±â ¶§¹®ÀÌ´Ù. µ¤¾î¾²±â ¸ðµå¿¡¼­µµ ¿£ÅÍ ÀÔ·ÂÀº ¿©ÀüÈ÷ »ðÀÔ°ú µ¿ÀÏÇÏ¿© <Enter>Å°¸¦ Ä¡¸é ¹®´ÜÀÌ ³¡³ª¸ç ´ÙÀ½ ÁÙ·Î °­Á¦ °³ÇàµÇ¾î¾ß ÇÑ´Ù. ¶ÇÇÑ »èÁ¦ÇÒ ´ë»óÀÌ °³ÇàÄÚµå¶ó¸é »èÁ¦ÇÏÁö ¸»°í °è¼Ó »ðÀÔÇÏ¿© ÁÙ µÚ¿¡ ¹®ÀÚ¸¦ ¿¬À̾î ÀÔ·ÂÇϵµ·Ï ÇÑ´Ù. Áï °³ÇàÄڵ带 ÀÔ·ÂÇÒ ¶§¿Í ÇöÀç ij·µ À§Ä¡°¡ °³ÇàÄÚµåÀÎ °æ¿ì ¸ðµÎ ¿¹¿Üó¸®ÇØ¾ß ÇÑ´Ù.

°³ÇàÄÚµå¿Í ¸¶Âù°¡Áö·Î ¶Ç Ư¼öÇÏ°Ô °ü¸®µÇ¾î¾ß ÇÒ Äڵ尡 Àִµ¥ ¹Ù·Î ¹®¼­ ³¡À» ³ªÅ¸³»´Â NULL¹®ÀÚÀÌ´Ù. ¾Æ¹«¸® µ¤¾î¾²±â ¸ðµå¶ó ÇÏ´õ¶óµµ ÀÌ ¹®ÀÚ´Â ¹®¼­ ÀÚü°¡ ¾Æ´Ï±â ¶§¹®¿¡ ´Ù¸¥ ¹®ÀÚ·Î ¹Ù²Ü ¼ö ¾ø´Ù. NULL¹®ÀÚ°¡ »ç¶óÁö¸é ApiEdit´Â ¹®¼­ ³¡À» ãÁö ¸øÇÏ°í ¿î¸íÇÏ°Ô µÈ´Ù. ±×·¯³ª À§ Äڵ带 º¸¸é ¾Ë°ÚÁö¸¸ NULL¹®ÀÚ¿¡ ´ëÇؼ­´Â ¾î¶°ÇÑ ¿¹¿Ü 󸮵µ ÇÏÁö ¾Ê°í Àִµ¥ ±×·¡µµ NULL¹®ÀÚ´Â Àý´ë·Î Áö¿öÁöÁö ¾Ê´Â´Ù. ¿Ö³ÄÇϸé Delete ÇÔ¼ö°¡ »èÁ¦µÉ ¹®ÀÚÀÇ ¹üÀ§ Á¡°ËÀ» öÀúÇÏ°Ô ÇÏ°í Àֱ⠶§¹®ÀÌ´Ù. Delete ÇÔ¼öÀÇ ¼±µÎ¿¡¼­ »èÁ¦ÇÒ ¹®ÀÚ ±æÀÌ°¡ 0ÀÌ»óÀÎÁö, »èÁ¦ ÈÄ¿¡µµ NULL¹®ÀÚ°¡ ¾È Áö¿öÁö´ÂÁö Ç×»ó °¨½ÃÇÏ°í ÀÖ´Ù.

OnImeChar ÇÔ¼öµµ °ÅÀÇ µ¿ÀÏÇÑ ¹æ¹ýÀ¸·Î ¼öÁ¤ÇÑ´Ù. ¹®ÀÚ¸¦ »ðÀÔÇϱâ Àü¿¡ ij·µ À§Ä¡¿¡ ÀÖ´Â ¹®ÀÚ¸¦ »èÁ¦Ç쵂 °³ÇàÄÚµå´Â »èÁ¦ÇÏÁö ¾Ê´Â´Ù. ÀÌ ÇÔ¼ö°¡ È£ÃâµÉ ¶§´Â ¼±Åÿµ¿ªÀÌ Ç×»ó ¾øÀ¸¸ç °³ÇàÄڵ尡 ÀԷµÇÁö ¾Ê±â ¶§¹®¿¡ OnChar ÇÔ¼öº¸´Ù´Â Á¶±Ý ´õ °£´ÜÇÏ´Ù.

 

LRESULT OnImeChar(HWND hWnd, WPARAM wParam, LPARAM lParam)

{

     ....

     if (bComp) {

          off-=2;

          Delete(off,2);

     }

    if (bOvr && bComp==FALSE) {

        if (IsDBCS(off)) {

           if (buf[off] != ¡®\r¡¯) {

               Delete(off,2);

           }

        } else {

           Delete(off,1);

        }

    }

     Insert(off,szChar);

     off+=lstrlen(szChar);

     bComp=FALSE;

     Invalidate(FindParaStart(off-lstrlen(szChar)));

     SetCaret();

     return 0;

}

 

µ¤¾î¾²±â ¸ðµåÀÌ°í ÇѱÛÁ¶¸³ÁßÀÌ ¾Æ´Ï¶ó¸é ÀÏ´Ü ÇöÀç À§Ä¡ÀÇ ¹®ÀÚ¸¦ »èÁ¦ÇÑ´Ù. À̶§µµ ¿£ÅÍÄÚµå´Â »èÁ¦ÇÏÁö ¾Êµµ·Ï ÁÖÀÇÇØ¾ß ÇÑ´Ù. OnImeCompostion ÇÔ¼ö´Â Á¶±Ý º¹ÀâÇÏ´Ù.

 

LRESULT OnImeComposition(HWND hWnd, WPARAM wParam, LPARAM lParam)

{

     ....

    BOOL bPrevSel;

    BOOL bNewIns=TRUE;

 

     if (bReadOnly)

          return 0;

 

    bPrevSel=DeleteSelection();

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

           bNewIns=FALSE;

          }

          if (len == 0) {

              bComp=FALSE;

          } else {

              bComp=TRUE;

          }

 

        if (bOvr && bNewIns && bPrevSel==FALSE) {

           if (IsDBCS(off)) {

               if (buf[off] != ¡®\r¡¯) {

                   Delete(off,2);

               }

           } else {

               Delete(off,1);

           }

        }

 

          Insert(off,szComp);

          off+=len;

          ImmReleaseContext(hWnd,hImc);

          free(szComp);

          Invalidate(FindParaStart(off-len));

          SetCaret();

     }

 

     return DefWindowProc(hWnd,WM_IME_COMPOSITION,wParam,lParam);

}

 

µ¤¾î¾²±â ¸ðµåÀÏ ¶§ ÇöÀç ¹®ÀÚ¸¦ »èÁ¦Ç쵂 ´Ü, ÇѱÛÀ» Á¶¸³ÁßÀÏ ¶§´Â ÀÌ¹Ì »èÁ¦¸¦ Ç߱⠶§¹®¿¡ ´Ù½Ã »èÁ¦¸¦ ÇÏÁö ¾Êµµ·Ï ÇÑ´Ù. bNewIns º¯¼ö´Â »õ·Î ¹®ÀÚ°¡ »ðÀÔµÈ °ÍÀÎÁö ¾Æ´ÑÁö¸¦ °¡¸®Å°´Â º¯¼öÀε¥ Á¶¸³Áß¿¡ »õ À½¼Ò°¡ ÀԷµǾú´Ù¸é ÀÌ º¯¼ö°¡ TRUE°¡ µÇ°í Á¶¸³Áß¿¡ ¹®ÀÚ°¡ ´ëüµÇ¾úÀ¸¸é ÃʱⰪÀÎ FALSE¸¦ ±×´ë·Î °¡Áø´Ù.

»ó±âÀÇ ¼¼ °¡Áö ÀÔ·Â ÇÔ¼ö°¡ µ¤¾î¾²±â¿¡ ´ëÇÑ Ã³¸®¸¦ ó¸®ÇÏ°í ÀÖÀ¸¸ç ¸¶Áö¸·À¸·Î SetCaret¿¡¼­ µ¤¾î¾²±â ¸ðµåÀÏ ¶§ ij·µÀÇ ¸ð¾çÀ» º¯°æÇÏ¸é µÈ´Ù.

 

void SetCaret(BOOL bUpdatePrevX/*=TRUE*/, BOOL bScrollToCaret/*=TRUE*/)

{

     ....

     if (bComp) {

          toff=off-2;

          caretwidth=GetCharWidth(buf+toff,2);

     } else {

          toff=off;

          caretwidth=2;

     }

 

    if (bOvr) {

        if (IsDBCS(toff)) {

           if (buf[toff] == ¡®\r¡¯) {

               caretwidth=arChWidth[¡® ¡®];

           } else {

               caretwidth=GetCharWidth(buf+off,2);

           }

        } else {

           caretwidth=GetCharWidth(buf+off,1);

        }

    }

     CreateCaret(hWndMain,NULL,caretwidth,FontHeight);

     ShowCaret(hWndMain);

     ....

 

µ¤¾î¾²±â ¸ðµåÀ̸é ij·µÀÇ ÆøÀ» ij·µ À§Ä¡ÀÇ ¹®ÀÚÆø¸¸Å­ È®ÀåÇØ ÀÌ ¹®ÀÚ°¡ ´ÙÀ½¿¡ µ¤¾î ¾²¿©Áú ¹®ÀÚ¶ó´Â °ÍÀ» º¸¿©ÁØ´Ù. ´Ü °³ÇàÄÚµå´Â DBCSÀÌÁö¸¸ ³Ê¹« ÆøÀÌ ³ÐÀ¸¸é º¸±â ÁÁÁö ¾ÊÀ¸¹Ç·Î °ø¹é°ú °°Àº ÆøÀ» °¡Áöµµ·Ï Çß´Ù. ij·µÀÌ ¹®¼­ ³¡¿¡ ÀÖÀ» ¶§´Â NULL¹®ÀÚÀÇ ÆøÀÌ Ä³·µÀÇ ÆøÀÌ µÇ´Âµ¥ PrepareCharWidth ÇÔ¼ö¿¡¼­ ÀÌ °æ¿ìÀÇ Ã³¸®¸¦ À§ÇØ NULL¹®ÀÚÀÇ ÆøÀ» °ø¹éÆø°ú °°µµ·Ï Çصξú´Ù.