´ç±ÙÀÇ Ãë¼Ò, Àç½ÇÇà ±â´ÉÀº ¸Þ¸ð¸® ¿ë·®±îÁö ¹«ÇÑ ´Ü°èÀÇ ÆíÁý °úÁ¤À» ÀúÀåÇÒ ¼ö ÀÖ´Ù´Â ¸é¿¡¼ »ó´çÈ÷ ¿ì¼öÇÑ ÆíÀÌ´Ù. ±×·±µ¥ Ãë¼Ò, Àç½ÇÇàÀ» ÇÒ ¶§ ÇÑ ´Ü°è¾¿¸¸ Ãë¼Ò, Àç½ÇÇàÇÒ ¼ö ÀÖÀ¸¹Ç·Î ÇÑÂü ÀÌÀüÀÇ ´Ü°è·Î µ¹¾Æ°¡°í ½ÍÀ¸¸é Ctrl+Z¸¦ °è¼Ó ´©¸£°í ÀÖ¾î¾ß ÇϹǷΠ´Ù¼Ò ºÒÆíÇÑ ¸éÀÌ ÀÖ´Ù. Áö±Ý±îÁö ÆíÁýÇß´ø °úÁ¤ÀÇ ¸ñ·ÏÀ» º¸¿©ÁÖ°í ÁöÁ¤ÇÑ ÁöÁ¡±îÁö ÇѲ¨¹ø¿¡ Ãë¼ÒÇÒ ¼ö ÀÖ´Ù¸é ´õ Æí¸®ÇÒ °ÍÀÌ´Ù. ºñÁÖ¾ó ½ºÆ©µð¿À¿Í ¿öµå¿¡ ÀÌ¹Ì ÀÌ ±â´ÉÀÌ ÀÛ¼ºµÇ¾î Àִµ¥ ÀÌ ±â´É°ú ¶È°°ÀÌ ¸¸µé¾î º¸ÀÚ.
ÀÌ ±â´ÉÀº ÇѲ¨¹ø¿¡ ÆíÁý µ¿ÀÛÀ» Ãë¼ÒÇÒ ¼ö ÀÖ´Ù´Â ¸é¿¡¼ ½Ç¿ë¼ºÀÌ ÀÖÀ» »Ó¸¸ ¾Æ´Ï¶ó ÆíÁý ±â·ÏÀ» »ìÆì º¸´Â ¿ëµµ·Îµµ °¡Ä¡°¡ ÀÖ´Ù. ¸ñ·ÏÀ» ÆîÃÄ º¸¸é ¾î¶² µ¿ÀÛÀ» ¾î¶² ¼ø¼´ë·Î ½ÇÇàÇß´ÂÁö¸¦ Àϸñ ¿ä¿¬ÇÏ°Ô ¾Ë ¼ö ÀÖ´Ù. »ðÀÔ, »èÁ¦, À̵¿ µîÀÇ µ¿ÀÛ¿¡ ´ëÇØ À̸§À» ºÙÀÌ°í »ðÀÔ, »èÁ¦ ´ë»ó±îÁöµµ Ç¥½ÃÇϸé ÆíÁý µ¿ÀÛÀ» ¿ä¾àÀûÀ¸·Î Ç¥ÇöÇÒ ¼ö ÀÖ´Ù.
±×·ì µ¿ÀÛÀº ¼¼ºÎÀûÀ¸·Î ¼ö¸¹Àº »ðÀÔ, »èÁ¦, À̵¿À¸·Î ÀÌ·ç¾îÁö´Âµ¥ ÇϳªÀÇ ÆíÁý µ¿ÀÛÀ» À§ÇÑ ±×·ìÀ̹ǷΠ¸ñ·Ï¿¡µµ Çϳª·Î ±â·ÏÇÏ´Â °ÍÀÌ ´õ ÁÁ´Ù. À̶§ ±×·ì µ¿ÀÛ¿¡ ´ëÇÑ ¼³¸íÀ» ¾î¶»°Ô Ç¥½ÃÇÒ °ÍÀΰ¡°¡ ¹®Á¦Àε¥ ±×·ì µ¿ÀÛ¿¡ ´ëÇؼµµ ¼³¸íÀ» ºÙÀÏ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. ÇöÀç ÆíÁý ±×·ìÀº StartUndoGroup ÇÔ¼ö·Î ½ÃÀ۵Ǹç ƽ Ä«¿îÆ®¿Í ±×·ì ¼±µÎ ·¹ÄÚµåÀÇ ¹øÈ£¸¦ Á¶ÇÕÇÑ ±×·ì ID·Î ±×·ì¿¡ ¼ÓÇÑ ·¹Äڵ带 ±¸ºÐÇÒ »Ó º°µµÀÇ ¼³¸íÀº ÀÛ¼ºµÇÁö ¾Ê´Â´Ù. ±×·¡¼ ±×·ì¿¡ ´ëÇÑ ¼³¸í ·¹Äڵ带 ÀÛ¼ºÇϱâ À§ÇØ UR_GROUPÀ̶ó´Â ·¹ÄÚµå ŸÀÔÀ» Ãß°¡ÇÑ´Ù.
enum { UR_NONE, UR_INSERT, UR_DELETE, UR_MOVE, UR_GROUP };
ÀÌ ·¹ÄÚµå´Â ½ÇÁ¦ ÆíÁý µ¿ÀÛÀ» ±â·ÏÇÏÁö´Â ¾ÊÁö¸¸ ±×·ì¿¡ ´ëÇÑ ¼³¸íÀ» ºÙÀÌ´Â ¿ëµµ·Î »ç¿ëµÈ´Ù. pos³ª len µîÀº »ç¿ëÇÏÁö ¾ÊÀ¸¸ç data¿¡ ¹®ÀÚ¿ Æ÷¸ËÀ¸·Î ÆíÁý ±×·ì¿¡ ´ëÇÑ °£·«ÇÑ ¼³¸íÀ» ÀúÀåÇÒ °ÍÀÌ´Ù. ¿¹¸¦ µé¾î ºí·Ï µé¿©¾²±â µ¿ÀÛÀ» À§ÇÑ ÆíÁýÀ» ÇÑ´Ù¸é "ºí·Ï µé¿©¾²±â"¶ó´Â ¹®ÀÚ¿À» °¡Áö´Â UR_GROUP ·¹Äڵ带 ¸ÕÀú ÀÛ¼ºÇÏ°í ÀÌ ·¹ÄÚµå µÚ¿¡ ÆíÁý µ¿ÀÛÀÇ ±×·ìÀÌ µû¶ó¿À´Â ½ÄÀÌ´Ù. ±×·ìÀ» ½ÃÀÛÇÏ´Â ÇÔ¼ö¸¦ ´ÙÀ½°ú °°ÀÌ ¼öÁ¤ÇÑ´Ù.
void CApiEdit::StartUndoGroup(int id, TCHAR *desc/*=NULL*/)
{
// Ç×»ó »õ·Î¿î ·¹Äڵ忡¼ ½ÃÀÛÇÏ¸ç º´ÇÕÇÏÁö ¾Ê´Â´Ù.
if (CanRedo()) {
ClearRedo();
} else {
if (pUR[nowur].action != UR_NONE) {
NextRecord();
}
}
// »õ ±×·ìÀÌ ½ÃÀ۵Ǹé UR_GROUP ·¹Äڵ带 ÀÛ¼ºÇÑ´Ù. Áßø ±×·ìÀº Á¦¿ÜÇÑ´Ù.
if (URnest==0) {
URtick=((nowur << 16) | (GetTickCount() & 0xffff));
// ¼³¸íÀº desc¿¡ ÀÛ¼ºÇÏ°í ±×·ì id´Â pos¿¡ ±â·ÏÇÑ´Ù.
if (desc) {
AllocURData(nowur,lstrlen(desc)+1,0);
lstrcpy(pUR[nowur].data,desc);
} else {
AllocURData(nowur,sizeof(int)*2,0);
lstrcpy(pUR[nowur].data,"");
}
pUR[nowur].action=UR_GROUP;
pUR[nowur].pos=id;
pUR[nowur].tick=URtick;
}
URnest++;
}
±×·ì Çì´õ´Â Ç×»ó »õ·Î¿î ·¹Äڵ忡¼ ½ÃÀÛÇÑ´Ù. Áï, ±×·ìÀº ±×·ì ÀÌÀüÀÇ ·¹ÄÚµå¿Í Á¶°ÇÀÌ ¸Â¾Æµµ º´ÇÕÇÏÁö ¾Ê´Â´Ù. 1.0ÀÇ º´ÇÕ ¾Ë°í¸®Áò¿¡ Ä¡¸íÀûÀÎ ¹®Á¦´Â ¾Æ´ÏÁö¸¸ ¾à°£ÀÇ ¹ö±×°¡ ÀÖ¾ú´Âµ¥ StartUndoGroupÀÌ »õ ·¹ÄÚµå ºÐÇÒÀ» ÇÏÁö ¾Ê±â ¶§¹®¿¡ ±×·ì°ú ¾È±×·ì ·¹Äڵ尡 º´ÇյǴ ¹®Á¦Á¡ÀÌ ÀÖ´Ù. ¿¹¸¦ µé¾î abcdef°¡ ÀԷµǾî ÀÖÀ» ¶§ dÀÚ¸®¿¡¼ BS¼¼¹ø ´·¯ abcÁö¿ì°í def¸¦ ºí·ÏÀ¸·Î ¼±ÅÃÇÑ ÈÄ ghi·Î ´ëüÇÏ¸é ´ÙÀ½°ú °°ÀÌ ±â·ÏµÈ´Ù.
¹®¼ |
µ¿ÀÛ |
·¹ÄÚµå |
abcdef |
abcÁö¿ò |
abc »èÁ¦ |
def |
def ¼±Åà ÈÄ ghi»ðÀÔ |
abc »èÁ¦¿Í def »èÁ¦ º´ÇÕ ghi »ðÀÔ |
ghi |
|
|
def »èÁ¦°¡ Á÷ÀüÀÇ abc »èÁ¦¿Í º´ÇÕµÇ¾î ¹ö¸®±â ¶§¹®¿¡ ghi »ðÀÔÀÌ ¼±Åà ´ëü ±×·ìÀ» ±¸¼ºÇÏÁö ¸øÇÏ´Â °ÍÀÌ´Ù. def »èÁ¦¿Í ghi »ðÀÔÀÌ ÇÑ µ¿ÀÛÀ̹ǷΠÀÌ µÑÀÌ ±×·ìÀÌ µÇ¾î¾ß Çϸç abc »èÁ¦¿Í def »èÁ¦´Â Á¶°ÇÀÌ ¸Â´õ¶óµµ ÇÑ ±×·ìÀÌ µÇ¾î¼´Â ¾ÈµÈ´Ù. ÀÌ·± ¹®Á¦¸¦ ÇØ°áÇϱâ À§ÇØ ¾ÕÂÊ ·¹Äڵ忡 ÆíÁý µ¿ÀÛÀÌ ±â·ÏµÇ¾î ÀÖÀ¸¸é ¹«Á¶°Ç NextRecord·Î ´ÙÀ½ ·¹ÄÚµå·Î À̵¿Çß´Ù.
±×·ìÀÌ ½ÃÀ۵Ǹé UR_GROUP ±×·ì ·¹Äڵ带 ÀÛ¼ºÇÑ´Ù. Àμö·Î ±×·ìÀÇ µ¿ÀÛÀ» ¼³¸íÇÏ´Â Á¤¼öÇüÀÇ id¿Í Ãß°¡ ¼³¸í ¹®ÀÚ¿À» Àü´Þ¹Þ¾Æ id´Â Ãë¼Ò ·¹ÄÚµåÀÇ pos¿¡ ±â·ÏÇÏ°í ¼³¸íÀº data¿¡ ¸Þ¸ð¸®¸¦ ÇÒ´çÇÏ¿© ±â·ÏÇÑ´Ù. ´Ü, ÀÌ ±×·ì ·¹ÄÚµå´Â ±×·ìÀÇ Çì´õÀÏ °æ¿ì¸¸ ÀÛ¼ºÇÑ´Ù. ´Ù¸¥ ±×·ì¿¡ ÁßøµÈ ±×·ìÀº ¸ñ·Ï¿¡ ³ªÅ¸³ªÁö ¾Ê±â ¶§¹®¿¡ ¼³¸íÀ» µû·Î ºÙÀÏ ÇÊ¿ä°¡ ¾ø´Ù. ±×·ì¿¡ ¼ÓÇÑ ±×·ìÀº ´õ ÀÌ»ó ±×·ìÀÌ ¾Æ´Ï¸ç ±×·ìÀ» ±¸¼ºÇÏ´Â ±¸¼º¿øÀÏ »ÓÀÌ´Ù.
±×·ìÀ» ½ÃÀÛÇÏ´Â StartUndoGroup ÇÔ¼öÀÇ ¿øÇüÀÌ ¼öÁ¤µÇ¾úÀ¸¹Ç·Î ÀÌ ÇÔ¼ö¸¦ È£ÃâÇÏ´Â ¸ðµç ºÎºÐ¿¡¼ ±×·ìÀ» ½ÃÀÛÇÒ ¶§ id¿Í ÇÊ¿äÇÒ °æ¿ì ¼³¸í ¹®ÀÚ¿À» Á¦°øÇØ¾ß ÇÑ´Ù. StartUndoGroup¿¡ Àμö¸¸ Ãß°¡ÇÏ¸é µÈ´Ù. ´ëºÎºÐ ApiEditText.cpp¿¡ ÀÖ´Ù.
À§Ä¡ |
¼³¸í |
OnChar OnImeComposition InsertText |
pFrame->StartUndoGroup(1); |
IDM_AE_PASTE |
pFrame->StartUndoGroup(2); |
ChangeCase |
pFrame->StartUndoGroup(3); |
RemoveExtraSpace |
pFrame->StartUndoGroup(4); |
BlockIndent |
pFrame->StartUndoGroup(5); |
Dangeun.cppÀÇ OnUser2 |
pSi->Ae.StartUndoGroup(6); |
CApiEditHexa::OnChar |
pFrame->StartUndoGroup(7); |
´ÙÀ½ ¼¼ ÇÔ¼ö´Â Á» ´õ ÀÚ¼¼ÇÑ ¼³¸íÀ» ºÙÀ̱â À§ÇØ ±¸Á¶°¡ ¾à°£ ¹Ù²î±âµµ ÇÑ´Ù. ¿¹¸¦ µé¿© ºí·Ï µé¿©¾²±âÀÇ °æ¿ì µé¿©¾²±âÀÎÁö ³»¾î¾²±âÀÎÁö¸¦ ±¸ºÐÇØ¾ß Çϸç InsertComment ÇÔ¼öÀÇ °æ¿ì ÁÖ¼®È¿Í ÁÖ¼® ÇØÁ¦¸¦ µ¿½Ã¿¡ ÇÏ°í ÀÖÀ¸¹Ç·Î Àü´ÞµÈ Àμö¿¡ µû¶ó ¼³¸íÀ» ´Þ¸®ÇØ¾ß ÇÑ´Ù.
void CApiEditText::ProcessIndent(TCHAR ch)
{
TCHAR szIndent[4096];
int toff;
int tlen;
BOOL bAllSpace;
int nTab;
if (ch == '\r') {
if (IsPrevParaBlockOpen(off)) {
MakeIndentString(1,szIndent,4096);
pFrame->StartUndoGroup(9);
} else {
lstrcpy(szIndent,"");
pFrame->StartUndoGroup(8);
}
pFrame->StartUndoGroup();
....
if (ch!='\r' && tlen && off >= tlen) {
....
pFrame->StartUndoGroup(10);
int CApiEditText::ReplaceText(int nPos, TCHAR *what, DWORD dwFlag, TCHAR *to)
{
TCHAR szDesc[1024];
....
wsprintf(szDesc," (%s -> %s)",what,to);
pFrame->StartUndoGroup(11,szDesc);
void CApiEditText::ConvertSpaceTab(BOOL bToSpace)
{
....
if (bToSpace) {
....
pFrame->StartUndoGroup(12);
} else {
....
pFrame->StartUndoGroup(13);
}
pFrame->StartUndoGroup();
void CApiEditText::InsertComment(BOOL bUnComment)
{
if (!bUnComment) {
....
pFrame->StartUndoGroup(14);
} else {
....
pFrame->StartUndoGroup(15);
}
pFrame->StartUndoGroup();
±×·ìÀ» ±¸¼ºÇÒ ¶§¸¶´Ù Ãë¼Ò ·¹Äڵ忡 ±×·ì ¼³¸íÀ» À§ÇÑ ·¹Äڵ带 ÀÛ¼ºÇϹǷΠ¸Þ¸ð¸®´Â Á¶±Ý ´õ ¾²°Ô µÉ °ÍÀÌ´Ù. °¢ ±×·ì µ¿ÀÛÀÌ ±¸Ã¼ÀûÀ¸·Î ¾î¶² µ¿ÀÛÀÎÁö´Â º°µµÀÇ ¹®ÀÚ¿ ¹è¿À» ÀÛ¼ºÇÑ´Ù. ´ÙÀ½ ¹è¿À» Dangeun.cppÀÇ ¼±µÎ¿¡ Á¤ÀÇÇÑ´Ù.
TCHAR arGroupDesc[50][32]={"",
"¼±Åà ´ëü",
"¼±Åà ´ëü ºÙ¿© ³Ö±â",
"´ë¼Ò¹®ÀÚ º¯°æ",
"¿©ºÐ °ø¹é Á¦°Å",
"ºí·Ï µé¿©¾²±â", // 5
"¸ðµÎ ¹Ù²Ù±â",
"ÀÌÁø ¹ÙÀÌÆ® ÆíÁý",
"ÀÚµ¿ µé¿©¾²±â",
"¹®¹ý µé¿©¾²±â",
"¹®¹ý ³»¾î¾²±â", // 10
"¹Ù²Ù±â",
"ÅÇÀ» °ø¹éÀ¸·Î",
"°ø¹éÀ» ÅÇÀ¸·Î",
"ÁÖ¼®À¸·Î",
"ÁÖ¼® Á¦°Å", // 15
"¿ »èÁ¦",
"¿ ºÙ¿©³Ö±â",
"¿ º¹»ç",
"¿ À̵¿",
"¿ ´ë¼Ò¹®ÀÚ º¯°æ", // 20
"¸ÅÅ©·Î ½ÇÇà",
"»ó¿ë±¸ »ðÀÔ",
"ÀÚµ¿ »ó¿ë±¸ »ðÀÔ",
"»èÁ¦-½º¸¶Æ® °ø¹é",
"ºÙ¿© ³Ö±â", // 25
"º¹»ç",
"À̵¿",
"¹®´Ü º´ÇÕ",
"¹®´Ü ºÐÇÒ",
"¹®´Ü ¼öÆò Á¤·Ä", // 30
"¹®´Ü Å©±â¼ø Á¤·Ä",
"¹®´Ü ºóÁÙ Á¶Á¤",
};
Áö±Ý ´çÀå Á¤ÀǵÇÁö ¾ÊÀº ±×·ì µ¿ÀÛ¿¡ ´ëÇÑ ¼³¸íµµ ¹Ì¸® ÀÛ¼ºÇØ ³õ¾Ò´Ù. ±×·ì µ¿ÀÛÀÌ ´õ ´Ã¾î³ª¸é ÀÌ ¹è¿ÀÇ Å©±â¿Í ÃʱâÈ ¹®ÀÚ¿µµ °°ÀÌ ´Ã¾î³¯ °ÍÀÌ´Ù. Ãë¼Ò ·¹ÄÚµåÀÇ actionÀÌ UR_GROUPÀÌ°í pos°¡ 5ÀÌ¸é ºí·Ï µé¿©¾²±â µ¿ÀÛ¿¡ ´ëÇÑ ±×·ìÀÓÀ» ¾Ë ¼ö ÀÖ´Ù. ±×·ì µ¿ÀÛ¿¡ ´ëÇØ Á¤¼öÇüÀ¸·Î id¸¦ ºÙÀÌ°í È£½ºÆ®°¡ id¿¡ ´ëÇÑ ¼³¸í ¹®ÀÚ¿À» Á¦°øÇÏ´Â ÀÌÀ¯´Â ´Ù±¹¾î ¹öÀüÀ» ½±°Ô ¸¸µé±â À§ÇؼÀÌ´Ù.
È£½ºÆ®´Â ¹®ÀÚ¿ ¸®¼Ò½º¸¦ ¹Ù²Ù¸é ´Ù¸¥ ¾ð¾î¸¦ ¾µ ¼ö ÀÖ´Ù. ±×·¯³ª ÄÁÆ®·ÑÀº ¸®¼Ò½º¸¦ °¡ÁöÁö ¾Ê±â ¶§¹®¿¡ ´Ù¸¥ ¾ð¾î¸¦ Áö¿øÇÏ·Á¸é ¹«Ã´ ¹ø°Å·Î¿ÍÁø´Ù. ±×·¡¼ ApiEdit´Â ±×·ì µ¿ÀÛ¿¡ ´ëÇÑ ¼³¸íÀ» Á÷Á¢ ¹®ÀÚ¿·Î ´ÞÁö ¾Ê°í ÀÏ·Ã ¹øÈ£·Î Á¤ÀÇÇϱ⸸ ÇÑ´Ù. ÇöÀç±îÁö ApiEditÀÇ ¼Ò½º¿¡¼ ¹®ÀÚ¿À» Á÷Á¢ »ç¿ëÇÑ °æ¿ì´Â Æ˾÷ ¸Þ´ºÀÇ "À߶󳻱â", "º¹»ç" °°Àº ¸Þ´º ĸ¼Ç¹Û¿¡ ¾ø´Ù. ÀÌ ¹®ÀÚ¿µµ ¹°·Ð ³ªÁß¿¡´Â ´Ù¸¥ ¹æ½ÄÀ¸·Î ±¸Çϵµ·Ï ¹Ù²Ù¾î¾ß ÇÑ´Ù. ÄÁÆ®·ÑÀÌ Á÷Á¢ ¹®ÀÚ¿À» ´Ù·ç´Â °ÍÀº ÁÁÁö ¾Ê´Ù.
±×·ì ½ÃÀÛ¸¸ ÇØ ³õ°í ½ÇÁ¦ ·¹Äڵ带 ±â·ÏÇÏÁö ¾Ê´Â °æ¿ì°¡ ÀÖ´Ù. ¿¹¸¦ µé¾î ÀÚµ¿ µé¿©¾²±âÀÇ °æ¿ì ±×·ì ½ÃÀÛÀº ÇßÁö¸¸ ÀÚµ¿ µé¿©¾²±â ÇÒ ³»¿ëÀÌ ¾øÀ¸¸é ½ÇÁ¦ ·¹Äڵ尡 ±â·ÏµÇÁö ¾Ê´Â´Ù. ¸ðµÎ ¹Ù²Ù±âÀÇ °æ¿ì ÀÏ´Ü ±×·ìÀ» ½ÃÀÛÇÏÁö¸¸ ã´Â ³»¿ëÀÌ ¾øÀ¸¸é ±×·ì Çì´õ¸¸ ÀÖ°í º»Ã¼´Â ¾øÀ» °ÍÀÌ´Ù. ³ªÈ¦·Î ±×·ìÀº »ç½Ç Á¸Àç °¡Ä¡°¡ ¾øÁö¸¸ Äڵ带 °£´ÜÇÏ°Ô Çϱâ À§Çؼ´Â ºÒ°¡ÇÇÇÏ°Ô ÀϽÃÀûÀ¸·Î »ý¼ºµÉ ¼ö¹Û¿¡ ¾ø´Ù. ±×·ìÀ» ½ÃÀÛÇÏ´Â ½ÃÁ¡¿¡¼ ½ÇÁ¦ ÆíÁý ¿©ºÎ¸¦ ÆÇ´ÜÇϱⰡ ´ë´ÜÈ÷ ¾î·Æ´Ù. ±×·¡¼ ÀÏ´Ü ³ªÈ¦·Î ±×·ìÀ» ±â·ÏÇØ ³õ°í ±×·ìÀ» ³¡³¾ ¶§ ÀÌ ±×·ìÀÌ ½ÇÁ¦ ÆíÁý ·¹Äڵ带 °¡Áö°í ÀÖ´ÂÁö Á¡°ËÇØ º¸°í ºó ·¹ÄÚµåÀÌ¸é »èÁ¦ÇÑ´Ù.
void CApiEdit::EndUndoGroup()
{
URnest--;
if (URnest==0) {
if (pUR[nowur].action == UR_GROUP) {
pUR[nowur].action=UR_NONE;
}
URtick=0;
}
}
±×·ìÀ» ³¡³¾ ¶§ nowurÀÚ¸®°¡ ±×·ì Çì´õ¶ó¸é ºó ±×·ìÀ̹ǷΠÀÌ ·¹ÄÚµåÀÇ actionÀ» UR_NONEÀ¸·Î ¸¸µé¾î ´ÙÀ½ ·¹ÄÚµå ÀÛ¼º½Ã Àç»ç¿ëÇÑ´Ù. ÇÒ´çÇØ ³õÀº ¸Þ¸ð¸®³ª pos, tick°ªÀº ±×´ë·Î µÎ¾îµµ ¾îÂ÷ÇÇ ´ÙÀ½¿¡ »õ·Î¿î °ªÀ¸·Î ´ëÀԵǹǷΠ»ó°ü¾ø´Ù. ±×·ìÀ» ³¡³¾ ¶§ NextRecord´Â È£ÃâÇÏÁö ¾Ê´Âµ¥ ¹Ù·Î ´ÙÀ½¹ø ·¹Äڵ尡 ±×·ìÀÇ ³¡ ·¹ÄÚµå¿Í º´ÇÕµÉ ¼ö Àֱ⠶§¹®ÀÌ´Ù. ¿¹¸¦ µé¾î abc¸¦ ¼±ÅÃÇØ ³õ°í def·Î ´ëüÇÒ ¶§ abc »èÁ¦¿Í dÀÔ·ÂÀÌ ÀÏ´Ü ±×·ìÀ¸·Î ÀÛ¼ºµÇ¸ç À̾îÁö´Â ef »ðÀÔÀÌ d»ðÀÔ°ú º´ÇյǾî¾ß abc »èÁ¦, def »ðÀÔÀÌ ÇÑ ±×·ìÀÌ µÉ ¼ö ÀÖ´Ù.
´ÙÀ½ ÇÔ¼öµéÀº ÆíÁý ±×·ìÀ» °ü¸®ÇÏ´Â ÇÔ¼öµéÀÌ¸ç ´ÙÀ½ Ç×ÀÇ ÆíÁý ±â·Ïâ¿¡¼ »ç¿ëÇÑ´Ù. FindGroupEnd´Â ±×·ìÀÇ ¸¶Áö¸· ·¹Äڵ带 ã´Â À¯Æ¿¸®Æ¼ ÇÔ¼öÀÌ´Ù. ƽ°ªÀÌ ´Ù¸¥ ÃÖÃÊÀÇ ·¹Äڵ带 ãÀº ÈÄ ¹Ù·Î Á÷ÀüÀÇ ·¹ÄÚµå ¹øÈ£¸¦ ÃëÇÏ¸é ¿©±â°¡ ±×·ìÀÇ ³¡ÀÌ´Ù.
int CApiEdit::FindGroupEnd(int idx)
{
int i;
for (i=idx+1;pUR[i].tick == pUR[idx].tick;i++);
return i-1;
}
void CApiEdit::MultiUndo(int idx)
{
for (;;) {
if (CanUndo()) {
Undo();
} else {
break;
}
if (nowur <= idx) {
break;
}
}
}
void CApiEdit::MultiRedo(int idx)
{
for (;;) {
if (CanRedo()) {
Redo();
} else {
break;
}
if (nowur > idx) {
break;
}
}
}
MultiUndo, MutiRedo´Â Àμö·Î Àü´Þ¹ÞÀº idx¹ø±îÁö ÇѲ¨¹ø¿¡ Undo, RedoÇÑ´Ù. idx¿¡ À̸¦ ¶§±îÁö Undo, Redo¸¦ °è¼Ó È£ÃâÇÏ´Â °£´ÜÇÑ ±¸Á¶·Î µÇ¾î ÀÖÀ¸¸ç ±×¸¸µÑ ½ÃÁ¡À» ÆÇ´ÜÇÏ´Â ºÎµîÈ£¿¡¸¸ ÁÖÀÇÇÏ¸é µÈ´Ù. MuitiUndo´Â idxº¸´Ù Å©Áö ¾ÊÀ» ¶§ Å»ÃâÇϹǷΠ<=·Î ºñ±³, MultiRedo´Â idxº¸´Ù Ŭ ¶§ Å»ÃâÇϹǷΠ>·Î ºñ±³ÇÑ´Ù.
ÀÌ Â÷ÀÌ´Â Undo¿Í Redo ÇÔ¼öÀÇ ±¸Á¶ Â÷ÀÌ¿¡¼ ±âÀÎÇÏ¸ç ´õ ±Ùº»ÀûÀ¸·Î´Â nowurÀÌ ¾îµð¸¦ °¡¸®Å°°í Àִ°¡ÀÇ Á¤ÀÇ¿¡ ÀÇÇØ °áÁ¤µÈ °ÍÀÌ´Ù. Undo´Â Å»Ãâ Á¡°ËÀ» ÇÑ ÈÄ nowur--·Î ´ÙÀ½ ·çÇÁ¸¦ µ¹±â ¶§¹®¿¡ Ãë¼ÒÈÄ ±× ÀÚ¸®¿¡ ¸Ó¹®´Ù. ¹Ý¸é Redo´Â ¹«Á¶°Ç NextRecordÈ£ÃâÀ» ¸ÕÀúÇÏ°í Å»Ãâ Á¡°ËÀ» ÇϹǷΠÀç½ÇÇà ÈÄ ´ÙÀ½ ·¹ÄÚµå·Î À̵¿ÇØ ÀÖ°Ô µÈ´Ù.
±×·¡¼ nowur°ú idx°¡ °°¾ÆÁø »óȲ¿¡ ´ëÇÑ Ã³¸®°¡ ´Þ¶óÁö´Â °ÍÀÌ´Ù. MultiUndo´Â idx±îÁö ÀÌ¹Ì Ãë¼ÒµÇ¾úÀ¸¹Ç·Î À̶§ Å»ÃâÇÑ´Ù. MultiRedo´Â ¾ÆÁ÷ idx±îÁö Àç½ÇÇàÇÑ °ÍÀÌ ¾Æ´Ï¹Ç·Î Çѹø ´õ Redo¸¦ È£ÃâÇØ¾ß ÇÑ´Ù. ÀÌ·¸°Ô ¼³¸íÀ» ÀÐÀ¸¸é Á¤¸» º¹ÀâÇØ º¸ÀÌÁö¸¸ ½ÇÁ¦·Î ¹®Á¦¸¦ Ç®¾î º¸¸é º° °Íµµ ¾Æ´Ï´Ù. óÀ½¿¡ ´ëÃæ ¸¸µé¾î ³õ°í µð¹ö°Å·Î µ¹·Á º¸¸é ¾î¶² ¿¬»êÀÚ·Î ºñ±³¸¦ ÇØ¾ß ÇÒÁö ½±°Ô °áÁ¤ÇÒ ¼ö ÀÖ´Ù.
±×·ì Çì´õ ·¹Äڵ尡 Ãß°¡µÇ¾úÁö¸¸ Undo, Redo µî Ãë¼Ò ·¹Äڵ带 °ü¸® ¹× »ç¿ëÇÏ´Â ÇÔ¼öµéÀº ¼öÁ¤ÇÒ ÇÊ¿ä°¡ ¾ø´Ù. Undo, Redo ÇÔ¼ö´Â action¿¡ µû¶ó ÀûÀýÇÑ µ¿ÀÛÀ» Çϴµ¥ actionÀÇ switch ¹®¿¡ case UR_GROUP¿¡ ´ëÇÑ Ã³¸®°¡ ¾ø±â ¶§¹®¿¡ ÀÚ¿¬È÷ ¹«½ÃµÈ´Ù.
ÆíÁý ±â·Ïâ Ç¥½Ã¸¦ À§ÇØ Åø¹ÙÀÇ Ãë¼Ò, Àç½ÇÇà ¹öÆ°ÀÇ ½ºÅ¸ÀÏÀ» µå·Ó ´Ù¿îÀ¸·Î º¯°æÇØ ³õ¾Ò´Ù. ÀÌ ¹öÆ°À» ´©¸£¸é ÆíÁý °úÁ¤À» Ç¥½ÃÇÏ´Â ÀÛÀº ´ëÈ»óÀÚ¸¦ ¿ °ÍÀÌ´Ù. µå·Ó ´Ù¿î Åø¹Ù¸¦ ¿¸é WM_NOTIFY ÅëÁö ¸Þ½ÃÁö°¡ Àü´ÞµÇ´Âµ¥ ÀÌ ¸Þ½ÃÁö¸¦ ¹Þ¾ÒÀ» ¶§ ÆíÁý ±â·ÏÀ» º¸¿©ÁØ´Ù.
static HWND hEdRecDlg;
void OnNotify(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
....
switch (hdr->code) {
case TTN_GETDISPINFO:
....
case TBN_DROPDOWN:
hEdRecDlg=CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_EDITRECORD),
hWnd, (DLGPROC)EditRecordProc,((NMTOOLBAR *)lParam)->iItem);
break;
}
}
ÆíÁý ±â·ÏÀ» Ç¥½ÃÇÏ´Â ÀÛÀº Æ˾÷ ´ëÈ»óÀÚ¸¦ ¸ðµ¨¸®½º·Î ¸¸µç´Ù. Æ÷Ä¿½º¸¦ ÀÒÀ¸¸é Áï½Ã »ç¶óÁ®¾ß ÇϹǷΠ¸ðµ¨¸®½º·Î ¸¸µé¾úÀ¸¸ç ¸ÞÀÎ ¸Þ½ÃÁö ·çÇÁ¿¡¼ ¸ðµ¨¸®½º ´ëÈ»óÀÚ·Î ¸Þ½ÃÁö¸¦ º¸³»¾ß ÇÑ´Ù.
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance
,LPSTR lpszCmdParam,int nCmdShow)
{
....
if ((!IsWindow(g_FindDlg) || !IsDialogMessage(g_FindDlg,&Message)) &&
(!IsWindow(hEdRecDlg) || !IsDialogMessage(hEdRecDlg,&Message)) ) {
if (!TranslateMDISysAccel(g_hMDIClient, &Message)) {
if (!TranslateAccelerator(hWnd,hAccel,&Message)) {
TranslateMessage(&Message);
DispatchMessage(&Message);
}
}
}
ÆíÁý ±â·Ï ÁßÀÇ ÅÇÀ̳ª °³Çà ÄÚµå µîÀ» ±×´ë·Î Ãâ·ÂÇÏ¸é ±×·¡ÇÈ ¹®ÀڷΠǥ½ÃµÇ¹Ç·Î ÀÌ Á¦¾î Äڵ带 ´«¿¡ º¸ÀÌ´Â ´Ù¸¥ ¹®ÀÚ·Î ´ëüÇؼ Ç¥½ÃÇÏ´Â °ÍÀÌ ´õ º¸±â¿¡ ÁÁ´Ù. ´ÙÀ½ ÇÔ¼ö¸¦ Util.cpp¿¡ ÀÛ¼ºÇÑ´Ù.
// Á¦¾îÄڵ带 ÀÐÀ» ¼ö ÀÖ´Â ¹®ÀÚ·Î º¯È¯ÇÑ´Ù.
void ReplaceCtrlString(TCHAR *src, int slen, TCHAR *dest, int dlen)
{
TCHAR *s,*d;
TCHAR *dest2;
s=src;
if (dest==NULL) {
d=dest2=(TCHAR *)malloc(1024);
dlen=1024;
} else {
d=dest;
}
memset(d,0,dlen);
for (;*s;d++, s++) {
if (s-src >= slen) {
break;
}
if ((dest && d-dest >= dlen-1) || (dest==NULL && d-dest2 >= dlen-1)) {
break;
}
if (*s == '\r' && s-src+1 < slen && s[1] == '\n') {
lstrcat(d,"[°³Çà]");
d+=5;
s++;
} else if (*s == '\t') {
lstrcat(d,"[ÅÇ]");
d+=3;
} else {
if (IsDBCSLeadByte(*s)) {
*d++=*s++;
*d=*s;
} else {
if (*s >= 0x20 && *s <= 0x7e) {
*d=*s;
} else {
*d='.';
}
}
}
}
if (dest==NULL) {
lstrcpy(src,dest2);
free(dest2);
}
}
ReplaceCtrlString ÇÔ¼ö´Â ÅÇ, °³Çà Äڵ带 ÀÐÀ» ¼ö ÀÖ´Â ¹®ÀÚ¿·Î º¯°æÇÏ¸ç ±× ¿ÜÀÇ ÀμâÇÒ ¼ö ¾ø´Â Á¦¾î ÄÚµå´Â .À¸·Î Ç¥½ÃÇÑ´Ù. ÀÌÁø ÆÄÀÏÀ» ´Ù·ê ¼ö Àֱ⠶§¹®¿¡ ÀÓÀÇÀÇ ¹®ÀÚ Äڵ尡 ¿Ã ¼ö ÀÖÀ¸¹Ç·Î ¸ðµç Äڵ忡 ´ëÇØ ´«¿¡ º¸ÀÌ´Â ¹®ÀÚ¿·Î º¯È¯ÇØ¾ß ÇÑ´Ù. src¸¦ º¯È¯ÇÏ¿© dest¿¡ º¹»çÇ쵂 dest°¡ NULLÀ̸é Àӽà ¹öÆÛ¸¦ ÇÒ´çÇÏ¿© º¯È¯ÇÏ°í ±× °á°ú¸¦ ´Ù½Ã src¿¡ º¹»çÇÑ´Ù. À̶§ src´Â º¯È¯ ÈÄÀÇ ¹®ÀÚ¿À» ÀúÀåÇÒ ¼ö ÀÖÀ»¸¸Å ÃæºÐÇÑ ±æÀ̸¦ °¡Á®¾ß ÇÑ´Ù. È£ÃâÇÏ´Â Ãø¿¡¼´Â src¿Í dest¸¦ µ¿½Ã¿¡ Àü´ÞÇÏ¿© src¸¦ À¯ÁöÇÑ Ã¤·Î º¯È¯ °á°ú¸¦ ¹ÞÀ» ¼öµµ ÀÖ°í src¸¸ Àü´ÞÇÏ¿© º¯È¯ °á°ú¸¦ src¿¡ ´Ù½Ã ä¿ì°Ô ÇÒ ¼ö ÀÖ´Ù.
´ÙÀ½Àº ÆíÁý ±â·Ï ´ëÈ»óÀÚ ÇÁ·Î½ÃÀú¸¦ ÀÛ¼ºÇÑ´Ù. ÀÌ ´ëÈ»óÀÚ´Â Ãë¼Ò ¹× Àç½ÇÇà ¹öÆ° µÑ ´Ù¿¡ ´ëÇØ µ¿ÀÛÇϴµ¥ lParamÀ¸·Î Åø¹Ù ¹öÆ°ÀÇ ID¸¦ Àü´Þ¹Þ¾Æ ´·¯Áø ¹öÆ°¿¡ µû¶ó ¸ñ·ÏÀ» ´Ù¸£°Ô ÀÛ¼ºÇÑ´Ù. ¾îÂ÷ÇÇ µÑ ´Ù Ãë¼Ò ·¹ÄÚµåÀÇ ¸ñ·ÏÀ» Ç¥½ÃÇϹǷΠÃâ·Â °úÁ¤Àº °ÅÀÇ ºñ½ÁÇÒ °ÍÀÌ´Ù.
BOOL CALLBACK EditRecordProc(HWND hDlg,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
static BOOL bUndo;
static HWND hList;
RECT rt;
LVCOLUMN COL;
SInfo *pSi;
HWND hActive;
int idx, count, Inc, idx2;
UndoRecord *pUR;
LVITEM LI;
TCHAR szAct[12], szCon[1024];
switch(iMessage) {
case WM_INITDIALOG:
if (lParam == IDM_EDIT_UNDO) {
bUndo=TRUE;
Inc=-1;
SetDlgItemText(hDlg,IDC_MULTIUR,"¼±Åà µ¿ÀÛ±îÁö Ãë¼Ò");
} else {
bUndo=FALSE;
Inc=1;
SetDlgItemText(hDlg,IDC_MULTIUR,"¼±Åà µ¿ÀÛ±îÁö Àç½ÇÇà");
}
SendMessage(hToolBar,TB_GETITEMRECT,bUndo ? 8:9,(LPARAM)&rt);
rt.top=rt.bottom+2;
ClientToScreen(g_hFrameWnd,(LPPOINT)&rt);
SetWindowPos(hDlg,HWND_NOTOPMOST,rt.left,
rt.top,0,0,SWP_NOSIZE);
hList=GetDlgItem(hDlg,IDC_UNDOLIST);
COL.mask=LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
COL.fmt=LVCFMT_LEFT;
COL.cx=40;
COL.pszText="µ¿ÀÛ";
COL.iSubItem=0;
ListView_InsertColumn(hList,0,&COL);
COL.cx=145;
COL.pszText="³»¿ë";
COL.iSubItem=1;
ListView_InsertColumn(hList,1,&COL);
ListView_SetExtendedListViewStyle(hList, LVS_EX_FULLROWSELECT);
hActive=(HWND)SendMessage(g_hMDIClient,WM_MDIGETACTIVE,0,NULL);
pSi=(SInfo *)GetWindowLong(hActive,0);
for (idx=pSi->Ae.nowur, count=0;;idx+=Inc) {
pUR=&pSi->Ae.pUR[idx];
if (bUndo) {
if (pUR->action == UR_NONE || pUR->status == UR_CANCELED)
continue;
} else {
if (pUR->action == UR_NONE)
break;
}
if (bUndo && pUR->action != UR_GROUP && pUR->tick) {
for (;idx >= 0;idx--) {
if (pSi->Ae.pUR[idx].action==UR_GROUP && pSi->Ae.pUR[idx].tick==pUR->tick) {
break;
}
}
if (idx < 0) {
break;
}
switch (pSi->Ae.pUR[idx].pos) {
case 8:
case 9:
for (idx2=idx;;idx2++) {
if (pSi->Ae.pUR[idx2].action==UR_INSERT)
break;
}
lstrcpy(szAct,"»ðÀÔ");
ReplaceCtrlString(pSi->Ae.pUR[idx2].data,pSi->Ae.pUR[idx2].len,szCon,1024);
break;
default:
lstrcpy(szAct,"±×·ì");
lstrcpy(szCon,arGroupDesc[pSi->Ae.pUR[idx].pos]);
if (pSi->Ae.pUR[idx].data) {
lstrcat(szCon,pSi->Ae.pUR[idx].data);
}
break;
}
} else if (bUndo==FALSE && pUR->action == UR_GROUP) {
switch (pSi->Ae.pUR[idx].pos) {
case 8:
case 9:
for (idx2=idx;;idx2++) {
if (pSi->Ae.pUR[idx2].action==UR_INSERT)
break;
}
lstrcpy(szAct,"»ðÀÔ");
ReplaceCtrlString(pSi->Ae.pUR[idx2].data,pSi->Ae.pUR[idx2].len,szCon,1024);
break;
default:
lstrcpy(szAct,"±×·ì");
lstrcpy(szCon,arGroupDesc[pUR->pos]);
if (pUR->data) {
lstrcat(szCon,pUR->data);
}
break;
}
idx=pSi->Ae.FindGroupEnd(idx);
} else {
switch (pUR->action) {
case UR_INSERT:
lstrcpy(szAct,"»ðÀÔ");
ReplaceCtrlString(pUR->data,pUR->len,szCon,1024);
break;
case UR_DELETE:
lstrcpy(szAct,"»èÁ¦");
ReplaceCtrlString(pUR->data,pUR->len,szCon,1024);
break;
case UR_MOVE:
lstrcpy(szAct,"À̵¿");
wsprintf(szCon,"%d -> %d(%d¹ÙÀÌÆ®)",pUR->pos,pUR->dest[0],pUR->dest[1]);
break;
}
}
LI.mask=LVIF_TEXT | LVIF_PARAM;
LI.iItem=count;
LI.iSubItem=0;
LI.lParam=idx;
LI.pszText=szAct;
ListView_InsertItem(hList,&LI);
ListView_SetItemText(hList,count,1,szCon);
if ((bUndo && idx == 0) || count == 200) {
break;
}
count++;
}
SetFocus(hList);
return FALSE;
case WM_ACTIVATE:
if (LOWORD(wParam) == WA_INACTIVE) {
PostMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDCANCEL,0),0);
return TRUE;
}
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDC_MULTIUR:
idx=ListView_GetNextItem(hList,-1,LVNI_ALL | LVNI_SELECTED);
if (idx != -1) {
LI.mask=LVIF_PARAM;
LI.iItem=idx;
ListView_GetItem(hList,&LI);
PostMessage(g_hFrameWnd,WM_USER+3,(WPARAM)bUndo,(LPARAM)LI.lParam);
}
case IDCANCEL:
DestroyWindow(hDlg);
return FALSE;
}
return FALSE;
case WM_NOTIFY:
LPNMHDR hdr;
hdr=(LPNMHDR)lParam;
if (hdr->hwndFrom == hList) {
switch (hdr->code) {
case NM_DBLCLK:
PostMessage(hDlg,WM_COMMAND,MAKEWPARAM(IDC_MULTIUR,0),0);
return TRUE;
}
}
break;
}
return FALSE;
}
´ëÈ»óÀÚ°¡ ¿¸± ¶§ lParamÀ¸·Î ¾î¶² Åø ¹öÆ°ÀÌ ´·¯Á³´ÂÁö ID¸¦ Àü´Þ¹Þ´Âµ¥ ÀÌ °ªÀ¸·ÎºÎÅÍ Ãë¼Ò ±â·ÏÀÎÁö, Àç½ÇÇà ±â·ÏÀÎÁö¸¦ ÆÇ´ÜÇÏ¿© bUndo ½ºÅÂƽ º¯¼ö¿¡ ÀúÀåÇÑ´Ù. WM_INITDIALOG¿¡¼ ¸®½ºÆ® ºä ÄÁÆ®·ÑÀ» ÃʱâÈÇÏ°í ÆíÁý ±â·ÏÀ» ¸®½ºÆ® ºä¿¡ Ãâ·ÂÇÑ´Ù. nowurºÎÅÍ ¼ø¼´ë·Î Ãë¼Ò ·¹Äڵ带 ÀÐ¾î ±× ³»¿ëÀ» ¸®½ºÆ® ºä¿¡ µî·ÏÇß´Ù.
¸ñ·ÏÀ» ä¿ì´Â ¹æ¹ýÀº bUndo¿¡ µû¶ó ´Þ¶óÁø´Ù. ÀÏ´Ü nowur¿¡¼ ¸ñ·ÏÀ» ÀÛ¼ºÇÒ ¹æÇâÀÌ ´Þ¶óÁö´Âµ¥ ÀÌ ¹æÇâÀº Incº¯¼ö°¡ ±â¾ïÇÑ´Ù. ¸ñ·ÏÀ» ä¿ì´Â for ·çÇÁ´Â nowur¿¡¼ ½ÃÀÛÇؼ Inc ¹æÇâÀ¸·Î Áõ°¨ÇÏ¸é¼ ¾Æ·¡ À§·Î À̵¿ÇÏ¸ç ¹ß°ßµÇ´Â ·¹Äڵ带 ¸®½ºÆ® ºä¿¡ ä¿î´Ù. Ãë¼Ò ¸ñ·ÏÀÎ °æ¿ì´Â ÀÌ¹Ì Ãë¼ÒµÈ ·¹Äڵ峪 ¾ÆÁ÷ ÀÛ¼ºµÇÁö ¾ÊÀº ·¹ÄÚµå´Â Ãë¼Ò ´ë»óÀÌ ¾Æ´Ï¹Ç·Î Ãë¼Ò °¡´ÉÇÑ ¸ñ·ÏÀ» ¸¸³¯ ¶§±îÁö °è¼Ó ·çÇÁÀÇ ¼±µÎ·Î º¸³»±â¸¸ ÇÑ´Ù. Àç½ÇÇà ¸ñ·ÏÀÎ °æ¿ì UR_NONEÀ» ¸¸³ª¸é ¸ñ·ÏÀÇ ³¡À̹ǷΠÀ̶§ ·çÇÁ¸¦ Á¾·áÇÑ´Ù.
±×·ì ·¹Äڵ带 ó¸®ÇÏ´Â ¹æ¹ýµµ »ó´çÈ÷ ´Ù¸£´Ù. Ãë¼Ò ¸ñ·ÏÀÇ °æ¿ì ±×·ì ¿ä¼Ò°¡ ³ªÅ¸³ª¸é ÀÏ´Ü ±×·ì Çì´õ¸¦ ã¾Æ Çì´õÀÇ ¼³¸íÀ» ÃëÇÑ´Ù. ´Ü, Ãë¼Ò ·¹ÄÚµå °³¼ö °ü¸® ±â´É¿¡ ÀÇÇØ ¿ä¼Ò¸¸ ³²°í Çì´õ´Â Àß·Á ³ª°£ °æ¿ì°¡ ÀÖÀ» ¼ö Àִµ¥ À̶§´Â ¸ñ·Ï ÀÛ¼ºÀ» ³¡³½´Ù. ±×·ì Çì´õÀÇ id°¡ 8, 9¹ø Áï µé¿©¾²±âÀÎ °æ¿ì´Â µé¿©¾²±â ÈÄ¿¡ »ðÀÔµÈ ¹®ÀÚ¿°ú ÇÔ²² »ðÀÔÀ¸·Î ó¸®ÇÏ°í ³ª¸ÓÁö ±×·ìÀº "±×·ì" µ¿ÀÛÀÇ ¼³¸í ¹®ÀÚ¿À» ³»¿ëÀ¸·Î ÃëÇÑ´Ù. Àç½ÇÇà ¸ñ·ÏÀÇ °æ¿ì ±×·ì Çì´õ¸¦ ¸ÕÀú ¸¸³ª´Âµ¥ À̶§´Â Çì´õÀÇ ¼³¸íÀ» ÃëÇÏ°í ±×·ìÀÇ ³¡À¸·Î À̵¿ÇÑ´Ù. ´ÙÀ½ ·çÇÁ¿¡¼ idx¸¦ 1Áõ°¡½ÃÅ°¹Ç·Î Á¤È®ÇÏ°Ô ±×·ì ´ÙÀ½ ·¹ÄÚµåºÎÅÍ ¸ñ·ÏÀ» ÀÛ¼ºÇÏ°Ô µÉ °ÍÀÌ´Ù.
±×·ìÀÌ ¾Æ´Ñ »ðÀÔ, »èÁ¦, À̵¿ ·¹Äڵ忡 ´ëÇÑ ¸ñ·Ï ÀÛ¼ºÀº ¾ÆÁÖ Á÷°üÀûÀÌ´Ù. ¼³¸íÀ» °¢°¢ "»ðÀÔ", "»èÁ¦","À̵¿"À¸·Î ÀÛ¼ºÇÏ°í »ðÀÔ, »èÁ¦µÈ ¹®ÀÚ¿À» ReplaceCtrlStringÀ¸·Î Á¦¾î Äڵ带 ó¸®ÇÑ ÈÄ ¸®½ºÆ® ºä¿¡ Ãß°¡ÇÏ°í À̵¿ÀÎ °æ¿ì´Â ¾îµð¼ºÎÅÍ ¾îµð±îÁö ¸î ¹ÙÀÌÆ®¸¦ À̵¿Çß´ÂÁö¸¦ Ç¥½ÃÇÑ´Ù. ¸®½ºÆ® ºä¿¡ Ç׸ñÀ» Ãß°¡ÇÑ ÈÄ ·çÇÁ ³¡ Á¡°ËÀ» Çϴµ¥ Ãë¼Ò ¸ñ·Ï¿¡¼ ·¹ÄÚµåÀÇ Ã³À½À» ¸¸³µ°Å³ª ÃÖ´ë °³¼ö°¡ 200°³¸¦ ³ÑÀ¸¸é ·çÇÁ¸¦ Á¾·áÇÑ´Ù. ÃÖ´ë 200°³±îÁöÀÇ µ¿ÀÛÀ» ÇѲ¨¹ø¿¡ Ãë¼ÒÇÒ ¼ö ÀÖ´Ù´Â ¶æÀÌ´Ù.
»ç¿ëÀÚ´Â ÆíÁý ±â·Ï ´ëÈ»óÀÚ¿¡¼ ÆíÁý ±â·ÏÀ» »ìÆì º¸°í ¾îµð±îÁö Ãë¼Ò ¶Ç´Â Àç½ÇÇàÀ» ÇÒ °ÍÀΰ¡¸¦ ¼±ÅÃÇÒ ¼ö ÀÖ´Ù. »ç¿ëÀÚ°¡ ¸ñ·ÏÀ» ´õºí Ŭ¸¯Çϰųª Ãë¼Ò ¹öÆ°À» ´©¸£¸é WM_USER+3 ¸Þ½ÃÁö¸¦ ºÎ¸ð À©µµ¿ìÀÇ ¸Þ½ÃÁö Å¥¿¡ ºÙÀδÙ. À̶§ wParamÀ¸·Î´Â Ãë¼ÒÀÎÁö Àç½ÇÇàÀÎÁö¸¦ ¾Ë¸®´Â bUndoÀÇ °ªÀÌ Àü´ÞµÇ°í lParamÀ¸·Î´Â ¸®½ºÆ®ºä¿¡¼ ¼±ÅÃµÈ ·¹ÄÚµåÀÇ À妽º¸¦ Àü´ÞÇÑ´Ù. SendMessage·Î ¸Þ½ÃÁö¸¦ º¸³»Áö ¾Ê°í PostMessage·Î ºÙÀÌ´Â ÀÌÀ¯´Â ÀÏ´Ü ÀÌ ´ëÈ»óÀÚ¸¦ ´ÝÀº ÈÄ¿¡ Ãë¼Ò ¹× Àç½ÇÇàÀ» ÇØ¾ß Çϱ⠶§¹®ÀÌ´Ù. ±×·¡¼ case IDC_MULTIUR: ´ÙÀ½¿¡´Â break°¡ ¾ø´Ù.
ÆíÁý ±â·Ï ´ëÈ»óÀÚ´Â ¸ðµ¨¸®½º·Î ¿¸®´Âµ¥ »ç¿ëÀÚ°¡ ¹Ýµå½Ã Ãë¼Ò ¹× Àç½ÇÇàÀ» Çϱâ À§Çؼ¸¸ ¿©´Â °ÍÀº ¾Æ´Ï´Ù. ¶§·Î´Â ¾î¶² ÆíÁýÀ» Çß´ÂÁö È®Àθ¸ Çϱâ À§ÇØ ¿ ¼öµµ ÀÖÀ¸¹Ç·Î ÀÚ½ÅÀÌ ºñÈ°¼ºÈµÇ¸é Áï½Ã âÀ» ´Ý¾Æ¾ß ÇÑ´Ù. ±×·¡¼ WM_ACTIVATE¿¡¼ ºñÈ°¼ºÈµÉ ¶§ Àڽſ¡°Ô IDCANCEL ¸Þ½ÃÁö¸¦ ó¸®ÇÏ¿© ´ëÈ»óÀÚ¸¦ ´Ý´Â´Ù. WM_ACTIVATE¿¡¼ ¹Ù·Î DestroyWindow·Î ÀÚ±â ÀÚ½ÅÀ» Æı«ÇØ ¹ö¸®¸é ¸ÞÀÎ À©µµ¿ì°¡ È°¼ºÈµÇÁö ¾ÊÀ¸¹Ç·Î ¹Ýµå½Ã IDCANCEL À» Å¥¿¡ ºÙ¿© Á¤»óÀûÀÎ °úÁ¤À¸·Î Æı«ÇØ¾ß ÇÑ´Ù. ¸ÞÀÎ À©µµ¿ì´Â ÀÌ ´ëÈ»óÀÚ°¡ º¸³»´Â WM_USER+3 ¸Þ½ÃÁö¸¦ ó¸®ÇÑ´Ù.
LRESULT CALLBACK DGWndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)
{
switch(iMessage) {
....
case WM_USER+3:OnUser3(hWnd,wParam,lParam);return 0;
}
return(DefFrameProc(hWnd,g_hMDIClient,iMessage,wParam,lParam));
}
void OnUser3(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
SInfo *pSi;
HWND hActive;
hActive=(HWND)SendMessage(g_hMDIClient, WM_MDIGETACTIVE,0,NULL);
if (hActive) {
pSi=(SInfo *)GetWindowLong(hActive,0);
if (wParam == TRUE) {
pSi->Ae.MultiUndo(lParam);
} else {
pSi->Ae.MultiRedo(lParam);
}
}
}
wParam°ª¿¡ µû¶ó MultiUndo ¶Ç´Â MultiRedo ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. Ãë¼Ò ¹× Àç½ÇÇà ´ë»ó ·¹ÄÚµåÀÇ À妽º´Â lParamÀ¸·Î Àü´ÞµÇ¹Ç·Î ÀÌ °ªÀ» Àμö·Î ±×´ë·Î Àü´ÞÇÏ¸é µÈ´Ù.