´ëºÎºÐÀÇ ¸ÞÀÎ À©µµ¿ì¿¡´Â µµ±¸¸ðÀ½ÀÌ ÀÖ¾î WM_DESTROY¸Þ¼¼Áö Çڵ鷯¿¡¼´Â ´ÜÁöPostQuitMessage()¸¦ È£ÃâÇϰí ÀÖ½À´Ï´Ù. ±×·±µ¥ Áö±Ý±îÁö ó·³ CWindowImplŬ·¡½º¸¦ ¸ÞÀÎ À©µµ¿ìÀÇ base class·Î¼ »ç¿ëÇϸé, ¸Åȸ ½º½º·ÎCWndClassInfo±¸Á¶Ã¼¸¦ Ä¿½ºÅ͸¶ÀÌÁî ÇØ ¸Þ´º ÀÚ¿øÀ» ¼³Á¤Çϰųª ¸Þ¼¼Áö ¸Ê¿¡WM_DESTROY¸Þ¼¼Áö¿ëÀÇ ¿£Æ®¸®¸¦ Ãß°¡ÇØ PostQuitMessage()¸¦ È£ÃâÇϱâ À§ÇØ WM_DESTROY¸Þ¼¼Áö Çڵ鷯¸¦ ¾²Áö ¾ÊÀ¸¸é ¾ÈµË´Ï´Ù.
¡¡WTLÀº ÀÌ·¯ÇÑ ±âº»ÀûÀÎ ±â´ÉÀ» °¡Áö´Â À©µµ¿ì¸¦ °£´ÜÇÏ°Ô ¸¸µé±â À§Çؼ CFrameWindowImpl¶ó°í Çϴ Ŭ·¡½º¸¦ ÁغñÇØ ÀÖ½À´Ï´Ù. CFrameWindowImpl(¶Ç´Â ±× base classÀÌ´Ù FrameWindowImplBase) Ŭ·¡½º¿¡´Â WM_DESTROY¸Þ¼¼Áö¿ëÀÇ µðÆúÆ®ÀÇ Çڵ鷯°¡ ÁغñµÇ¾î ÀÖ´Â °Í ¿Ü À©µµ¿ì »çÀÌÁî°¡ º¯°æµÇ¾úÀ» ¶§¿¡ ÀÚµ¿ÀûÀ¸·Î ·¹À̾ƿôÀ» Á¶Á¤ÇÏ´ÂWM_SIZE¸Þ¼¼Áö Çڵ鷯 Åø¹Ù³ª »óÅ ¹Ù¸¦ ÀÛ¼ºÇÏ´Â ÇÔ¼ö Űº¸µå °¡¼Ó±â¿ëÀÇ Äڵ峪 Åø ÆÁ¿ëÀÇ ¸Þ¼¼Áö Çڵ鷯µîÀÌ °®ÃçÁ® ÀÖ½À´Ï´Ù. ±×¸®°í µµ±¸¸ðÀ½µîÀÇ ÀÚ¿øÀ» °£´ÜÇÏ°Ô ¼³Á¤ÇÏ´Â ¸ÅÅ©·Î¸¦ ¼Æ÷Æ®Çϰí ÀÖ½À´Ï´Ù.
¡¡¿©±â¿¡¼´Â ÀüȸÀÇ pop-up menu¸¦ Ãß°¡ÇÑ ¡¸Hello, ATL/WTL¡¹ÇÁ·Î±×·¥ÀÇ base class¸¦ CWindowImpl·ÎºÎÅÍCFrameWindowImpl¿¡ º¯°æÇØ °íÃÄ ¾¹´Ï´Ù.

