µ¤¾î¾²±â ¸ðµå´Â 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¹®ÀÚÀÇ ÆøÀ» °ø¹éÆø°ú °°µµ·Ï Çصξú´Ù.