´ëºÎºÐÀÇ ¸ÞÀÎ À©µµ¿ì¿¡´Â µµ±¸¸ðÀ½ÀÌ ÀÖ¾î 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()¸¦ »ç¿ëÇÒ Çʿ䰡 ÀÖ½À´Ï´Ù.