|
// stdafx.h¾È #include <atlbase.h> #include <atlapp.h> extern CAppModule _Module; #include <atlwin.h> #include <atlcrack.h> #include <atlmisc.h> #include <atlframe.h> // CFrameWindowImplŬ·¡½º¸¦ »ç¿ëÇϱâ À§ÇØ(¶§¹®¿¡) |
|
// MainWindow.h¾È // ¸ÞÀÎ
À©µµ¿ìÀÇ base class¸¦CFrameWindowImpl·Î
º¯°æ class CMyWindow : public CFrameWindowImpl<CMyWindow>, public CMessageFilter, public CIdleHandler { public: // À©µµ¿ì Ŭ·¡½º¸í , °øÅë ÀÚ¿øID,
½ºÅ¸ÀÏ , ¹è°æ»öÀ» µî·Ï
DECLARE_FRAME_WND_CLASS_EX(_T("Hello"), IDR_MAINFRAME,
CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS, COLOR_WINDOW) private: // ¸Þ¼¼Áö ÇÊÅÍ Ã³¸® virtual
BOOL PreTranslateMessage(MSG* pMsg){ // base classÀÇ °ÍPreTranslateMessageÀ»
È£ÃâÇÏ´Â return CFrameWindowImpl<CMyWindow>::PreTranslateMessage(pMsg); } // ¾ÆÀ̵¹ ó¸® virtual
BOOL OnIdle(){ return FALSE; } // ¸Þ¼¼Áö ¸Ê BEGIN_MSG_MAP_EX(CMyWindow) MSG_WM_PAINT(OnPaint)
MSG_WM_CONTEXTMENU(OnContextMenu)
MSG_WM_CREATE(OnCreate)
COMMAND_ID_HANDLER_EX(ID_MENUITEM_HELLO, OnMenuHello)
COMMAND_ID_HANDLER_EX(ID_MENUITEM_EXIT, OnMenuExit)
CHAIN_MSG_MAP(CFrameWindowImpl<CMyWindow>)
// CFrameWindowImplŬ·¡½º¿¡
üÀÎ END_MSG_MAP() void OnPaint(HDC /*hDC*/){ CPaintDC dc(m_hWnd); CRect rect; GetClientRect(rect); dc.DrawText(_T("Hello, ATL/WTL"), -1,
rect, DT_SINGLELINE | DT_CENTER |
DT_VCENTER); } void OnContextMenu(HWND hWnd, CPoint pt){ // [Shift]+[F10]۰¡ ¹Ð·ÈÀ» °æ¿ì´Â ÁÂÇ¥¸¦ Ŭ¶óÀÌ¾ðÆ® ¿µ¿ªÀÇ Á»óÀ¸·Î ¼³Á¤ if(pt.x == -1 && pt.y
== -1){
pt.SetPoint(0, 0);
ClientToScreen(&pt); } // ÁÂÇ¥°¡
Ŭ¶óÀÌ¾ðÆ® ¿µ¿ª³»ÀÇ °æ¿ì¸¸ pop-up menu¸¦ Ç¥½Ã CRect rc; GetClientRect(&rc); ClientToScreen(&rc); if(rc.PtInRect(pt)){
CMenu menuPopup;
menuPopup.LoadMenu(IDR_MENU_POPUP);
menuPopup.GetSubMenu(0).TrackPopupMenu(
TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON, pt.x,
pt.y, m_hWnd); }else{
SetMsgHandled(false); } } LRESULT OnCreate(LPCREATESTRUCT lpcs){ // ¸Þ½ÃÁö
·çÇÁ¿¡ ¸Þ¼¼Áö ÇÊÅÍ¿Í ¾ÆÀ̵¹ Çڵ鷯¸¦ Ãß°¡ CMessageLoop* pLoop = _Module.GetMessageLoop(); pLoop->AddMessageFilter(this); pLoop->AddIdleHandler(this); return 0; } void OnMenuHello(UINT uNotifyCode, int nID, HWND hWndCtl){ MessageBox(_T("Hello, ATL/WTL")); } void OnMenuExit(UINT uNotifyCode, int nID, HWND hWndCtl){ PostMessage(WM_CLOSE); } }; |
|
// hello.cpp³» #include "stdafx.h" #include "resource.h" #include "MainWindow.h" CAppModule _Module; int WINAPI _tWinMain(HINSTANCE
hInstance, HINSTANCE, LPTSTR lpCmdLine,
int nCmdShow) { _Module.Init(NULL,
hInstance); CMessageLoop
theLoop; _Module.AddMessageLoop(&theLoop); // µ¶ÀÚ À©µµ¿ì¸¦ ÀÛ¼º CMyWindow
wnd; wnd.CreateEx(); wnd.ShowWindow(nCmdShow); wnd.UpdateWindow(); int nRet = theLoop.Run(); _Module.RemoveMessageLoop(); _Module.Term(); return nRet; } |
¡¡¿ì¼± stdafx.h¾È¿¡¼´ÂCFrameWindowImplŬ·¡½º¸¦ »ç¿ëÇϱâ À§Çؼatlframe.hÇì´õ¸¦ ÀÎŬ·çµå ÇÕ´Ï´Ù.
¡¡´ÙÀ½¿¡ , ¸ÞÀÎ À©µµ¿ìÀÎCMyWindowŬ·¡½ºÀÇ base class¸¦ CWindowImplŬ·¡½º¿¡¼CFrameWindowImplŬ·¡½º¿¡ º¯°æÇÕ´Ï´Ù. CFrameWindowImplŬ·¡½ºµµCWindowImplŬ·¡½º¶§¿Í °°°Ô , 3°³ÀÇ ÅÛÇø´ Àμö¸¦ °¡Áý´Ï´Ù. ¿©±â¿¡¼´Â »ý·« °¡´ÉÇÑ Á¦2, 3ÅÛÇø´ Àμö¸¦ »ý·« ÇØ Á¦1ÅÛÇø´ Àμö¿¡ »ó¼Ó Ŭ·¡½ºÀÇ À̸§À» °Ç³×ÁÝ´Ï´Ù. µ¡ºÙ¿© µðÆúÆ®·Î Á¦2ÅÛÇø´ Àμö¿¡´ÂCWindow, Á¦3ÅÛÇø´ Àμö¿¡´Â À©µµ¿ì Ư¼ºÀ¸·Î¼CFrameWinTraits°¡ °Ç³×¹Þ½À´Ï´Ù. CFrameWinTraits(Àº)´ÂATLÀÇatlwin.hÇì´õ·Î ´ÙÀ½°ú °°ÀÌ Á¤Àǵǰí ÀÖ½À´Ï´Ù.
|
// atlwin.h³» typedef CWinTraits<WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN | WS_CLIPSIBLINGS, WS_EX_APPWINDOW |
WS_EX_WINDOWEDGE> CFrameWinTraits; |
¡¡CMyWindowŬ·¡½º¿¡¼´Â ¿ì¼± ÇÁ·¹ÀÓ À©µµ¿ì¿ëÀÇ À©µµ¿ì Ŭ·¡½º¸í µî·Ï ¸ÅÅ©·Î¸¦ »ç¿ëÇØ À©µµ¿ì Ŭ·¡½º¸í , ÀÚ¿øID, ½ºÅ¸ÀÏ , ¹è°æ»öÀ» µî·ÏÇϰí ÀÖ½À´Ï´Ù. ÀÌ ¶§ ÀÚ¿øIDÀº ÀÌÇÏÀÇ ÀÚ¿øÀ¸·Î °øÅëÀÔ´Ï´Ù.
Áï , ÀÌ·¯ÇÑ ÀÚ¿ø¿¡ °øÅëÀÇ ÀÚ¿øIDÀ» ºÙ¿© ±×ID¸¦DECLARE_FRAME_WND_CLASS_EX¸ÅÅ©·Î¿¡ ÀÇÇØ µî·ÏÇϸé CFrameWindowImplŬ·¡½º´Â ±×·¯ÇÑ ÀÚ¿øÀ» ÀÚµ¿ÀûÀ¸·Î À©µµ¿ì·Î ¼³Á¤ÇÕ´Ï´Ù. À̹ø ¿¹¿¡¼´Â °øÅë ÀÚ¿øIDÀ¸·Î¼IDR_MAINFRAME¸¦ »ç¿ëÇϱâ·Î Çß½À´Ï´Ù. ±×·±µ¥ ¾ÆÀÌÄÜ ÀÚ¿øÀ̳ª À©µµ¿ì ŸÀÌÆ²À» À§ÇÑ Ä³¸¯ÅÍ ¶óÀÎ ÀÚ¿øÀ» Ãß°¡ÇØ °¢°¢IDR_MAINFRAMEÀ̶ó°í ÇÏ´ÂIDÀ» ºÙÀÔ´Ï´Ù. ±×¸®°í µµ±¸¸ðÀ½À» À§ÇÑ ¸Þ´º ÀÚ¿øIDµµIDR_MAINFRAME·Î º¯°æÇÕ´Ï´Ù.

