MFC·Î 'ÀÚµ¿ µé¿©¾²±â' ³ëÆ®ÆÐµå ¸¸µé±â
¿ª½Ã ¸¶ÀÌÅ©·Î¼ÒÇÁÆ® 97³â 3¿ùÈ£¿¡ ½Ç¸° ³»¿ëÀÔ´Ï´Ù. ¿¹Á¦ ÇÁ·ÎÁ§Æ®´Â ¿©±â¼..
ÇöÀç Ä¿¼ÀÇ ¶óÀΰú Ä÷³, ¼öÁ¤µÈ ¹®¼ Ç¥½Ã ±â´É, ÀÚµ¿ µé¿©¾²±â¸¦ ±¸ÇöÇÑ °£´ÜÇÑ ³ëÆ®Æе带 ¸¸µé¾î º¸±â·Î ÇÏÁö¿ä. CWinAppÀÇ OnIdle ÇÔ¼ö¸¦ ¿À¹ö¶óÀ̵åÇؼ À§ÀÇ ±â´ÉµéÀ» ±¸ÇöÇÑ °Ì´Ï´Ù. ´ÙÀ½Àº º»¹® ³»¿ë Áß ÀϺθ¦ ÀοëÇÑ °Ì´Ï´Ù.
ó¸®ÇÒ ¸Þ½ÃÁö°¡ ¾øÀ» ¶§ (¿¹ : ¸Þ½ÃÁö Å¥°¡ ºñ¾îÀÖÀ» ¶§) ÇÁ·¹ÀÓ¿÷Àº CWinAppÀÇ ¸â¹öÇÔ¼öÀÎ OnIdle()À» È£ÃâÇϱ⠶§¹®¿¡ ¹é±×¶ó¿îµå ÀÛ¾÷À» ¼öÇàÇÏ·Á¸é ÀÌ ÇÔ¼ö¸¦ ¿À¹ö¶óÀ̵åÇÏ¸é µÈ´Ù. ±âº»ÀûÀ¸·Î OnIdle ÇÔ¼ö´Â Åø¹Ù ¹öÆ°À̳ª ¸Þ´º µî »ç¿ëÀÚ ÀÎÅÍÆäÀ̽º¿¡ °ü·ÃµÈ °´Ã¼ »óŸ¦ °»½ÅÇϰųª, ÇÁ·¹ÀÓ¿÷ÀÌ »ý¼ºÇÑ Àӽà °´Ã¼¸¦ Áö¿ì´Â µî ÀÌ°ÍÀú°ÍÀ» ÇÑ´Ù. À̶§ ÁÖÀÇÇÒ Á¡Àº ³Ê¹« ±ä ½Ã°£À» ¿äÇÏ´Â ÀÛ¾÷À» Idle ŸÀÓ¿¡ ó¸®Çϸé Àý´ë ¾ÈµÈ´Ù´Â °Í. Idle ŸÀÓ ÇÁ·Î¼¼½ÌÀÌ ³¡³¯ ¶§±îÁö ÇÁ·Î±×·¥Àº ¾Æ¹« Àϵµ ÇÒ ¼ö ¾ø±â ¶§¹®ÀÌ´Ù. ±×·¸°Ô µÇ¸é ÁÖ°´ÀÌ ÀüµµµÈ ¼ÀÀÌ µÇ°í ¸¸´Ù.
~~~~~~~~~~~
UI (User Interface)ºÎºÐ¿¡¼ Idle ŸÀÓ ÇÁ·Î¼¼½ÌÀ» ÀÀ¿ëÇÒ ¼ö ÀÖ´Â ºÐ¾ß°¡ ¾ÆÁÖ ¸¹´Ù. °¡·É ½Ã°è¿Í °°ÀÌ ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÇ´Â µ¿¾È Áö¼ÓÀûÀ¸·Î »óŸ¦ °»½ÅÇØ ÁÖ¾î¾ß ÇÏ´Â ÀÛ¾÷¿¡ À¯¿ëÇÏ°Ô »ç¿ëÇÒ ¼ö ÀÖÀ¸¸ç, °¢ °³ÀÎÀÇ Ã¢ÀǷ¿¡ µû¶ó¼ ´õ °·ÂÇÑ ±â´ÉÀ» ±¸»çÇÒ ¼ö ÀÖ´Ù.
±×·³ ÀÌÁ¦ ÇØ¾ß ÇÒ ÀÏ¿¡ ´ëÇØ ¸»ÇØ µå¸®ÁÒ.
1. MDI·Î ÇÁ·ÎÁ§Æ®¸¦ ¸¸µéµÇ AppWizard ¸¶Áö¸· ´Ü°è¿¡¼ CView¸¦ CEditView·Î ¹Ù²Ù¾î ÁÖ¾î¾ß ÇÕ´Ï´Ù. ÀÌ·¸°Ô¸¸ ÇÏ°í ÄÄÆÄÀÏÀ» Çصµ ±âº»ÀûÀÎ ¿¡µðÅÍ ±â´ÉÀº °¡Áö°í ÀÖÁÒ. ¿©±â¼ ÇÁ·ÎÁ§Æ® À̸§Àº Pad ·Î Çß½À´Ï´Ù.
2. MainFrm.cpp¿¡¼ ´ÙÀ½ ºÎºÐÀ» ã¾Æ ±½Àº ±Û¾¾ ºÎºÐÀ» Ãß°¡ÇÕ´Ï´Ù. ¿©±â¼ ÇÏ´Â ÀÛ¾÷Àº »óŹٿ¡ paneÀ» Çϳª Ãß°¡ÇÏ´Â °ÍÀÌ°í, ¿©±â¼ ¶óÀΰú Ä÷³À» Ãâ·ÂÇÕ´Ï´Ù.
static UINT indicators[] =
{
ID_SEPARATOR, //
status line indicator
ID_INDICATOR_INFO,
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
3. MainFrm.cpp ÆÄÀÏÀÇ ´ÙÀ½ºÎºÐµµ °íÃÄÁÝ´Ï´Ù. ¾Æ·¡ÀÇ ±½Àº ±Û¾¾ ºÎºÐ ÇÑ ÁÙ¸¸ Ãß°¡ÇÏ¸é µË´Ï´Ù.
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CMDIFrameWnd::OnCreate(lpCreateStruct)
== -1)
return
-1;
if (!m_wndToolBar.CreateEx(this,
TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
|
CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed
to create toolbar\n");
return
-1; // fail to create
}
if (!m_wndStatusBar.Create(this)
||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed
to create status bar\n");
return
-1; // fail to create
}
m_wndStatusBar.SetPaneInfo(1, ID_INDICATOR_INFO, SBPS_NORMAL, 100);
// TODO: Delete these three
lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
4. À§ÀÇ 2, 3 ¹ø¿¡¼ º¸¸é ID_INDICATOR_INFO¸¦ ¾Æ¹«µ¥µµ Á¤Àǵµ ÇÏÁö ¾Ê°í ±×³É ½á³ùÁÒ? ±×·³ Á¤ÀǸ¦ ÇØÁÖÁö¿ä ¹¹.. ¸®¼Ò½º ºä¿¡¼ String TableÀ» ¿¾îº¾´Ï´Ù. °Å±â´Ù ´ÙÀ½ ³»¿ëÀ» Ãß°¡ÇÏ´Â °ÅÁÒ.
ID : ID_INDICATOR_INFO
Caption : Ln 1, Col 1
Value ´Â Àû´çÈ÷ ¾Ë¾Æ¼ Á¤ÇØÁú °Ì´Ï´Ù. ´Ù¸¥ id¿Í Áߺ¹µÇÁö ¾Ê´Â Àû´çÇÑ °ª ¾Æ¹«°Å³ª »ó°üÀº ¾øÁö¿ä.
5. ºäÀÇ OnKeyDownÀ» ¿À¹ö¶óÀ̵å ÇÕ´Ï´Ù. ÀÌ ÇÔ¼ö¸¦ °íÄ¡´Â ÀÌÀ¯´Â ºä¿¡¼ ¿£ÅÍ°¡ ´·ÈÀ» ¶§ ÀÚµ¿ µé¿©¾²±â¸¦ Çϵµ·Ï ÇØÁÖ±â À§ÇؼÀÌÁÒ.
void CPadView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler
code here and/or call default
if(nChar == VK_RETURN) {
// ¿£ÅÍÅ°°¡ ´·ÁÁ³À» ¶§
((CPadApp
*)AfxGetApp())->m_bTabFlag = TRUE;
}
CEditView::OnKeyDown(nChar,
nRepCnt, nFlags);
}
6. ¾ÖÇø®ÄÉÀÌ¼Ç Å¬·¡½º¿¡ ´ÙÀ½ µÎ º¯¼ö¸¦ public ¼Ó¼ºÀ¸·Î Á¤ÀÇÇÕ´Ï´Ù. m_nTabCount ´Â ÇöÀç ¶óÀÎÀÇ ÅÇ ¼ö¸¦ °¡Áö°í ÀÖ´Â º¯¼öÀÌ°í, m_nTabFlag ´Â ¿£ÅÍÅ°°¡ ´·ÁÁ³´ÂÁöÀÇ ¿©ºÎ¸¦ ÀúÀåÇÏ´Â Ç÷¡±× º¯¼öÀÔ´Ï´Ù.
public:
int m_nTabCount;
BOOL m_bTabFlag;
7. ¸¶Áö¸·À¸·Î °¡Àå ÇÙ½ÉÀÌ µÇ´Â OnIdle ÇÔ¼ö ºÎºÐÀÔ´Ï´Ù.
BOOL CPadApp::OnIdle(LONG lCount)
{
// TODO: Add your specialized
code here and/or call the base class
static CMainFrame* pFrame
= (CMainFrame*)AfxGetMainWnd(); // ÇÁ·¹ÀÓ
static CStatusBar* pStatusBar
= // »óŹٿ¡ ´ëÇÑ Æ÷ÀÎÅÍ(CStatusBar*)pFrame->GetDescendantWindow(AFX_IDW_STATUS_BAR);
static CChildFrame* pChild;
// Â÷Àϵå ÇÁ·¹ÀÓ¿¡ ´ëÇÑ Æ÷ÀÎÅÍ
static CPadView* pView;
// ºä¿¡ ´ëÇÑ Æ÷ÀÎÅÍ
static CEdit* pEdit;
// ¿¡µðÆ® ÄÁÆ®·Ñ¿¡ ´ëÇÑ Æ÷ÀÎÅÍ
static CString str;
static int posStart; //
SelÀÇ ½ÃÀÛ ±ÛÀÚ À§Ä¡
static int posEnd; //
SelÀÇ ³¡ ±ÛÀÚ À§Ä¡
static int posFirst; //
¶óÀÎÀÇ Ã¹ ±ÛÀÚ À§Ä¡
static int posPrev; //
ÀÌÀü ±ÛÀÚ À§Ä¡, ¹®ÀÚ¿ÀÌ ¼±ÅÃµÈ °æ¿ì
//
¿ÞÂÊ ¹æÇâÀÎÁö ¿À¸¥ÂÊ ¹æÇâÀÎÁö ¾Ë±âÀ§ÇØ ÇÊ¿ä
static int nCurLine; //
ÇöÀç ¶óÀÎ ¼ö
static int nCurCol; //
ÇöÀç Ä÷³ ¼ö
static char buf[1024];
int i;
int n;
pChild = (CChildFrame*)pFrame->GetActiveFrame();
pView = (CPadView*)pChild->GetActiveView();
pEdit = &(pView->GetEditCtrl());
switch(lCount)
{
case 0:
case 1:
CWinApp::OnIdle(lCount);
return
TRUE;
case 2: // »óŹٿ¡ ¶óÀÎ ¼ö¿Í Ä÷³ ¼ö¸¦ Ç¥½ÃÇÑ´Ù.
if(!pStatusBar)
return TRUE;
if(!pEdit)
{
str.Format("Ln
??, Col ??");
pStatusBar->SetPaneText(1,
str);
return
TRUE;
}
pEdit->GetSel(posStart,
posEnd);
if(posStart
== posEnd) // ¹®ÀÚ¿ÀÌ ¼±ÅõÇÁö ¾Ê¾ÒÀ¸¸é...
{
posFirst
= pEdit->LineIndex();
nCurLine
= pEdit->LineFromChar() + 1;
nCurCol
= posStart - posFirst + 1;
posPrev
= posStart;
}
else
//
¹®ÀÚ¿ÀÌ ¼±ÅõŠÀÖÀ¸¸é
{
if(posStart
< posPrev) // ¿ÞÂÊ ¹æÇâÀ¸·Î ¼±ÅÃÇßÀ¸¸é
{
nCurLine
= pEdit->LineFromChar(posStart) + 1;
posFirst
= pEdit->LineIndex(nCurLine - 1);
nCurCol
= posStart - posFirst + 1; // ÇöÀç Ä÷³Àº
}
// ½ÃÀÛ ¹®ÀÚ À§Ä¡
else
// ¿À¸¥ÂÊ ¹æÇâÀ¸·Î ¼±ÅÃÇßÀ¸¸é
{
nCurLine
= pEdit->LineFromChar(posEnd) + 1;
posFirst
= pEdit->LineIndex(nCurLine - 1);
nCurCol
= posEnd - posFirst + 1; // ÇöÀç Ä÷³Àº
}
// ³¡ ¹®ÀÚ À§Ä¡
}
str.Format("Ln
%d, Col %d", nCurLine, nCurCol);
pStatusBar->SetPaneText(1,
str);
//
»óŹٿ¡ ÇöÀç ¶óÀÎ, Ä÷³ Ç¥½Ã
return
TRUE;
case 3: //
ÀÚµ¿ µé¿©¾²±â
if(!pEdit)
return TRUE;
pEdit->GetSel(posStart,
posEnd);
posFirst
= pEdit->LineIndex();
if((m_bTabFlag
== TRUE) && (posStart == posFirst))
{
for(i
= 0; i < m_nTabCount; i++) // ÀÌÀü ¶óÀÎÀÇ ÅÇ ¼ö¸¸Å
{
//
ÅÇÀ» ä¿î´Ù.
pEdit->ReplaceSel("\t");
}
m_nTabCount
= 0;
m_bTabFlag
= FALSE; //
´Ù½Ã Ç÷¡±×¸¦ °ÅÁþÀ¸·Î
}
else
// ÅÇ Ç÷¡±×°¡ °ÅÁþÀ̸é ÇöÀç ¶óÀÎÀ» Àоî¿Í¼
{
// ¾ÕÀÇ ÅÇ ¹®ÀÚ°¡
¸î °³ ÀÎÁö¸¦ °è»êÇÑ´Ù.
n
= pEdit->GetLine(pEdit->LineFromChar(), buf, 1024);
i
= 0;
while(i
< n && buf[i] == '\t') i++;
m_nTabCount
= i;
}
return TRUE;
case 4: //
ŸÀÌƲ¿¡ '*' Ç¥½Ã
if(!pEdit)
return FALSE;
if(pEdit->GetModify())
// ¹®¼°¡ º¯°æµÇ¾úÀ¸¸é
{
str
= pView->GetDocument()->GetTitle();
if(str.Right(1)
!= '*') // '*' Ç¥½Ã°¡ µÇ¾îÀÖÁö ¾ÊÀ¸¸é
{
str
+= '*';
pView->GetDocument()->SetTitle(str);
}
}
return
FALSE; // ´õ ÀÌ»ó Idle ŸÀÓ ÀÛ¾÷ÀÌ ¾øÀ½
}
return FALSE;
}