WTLÀº Win32³ª MFC¿¡ ºñÇØ ¹®¼È°¡ °ÅÀÇ µÇ¾î ÀÖÁö ¾Ê¾Æ ÇнÀ¿¡ ¾î·Á¿òÀÌ ¸¹´Ù. ±×·¯³ª ÅÛÇø´ÀÌ´Ù º¸´Ï Çì´õ ÆÄÀÏ¿¡ ¼Ò½º°¡ ÀüºÎ °ø°³µÇ¾î ÀÖ¾î »ç½Ç ¾Æ¹« °Íµµ ¼û±âÁö ¾Ê´Â´Ù´Â ¸é¿¡¼ ºÐ¼®ÇØ º¸±â´Â ¿ÀÈ÷·Á ´õ ½±´Ù. ¼Ò½º¸¦ ºÐ¼®ÇØ º¸¸é ±¸Á¶¸¦ È®½ÇÈ÷ ¾Ë ¼ö ÀÖÀ¸¸ç °í±Þ ¹®¹ýµµ ¸Àº¼ ¼ö ÀÖ´Ù. ¹®Á¦°¡ »ý°Üµµ ¶óÀ̺귯¸® ¾ÈÀ¸·Î ÆÄ°í µé¾î°¡ µð¹ö±ëÀ» ÇÒ ¼ö ÀÖÀ¸´Ï ½Ã°£ÀÌ Á» °É¸®´õ¶óµµ ¹®Á¦¸¦ È®½ÇÈ÷ ÇØ°áÇÒ ¼ö ÀÖ´Ù.
°Ô´Ù°¡ ÃֽŠºñ½ºÅ¸ UIÀÇ Àû¿ë ¹æ¹ý±îÁö ¹ß ºü¸£°Ô ±¸°æÇÒ ¼ö ÀÖ¾î ¼Ò½º ºÐ¼®Àº »Ñ¸®Ä¥ ¼ö ¾ø´Â À¯È¤ÀÌ´Ù. ´Ü, ÀÌ·¸°Ô ¼Ò½º¸¦ ¸¶À½ ¸ÔÀº´ë·Î ÁÖ¹°·¯ º¸·Á¸é ±× ¼Ò½º¿¡¼ »ç¿ëÇÑ´Â ¹®¹ý°ú ±â¹Ý API ±¸Á¶¿¡ ´ëÇؼ ¾ÆÁÖ »ó¼¼ÇÏ°Ô Àß ¾Ë°í ÀÖ¾î¾ß ÇÑ´Ù. ¿©±â¼´Â óÀ½ ¸¸µç WTL ¿¹Á¦ÀÎ WTLFirst ¿¹Á¦¸¦ ÅëÇØ WTLÀÇ ³»ºÎ¸¦ ºÐ¼®ÇØ º¸ÀÚ. ¿£Æ®¸® Æ÷ÀÎÆ®´Â WTLFirst.cpp ÆÄÀÏ¿¡ ÀÖ´Ù. ÁÖ¼®À̳ª ASSERT´Â »©°í Á¤¸®ÇØ º¸¸é ´ÙÀ½°ú °°´Ù.
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
HRESULT hRes = ::CoInitialize(NULL);
AtlInitCommonControls(ICC_COOL_CLASSES | ICC_BAR_CLASSES);
hRes = _Module.Init(NULL, hInstance);
int nRet = Run(lpstrCmdLine, nCmdShow);
_Module.Term();
::CoUninitialize();
return nRet;
}
COM ¶óÀ̺귯¸®¿Í °øÅë ÄÁÆ®·ÑÀ» ÃʱâÈÇÑ´Ù. ±×¸®°í Àü¿ª °´Ã¼ÀÎ _ModuleÀÇ Init¸¦ È£ÃâÇÏ¿© ÀÀ¿ë ÇÁ·Î±×·¥À» ÃʱâÈÇÏ°í Run ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ÇÁ·Î±×·¥À» ½ÇÇàÇϸç TermÀ¸·Î Á¾·á ó¸®ÇÑ´Ù. _ModuleÀº ¼Ò½ºÀÇ »ó´Ü¿¡ ¼±¾ðµÇ¾î ÀÖÀ¸¸ç stdafx.h¿¡ extern ¼±¾ðµÇ¾î ÀÖ´Â Àü¿ª °´Ã¼ÀÌ´Ù.
CAppModule _Module;
MFCÀÇ theApp¿¡ ÇØ´çÇÏ´Â Àü¿ª °´Ã¼À̸ç ÀÀ¿ë ÇÁ·Î±×·¥ÀÇ ¿©·¯ °¡Áö ¼³Á¤ Á¤º¸¸¦ °¡Áø´Ù. CAppModule Ŭ·¡½º´Â atlapp.h Çì´õ ÆÄÀÏ¿¡ Á¤ÀǵǾî ÀÖ´Ù. ATLÀÇ COM ¼¹ö ¸ðµâÀ» Ç¥ÇöÇÏ´Â CComModule·ÎºÎÅÍ »ó¼Ó¹Þ¾Æ ÀÀ¿ë ÇÁ·Î±×·¥ Àüü¸¦ ´ëÇ¥ÇÑ´Ù. ¸Þ½ÃÁö ·çÇÁ¿Í ¼¼Æà º¯°æ µîÀÇ ÀÀ¿ë ÇÁ·Î±×·¥ Àü¿ªÀûÀÎ Á¤º¸¸¦ °ü¸®ÇÏ´Â ¿ªÇÒÀ» ÇÑ´Ù.
class CAppModule : public ATL::CComModule
{
public:
DWORD m_dwMainThreadID;
ATL::CSimpleMap<DWORD, CMessageLoop*>* m_pMsgLoopMap;
ATL::CSimpleArray<HWND>* m_pSettingChangeNotify;
Init¿Í Term ÇÔ¼ö´Â ÀÀ¿ë ÇÁ·Î±×·¥À» ÃʱâÈÇÏ°í Á¾·á ó¸®ÇÑ´Ù. ÇöÀç ½º·¹µåÀÇ ID¸¦ Á¶»çÇØ ³õ°í ¸Þ½ÃÁö ·çÇÁ °´Ã¼¸¦ ÀúÀåÇÒ ºó ¸Ê °´Ã¼¸¦ »ý¼ºÇØ µÎ´Â Á¤µµÀÇ °£´ÜÇÑ ÀÛ¾÷¸¸ ÇÑ´Ù.
HRESULT Init(ATL::_ATL_OBJMAP_ENTRY* pObjMap, HINSTANCE hInstance, const GUID* pLibID = NULL)
{
HRESULT hRet = CComModule::Init(pObjMap, hInstance, pLibID);
m_dwMainThreadID = ::GetCurrentThreadId();
typedef ATL::CSimpleMap<DWORD, CMessageLoop*> _mapClass;
m_pMsgLoopMap = NULL;
ATLTRY(m_pMsgLoopMap = new _mapClass);
m_pSettingChangeNotify = NULL;
return hRet;
}
void Term()
{
TermSettingChangeNotify();
delete m_pMsgLoopMap;
CComModule::Term();
}
ÀÀ¿ë ÇÁ·Î±×·¥À» ½ÇÇàÇÏ´Â ÁÖü´Â Run ÇÔ¼öÀ̸ç ÀÀ¿ë ÇÁ·Î±×·¥ ¸ðµâÀÇ _tWinMain ¹Ù·Î À§¿¡ Á¤ÀǵǾî ÀÖ´Ù. ÀÌ ÇÔ¼ö¿¡ ´ëÇÑ ¿øÇü ¼±¾ðÀÌ µû·Î ¾ø°í »ç¿ëÇϱâ Àü¿¡ Á¤ÀǸ¸ Çß´Ù´Â Á¡Àε¥ ÀÌ·± ±â¹ýÀº C¿¡¼³ª ¾²Áö C++¿¡¼´Â Àß ¾²Áö ¾Ê´Â °ÍÀÌ´Ù.
int Run(LPTSTR /*lpstrCmdLine*/ = NULL, int nCmdShow = SW_SHOWDEFAULT)
{
CMessageLoop theLoop;
_Module.AddMessageLoop(&theLoop);
CMainFrame wndMain;
if(wndMain.CreateEx() == NULL)
{
ATLTRACE(_T("Main window creation failed!\n"));
return 0;
}
wndMain.ShowWindow(nCmdShow);
int nRet = theLoop.Run();
_Module.RemoveMessageLoop();
return nRet;
}
¸Þ½ÃÁö ·çÇÁ °´Ã¼ Çϳª¸¦ »ý¼ºÇÏ¿© ¸ðµâ¿¡ Ãß°¡ÇÑ´Ù. ±×¸®°í ¸ÞÀÎ À©µµ¿ì °´Ã¼¸¦ »ý¼ºÇϴµ¥ ÀÌ °úÁ¤¿¡¼ ¸ÞÀÎ À©µµ¿ìÀÇ Â÷ÀϵåµéÀÌ ÁÙÁÙÀÌ »ý¼ºµÈ´Ù. Åø¹Ù, »óŶõÀÌ ºÙ°í ºä°¡ »ý¼ºµÇ¸ç ºäÀÇ Â÷Àϵåµéµµ À̶§ »ý¼ºµÉ °ÍÀÌ´Ù. ¸¸¾à ÀÌ °úÁ¤¿¡¼ Á¶±ÝÀÌ¶óµµ ¿¡·¯°¡ ¹ß»ýÇϸé ÀÀ¿ë ÇÁ·Î±×·¥Àº ¹Ù·Î Á¾·áµÈ´Ù. ¹«»çÈ÷ ÃʱâÈ°¡ ¿Ï·áµÇ¾úÀ¸¸é ¸Þ½ÃÁö ·çÇÁ °´Ã¼ÀÇ Run ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ¿î¿µÃ¼Á¦³ª »ç¿ëÀڷκÎÅÍ Àü´ÞµÇ´Â ¸Þ½ÃÁö¸¦ ó¸®ÇÑ´Ù.
int Run()
{
BOOL bDoIdle = TRUE;
int nIdleCount = 0;
BOOL bRet;
for(;;)
{
while(bDoIdle && !::PeekMessage(&m_msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!OnIdle(nIdleCount++))
bDoIdle = FALSE;
}
bRet = ::GetMessage(&m_msg, NULL, 0, 0);
if(bRet == -1)
{
ATLTRACE2(atlTraceUI, 0, _T("::GetMessage returned -1 (error)\n"));
continue; // error, don't process
}
else if(!bRet)
{
ATLTRACE2(atlTraceUI, 0, _T("CMessageLoop::Run - exiting\n"));
break; // WM_QUIT, exit message loop
}
if(!PreTranslateMessage(&m_msg))
{
::TranslateMessage(&m_msg);
::DispatchMessage(&m_msg);
}
if(IsIdleMessage(&m_msg))
{
bDoIdle = TRUE;
nIdleCount = 0;
}
}
return (int)m_msg.wParam;
}
OnIdle¿¡ ´ëÇÑ Ã³¸®¿Í PreTranslateMessage °¡»ó ÇÔ¼ö¸¦ È£ÃâÇÏ´Â Á¤µµ¸¦ »©°í ³ª¸é ±×³É ´Ü¼øÇÑ ¸Þ½ÃÁö ·çÇÁÀÏ »ÓÀÌ´Ù. MFC¿¡µµ ºñ½ÁÇÑ Çü½ÄÀÇ Run ¸Þ¼Òµå°¡ CWinThread¿¡ Á¤ÀǵǾî ÀÖ´Ù. ÀÌ ÇÔ¼ö´Â ÇüÅ»óÀ¸·Î ¹«ÇÑ ·çÇÁ·Î µÇ¾î ÀÖÀ¸¸ç ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ Á¾·áµÉ ¶§, Áï WM_QUIT°¡ Àü´ÞµÉ ¶§±îÁö °è¼Ó ½ÇÇàµÈ´Ù. ÀÌ ÇÔ¼ö°¡ ¸®ÅÏÇϸé ÀÀ¿ë ÇÁ·Î±×·¥ÀÌ Á¾·áµÈ´Ù.
CMainFrame°´Ã¼´Â ÀÀ¿ë ÇÁ·Î±×·¥ÀÇ ¸ÞÀÎ À©µµ¿ìÀÌ´Ù. Ŭ·¡½º ¼±¾ð¹®À» º¸¸é ¹«·Á 4Áß ´ÙÁß »ó¼ÓÀ» ¹Þ°í Àִµ¥ ¸ÞÀÎ À©µµ¿ìÀÇ ±â´É ´ëºÎºÐÀº CFrameWindowImpl ¹Í½ºÀÎÀ¸·ÎºÎÅÍ »ó¼Ó¹Þ´Â´Ù. ³ª¸ÓÁö ¼¼ °³ÀÇ ±â¹Ý Ŭ·¡½º´Â »ó¼ÓÀ̶ó±â º¸´Ù´Â ´Ü¼øÈ÷ ±â´ÉÀ» À§ÇÑ ÀÎÅÍÆäÀ̽º¸¸ Á¦°øÇÏ´Â °ÍÀÌ´Ù.
class CMainFrame : public CFrameWindowImpl<CMainFrame>, public CUpdateUI<CMainFrame>,
public CMessageFilter, public CIdleHandler
{
public:
//DECLARE_FRAME_WND_CLASS(NULL, IDR_MAINFRAME)
static WTL::CFrameWndClassInfo& GetWndClassInfo()
{
static WTL::CFrameWndClassInfo wc =
{
{ sizeof(WNDCLASSEX), 0, StartWindowProc,
0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, NULL, NULL },
NULL, NULL, IDC_ARROW, TRUE, 0, _T(""),MAINFRAME
};
return wc;
}
¼±¾ð¹® ¼±µÎ¿¡ DECLARE_FRAME_WND_CLASS¶ó´Â ¸ÅÅ©·Î°¡ Àִµ¥ Àü°³ÇØ º¸¸é À©µµ¿ì Ŭ·¡½ºÀÇ ¿©·¯ °¡Áö Á¤º¸¸¦ Á¤ÀÇÇÏ¿© ¸®ÅÏÇÏ´Â GetWndClassInfo¶ó´Â Á¤Àû ¸â¹ö ÇÔ¼ö¸¦ Á¤ÀÇÇÑ´Ù. ÀÌ ÇÔ¼ö°¡ ¸®ÅÏÇÏ´Â wc¿¡´Â Ŭ·¡½º À̸§, ¹è°æ»ö, Ä¿¼, ¸®¼Ò½º ID, ĸ¼Ç µîÀÇ Á¤º¸µéÀÌ ÀúÀåµÇ¾î ÀÖÀ¸¸ç ÀÌ Á¤º¸´Â ÀÌÈÄ À©µµ¿ì Ŭ·¡½º µî·ÏÀ̳ª À©µµ¿ì »ý¼º¿¡ »ç¿ëµÉ °ÍÀÌ´Ù.
HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
{
const int cchName = 256;
TCHAR szWindowName[cchName];
szWindowName[0] = 0;
::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
T* pT = static_cast<T*>(this);
HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
if(hWnd != NULL)
m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
return hWnd;
}
HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR szWindowName = NULL,
DWORD dwStyle = 0, DWORD dwExStyle = 0,
HMENU hMenu = NULL, LPVOID lpCreateParam = NULL)
{
ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc);
dwStyle = T::GetWndStyle(dwStyle);
dwExStyle = T::GetWndExStyle(dwExStyle);
if(rect.m_lpRect == NULL)
rect.m_lpRect = &TBase::rcDefault;
return CFrameWindowImplBase< TBase, TWinTraits >::Create(hWndParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam);
}
CreateEx ÇÔ¼ö´Â ¹®ÀÚ¿ ¸®¼Ò½º¿¡¼ À©µµ¿ì ĸ¼Ç, ¸Þ´º µîÀ» Àаí À©µµ¿ì¸¦ »ý¼ºÇÑ´Ù. Create ÇÔ¼ö¿¡¼ À©µµ¿ì Ŭ·¡½º¸¦ µî·ÏÇÏ°í ½ºÅ¸ÀÏÀ» Á¶»çÇÑ ÈÄ ¶Ç ´Ù¸¥ Create ÇÔ¼ö¸¦ È£ÃâÇϴµ¥ °á±¹ ÀÌ ¾È¿¡¼ CreateWindowEx API ÇÔ¼ö·Î À©µµ¿ì¸¦ »ý¼ºÇÑ´Ù. »ý¼º¿¡ ¼º°øÇÏ¸é ¿¢¼¿·¯·¹ÀÌÅͱîÁöµµ ¹Ì¸® ·ÎµåÇØ ³õ´Â´Ù. À©µµ¿ì°¡ »ý¼ºµÇ¸é ¸Þ½ÃÁö ·çÇÁ·Î ÁøÀÔÇÏ¿© ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÉ °ÍÀÌ´Ù.
WTLÀÇ ¸Þ½ÃÁö ¸ÊÀº MFCÀÇ ¸Þ½ÃÁö ¸Ê°ú ÇüÅ°¡ ºñ½ÁÇÏ´Ù. ±×·¯³ª ³»ºÎ ±¸Á¶´Â ¿ÏÀüÈ÷ ´Ù¸£´Ù. MFCÀÇ ¸Þ½ÃÁö ¸ÊÀº ¸Þ½ÃÁö¿Í Çڵ鷯ÀÇ ´ëÀÀ °ü°è¸¦ Á¤ÀÇÇÏ´Â ±¸Á¶Ã¼ ¹è¿ÀÌ¸ç ±¸Çö ÆÄÀÏ¿¡ Á¤ÀǵȴÙ. ÀÌ¿¡ ºñÇØ WTLÀÇ ¸Þ½ÃÁö ¸ÊÀº ¸Þ½ÃÁö·ÎºÎÅÍ Çڵ鷯¸¦ È£ÃâÇÏ´Â ÄÚµåÀ̸ç Çì´õ ÆÄÀÏ¿¡ Á¤ÀǵȴÙ. ¸ÞÀÎ ÇÁ·¹ÀÓÀÇ Çì´õ ÆÄÀÏÀ» º¸¸é ´ÙÀ½ ¸Þ½ÃÁö ¸ÊÀ» º¼ ¼ö ÀÖ´Ù.
BEGIN_MSG_MAP(CMainFrame)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
COMMAND_ID_HANDLER(ID_FILE_NEW, OnFileNew)
COMMAND_ID_HANDLER(ID_VIEW_TOOLBAR, OnViewToolBar)
COMMAND_ID_HANDLER(ID_VIEW_STATUS_BAR, OnViewStatusBar)
COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
CHAIN_MSG_MAP(CUpdateUI<CMainFrame>)
CHAIN_MSG_MAP(CFrameWindowImpl<CMainFrame>)
END_MSG_MAP()
¸¶¹ý»ç°¡ ¹Ì¸® ¸¸µç ¸Þ½ÃÁö Çڵ鷯¿Í ¸í·É Çڵ鷯, üÀÎ µîÀÌ Æ÷ÇԵǾî Àִµ¥ °£·«ÈÇÏ¿© ½ÇÁ¦ ÄÚµå·Î Àü°³ÇØ º¸ÀÚ. ¸Þ½ÃÁö ¸Ê¿¡ µÎ °³ÀÇ Ç׸ñ¸¸ ³²±â°í ÀÏ´ÜÀº »èÁ¦ÇÑ´Ù.
BEGIN_MSG_MAP(CMainFrame)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
END_MSG_MAP()
±×¸®°í ÀÌ ±¸¹®À» ±â°èÀûÀ¸·Î ġȯÇØ º¸¸é ´ÙÀ½ ÇÔ¼ö Çϳª°¡ Á¤ÀǵȴÙ. ½ÇÁ¦·Î ÀÌ ÇÔ¼ö·Î ġȯÇÑ Ã¤·Î ÄÄÆÄÀÏÇصµ Àß ½ÇÇàµÈ´Ù. WM_DESTROY¸¦ »©¼ Á¤»ó Á¾·á´Â ¾ÈµÇÁö¸¸ ¸»ÀÌ´Ù.
// BEGIN_MSG_MAP(CMainFrame)
BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0)
{
BOOL bHandled = TRUE;
switch(dwMsgMapID)
{
case 0:
//MESSAGE_HANDLER(WM_CREATE, OnCreate)
if(uMsg == WM_CREATE)
{
bHandled = TRUE;
lResult = OnCreate(uMsg, wParam, lParam, bHandled);
if(bHandled)
return TRUE;
}
//COMMAND_ID_HANDLER(ID_APP_EXIT, OnFileExit)
if(uMsg == WM_COMMAND && ID_APP_EXIT == LOWORD(wParam))
{
bHandled = TRUE;
lResult = OnFileExit(HIWORD(wParam), LOWORD(wParam), (HWND)lParam, bHandled);
if(bHandled)
return TRUE;
}
break;
//END_MSG_MAP()
default:
ATLTRACE(ATL::atlTraceWindowing, 0, _T("Invalid message map ID (%i)\n"), dwMsgMapID);
ATLASSERT(FALSE);
break;
}
return FALSE;
}
BEGIN_MSG_MAP ¸ÅÅ©·Î´Â ÇÔ¼öÀÇ ¼±µÎ¸¦ Á¤ÀÇÇÑ´Ù. ¸ðµç Çڵ鷯¿¡¼ °øÅëÀûÀ¸·Î »ç¿ëµÇ´Â bHandled º¯¼ö¸¦ ¼±¾ð ¹× TRUE·Î ÃʱâÈÇÏ°í ¸Þ½ÃÁö ¸Ê ID¿¡ µû¶ó ºÐ±âÇÑ´Ù. ¸Þ½ÃÁö ¸Ê ID´Â 0ÀÏ °æ¿ì ÇöÀç °´Ã¼ÀÇ ¸Þ½ÃÁö¸¦ ÀǹÌÇÑ´Ù. END_MSG_MAP() ¸ÅÅ©·Î´Â ÇÔ¼ö ¼±¾ð¹®À» Á¾·áÇÏ°í Ʋ¸° ¸Þ½ÃÁö ¸Ê ID¿¡ ´ëÇØ ¿¡·¯ ó¸®ÇÏ´Â ¿ªÇÒÀ» ÇÑ´Ù. ÀÌ µÎ ¸ÅÅ©·Î »çÀÌ¿¡ ¸Þ½ÃÁö ¸ÊÀÌ ÀÛ¼ºµÈ´Ù.
MESSAGE_HANDLER ¸ÅÅ©·Î´Â if¹®À¸·Î ¸Þ½ÃÁö ID¸¦ ºñ±³ÇØ º¸°í ¸Þ½ÃÁö¿¡ ´ëÀÀÇÏ´Â ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù. bHandled¸¦ ÂüÁ¶ Àμö·Î ³Ñ°Ü Çڵ鷯¿¡¼ ó¸®Çß´ÂÁö¸¦ Á¶»çÇÏ°í ±× °á°ú¸¦ ´Ù½Ã ¸®ÅÏÇÒ »ÓÀÌ´Ù. COMMAND_ID_HANDLER ¸ÅÅ©·Î´Â WM_COMMAND ¸Þ½ÃÁö¿¡ ´ëÇØ LOWORD(wParam)ÀÌ ¸í·É ID¿Í ÀÏÄ¡ÇÏ´ÂÁö º¸°í ¸í·É ID¿¡ ´ëÀÀÇÏ´Â ÇÔ¼ö¸¦ È£ÃâÇÑ´Ù.
¸Þ½ÃÁö ¸Ê ÇÔ¼ö´Â WTL³»ÀÇ ´ÙÀ½ ÇÔ¼ö°¡ È£ÃâÇÑ´Ù. ÀÌ ÇÔ¼ö´Â WTL³»¿¡¼ »ý¼ºµÇ´Â À©µµ¿ìÀÇ ¸Þ½ÃÁö ó¸® ÇÔ¼öÀÌ¸ç »ý¼º °úÁ¤¿¡¼ ´Ù¼Ò º¹ÀâÇÑ °úÁ¤À» ÅëÇØ ÀÌ ÇÔ¼ö°¡ À©µµ¿ì ÇÁ·Î½ÃÀú·Î ÁöÁ¤µÈ´Ù. Win32 ÇÁ·ÎÁ§Æ®ÀÇ WndProc¿¡ ÇØ´çÇÏ´Â ÇÔ¼ö¶ó°í »ý°¢ÇÏ¸é µÈ´Ù.
template <class TBase, class TWinTraits>
LRESULT CALLBACK CWindowImplBaseT< TBase, TWinTraits >::WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CWindowImplBaseT< TBase, TWinTraits >* pThis = (CWindowImplBaseT< TBase, TWinTraits >*)hWnd;
....
LRESULT lRes;
BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wParam, lParam, lRes, 0);
ÇÚµéÀ» °´Ã¼·Î º¯È¯ÇÑ ÈÄ °´Ã¼ÀÇ ProcessWindowMessage ÇÔ¼ö¸¦ È£ÃâÇÏ°í ÀÌ ÇÔ¼ö´Â ¸Þ½ÃÁö ¸Ê¿¡ µî·ÏµÈ Á¶°Ç¹®À» ¼ø¼´ë·Î Á¡°ËÇÏ¿© Çڵ鷯¸¦ È£ÃâÇÑ´Ù. ó¸® °á°ú¸¦ bRet·Î ¹Þ´Âµ¥ ÀÌ °ªÀº °¢ ¸Þ½ÃÁö Çڵ鷯°¡ ÂüÁ¶ È£Ãâ·Î ¸®ÅÏÇÏ´Â bHandled°ªÀÌ´Ù. bRet°¡ FALSEÀÌ¸é µðÆúÆ® ó¸®Ç쵂 WM_NCDESTROY°°Àº Ư¼öÇÑ ¸Þ½ÃÁö¸¦ Á¦¿ÜÇÏ°í´Â ´ëºÎºÐ DefWindowProcÀ¸·Î º¸³»Áø´Ù.
ÀÌ»óÀ¸·Î WTLÀÇ ³»ºÎ¸¦ ¾à°£, ¾ÆÁÖ »ì¦Äô µé¿©´Ù º¸¾Ò´Âµ¥ ¿©±â¼ WTL Àüü¸¦ ´Ù ºÐ¼®ÇØ º¸°íÀÚ ÇÏ´Â °ÍÀº ¾Æ´Ï´Ù. ¸¶À½ °°¾Æ¼´Â ¾ÈÂÊ ±íÀº °÷ÀÇ Äڵ带 ÈÖµü ±î µÚÁý¾î º¸¿© ÁÖ°í ½ÍÀº ¸¶À½ ±¼¶Ò°°Áö¸¸ ½Ã°£ÀÌ Çã¶ôÇÏÁö ¾ÊÀ½ÀÌ ¾ÈŸ±î¿ï »ÓÀÌ´Ù. ³ªµµ ³»ÀϱîÁö ´çÀå ÇØ°áÇØ¾ß ÇÒ ¹ö±× ¸ñ·ÏÀÌ ÀÜ¶à ½×¿© ÀÖ´Â °³¹ßÀÚÀÌ´Ù º¸´Ï ÇÑ°¡ÇÏ°Ô ±ÛÀ̳ª ¾²°í ÀÖÀ» ¿©À¯°¡ ¾ø´Ù. ÀÌ ¾û¸Á ÁøâÀÎ °Áµµ Á¤¸»ÀÌÁö ¾ø´Â ½Ã°£ ÂÉ°³ °¡¸ç ¾´ °ÍÀÌ´Ï ºÎÁ·ÇÑ ºÎºÐÀÌ ÀÖ´õ¶óµµ ¾çÇØÇØ Áֱ⠹ٶõ´Ù.
»ó¼¼ÇÑ ºÐ¼®À» ÇØ º¸Áö ¸øÇØ ¾Æ½±±â´Â Çѵ¥ ³ª´Â ´Ù¸¸ ÀÌ·± ½ÄÀ¸·Î ¾ÈÀ¸·Î Á¶±Ý¸¸ ÃßÀûÇØ µé¾î°¡ º¸¸é WTL ÀÚü¸¦ »ó¼¼ÇÏ°Ô Å½±¸ÇÒ ¼ö ÀÖ´Ù´Â °ÍÀ» ¾Ë·Á ÁÖ°í ½ÍÀ» »ÓÀÌ´Ù. ÀÌÈÄ ´©±º°¡°¡ ÀÌ °Á¸¦ ±âÃÊ·Î ÇÏ¿© WTL ³»ºÎ ±¸Á¶¸¦ ºÐ¼®ÇÑ °Á¸¦ ÀÛ¼ºÇØ ÁÖ¸é Âü °í¸¿°Ú´Ù. ÀÌ»óÀ¸·Î ºÎÁ·ÇÑ °Á¸¦ ¸¶Ä£´Ù.