µ¡ºÙ¿© À̹ø ¿¹¿¡¼´Â Åø¹Ù³ª Űº¸µå °¡¼Ó±â´Â »ç¿ëÇÏÁö ¾Ê±â ¶§¹®¿¡ ±×°ÍÀ» À§ÇÑ ÀÚ¿øÀº Ãß°¡Çϰí ÀÖÁö ¾Ê½À´Ï´Ù.
¡¡´ÙÀ½¿¡ ¸Þ¼¼Áö ÇÊÅÍ¿¡¼´Â base classÀÎCFrameWindowImplŬ·¡½ºÀÇ °Í PreTranslateMessage()À» È£ÃâÇÕ´Ï´Ù. CFrameWindowImpl::PreTranslateMessage()´Â Űº¸µå °¡¼Ó±â¿ëÀ¸·Î ::TranslateAccelerator()¸¦ È£ÃâÇϰí ÀÖ½À´Ï´Ù. ÀÌÇÏ´Â ±× ¼Ò½ºÀÔ´Ï´Ù.
|
// atlframe.h¾È BOOL PreTranslateMessage(MSG*
pMsg) { if(m_hAccel != NULL && ::TranslateAccelerator(m_hWnd, m_hAccel, pMsg)) return TRUE; return
FALSE; } |
´Ù¸¸ À̹øÀº Űº¸µå °¡¼Ó±â¸¦ »ç¿ëÇÏÁö ¾Ê±â ¶§¹®¿¡ ³Ê¹« °ü°è ¾ø½À´Ï´Ù.
¡¡´ÙÀ½¿¡ ¸Þ¼¼Áö ¸Ê¿¡ base classÀÎCFrameWindowImplŬ·¡½º¿¡ üÀÎÀ» Ãß°¡ÇÕ´Ï´Ù. À̰Ϳ¡ ÀÇÇØ WM_DESTROY¸Þ¼¼Áö¿¡ ´ëÇÑ Ã³¸®´Â CMyWindowŬ·¡½º°¡ ¾Æ´Ï°í CFrameWindowImplŬ·¡½º¿¡ ¸Ã±æ ¼ö°¡ ÀÖÀ¸¹Ç·Î »ó±âÀÇ ¿ø½Ã ÄÚµå·ÎºÎÅÍ´Â WM_DESTROY¸Þ¼¼Áö Çڵ鷯¿ëÀÇ Äڵ带 »èÁ¦Çϰí ÀÖ½À´Ï´Ù.
¡¡¹°·Ð ½º½º·ÎWM_DESTROY¸Þ¼¼Áö Çڵ鷯¸¦ ÁغñÇØ °Å±â¿¡ ÀÚ½ÅÀÇ ¾îÇø®ÄÉÀÌ¼Ç Æ¯À¯ÀÇ Ã³¸®¸¦ ´õÇÒ ¼ö°¡ ÀÖ½À´Ï´Ù. ±× °æ¿ì base classÀÎ CFrameWindowImplŬ·¡½º¿¡ ¸Þ¼¼Áö¸¦ º¸³»´Â °ÍÀ» Àؾ ¾ÈµË´Ï´Ù. ±×·¸°Ô ÇÏÁö ¾ÊÀ¸¸é ÃÖÁ¾ÀûÀ¸·Î ::PostQuitMessage()°¡ ºÒ·Á °¡Áö ¾Ê°í ÇÁ·Î±×·¥ÀÌ Á¾·áÇÏÁö ¾Ê±â ¶§¹®ÀÔ´Ï´Ù. ÀÌÇÏ´Â ½º½º·ÎWM_DESTROY¸Þ¼¼Áö Çڵ鷯¸¦ ÁغñÇßÀ» °æ¿ìÀÇ ÄÚµåÀÔ´Ï´Ù.
|
// MainWindow.h¾È class CMyWindow : public CFrameWindowImpl<CMyWindow>, public CMessageFilter, public CIdleHandler, public CUpdateUI<CMyWindow> { ... // ¸Þ¼¼Áö ¸Ê BEGIN_MSG_MAP_EX(CMyWindow)
MSG_WM_DESTROY(OnDestroy)
...
... CHAIN_MSG_MAP(CFrameWindowImpl<CMyWindow>)
// CFrameWindowImplŬ·¡½º¿¡
üÀÎ END_MSG_MAP() ... ... void OnDestroy(){ // ¾îÇø®ÄÉÀ̼Ç
ƯÀ¯ÀÇ Ã³¸®
... // ÀÌ ÇÔ¼ö
È£Ãâ¿¡ ÀÇÇØ ¸Þ¼¼Áö´Â üÀÎóÀÇ °ÍCFrameWindowImpl¿¡ º¸³»Áø´Ù SetMsgHandled(false); } } |
¡¡ÀÌ ¿¹¿¡¼´Â ¿ì¼± WM_DESTROY¸Þ¼¼Áö°¡ º¸³»Á® ¿À¸é CMyWindowŬ·¡½ºÀÇ ¸Þ¼¼Áö ¸ÊÀÇMSG_WM_DESTROY()¿£Æ®¸®¿¡ ÀÇÇØ CMyWindow::OnDestroy()°¡ ½ÇÇàµË´Ï´Ù. CMyWindow::OnDestroy()±×·³ ¾îÇø®ÄÉÀÌ¼Ç Æ¯À¯ÀÇ Ã³¸®¸¦ ÇÏ°í ³ª¼ SetMsgHandled(false)¸¦ È£ÃâÇÕ´Ï´Ù. ÀÌ È£Ãâ¿¡ ÀÇÇØ ÇÑÃþ ´õ ¸Þ¼¼Áö ¸Ê³»°¡ °Ë»öµÇ¾î WM_DESTROY¸Þ¼¼Áö´Â üÀο¡ ÀÇÇØ base classÀÎCFrameWindowImplŬ·¡½º¿¡ º¸³»Áý´Ï´Ù. CFrameWindowImplŬ·¡½º³»¿¡¼´Â ÇÑÃþ ´õ üÀο¡ ÀÇÇØ base classÀÎCFrameWindowImplBaseŬ·¡½º¿¡ º¸³»Á® ÃÖÁ¾ÀûÀ¸·ÎCFrameWindowImplBaseŬ·¡½ºÀÇWM_DESTROY¸Þ¼¼Áö Çڵ鷯·Î ::PostQuitMessage()°¡ ºÒ·Á °¡ ¾îÇø®ÄÉÀ̼ÇÀº Á¾·áÇÕ´Ï´Ù.
¡¡_tWinMain()´Â À©µµ¿ì¸¦ ÀÛ¼ºÇϱâ À§ÇؼCreateEx()¸¦ »ç¿ëÇϰí ÀÖ½À´Ï´Ù. CFrameWindowImplŬ·¡½º´ÂCreate()µµ ÁغñÇØ ÀÖ½À´Ï´Ù¸¸ °øÅë ÀÚ¿øID¿¡ ÀÇÇØ ÀÚµ¿ÀûÀ¸·Î ÀÚ¿øÀ» ¼³Á¤ÇÏ·Á¸é CreateEx()¸¦ »ç¿ëÇÒ Çʿ䰡 ÀÖ½À´Ï´Ù.