¡¡WTL¿¡¼­ ¸Þ´º¸¦CMenuTÀ̶ó°í ÇÏ´Â ÅÛÇø´ Ŭ·¡½º¿¡¼­ ĸ½¶È­Çϰí ÀÖ½À´Ï´Ù. ÅÛÇø´ Àμö´Âbool°ªÀ¸·Î trueÀÇ °æ¿ì´Â ¼Ò¸êÀÚ·ÎDestroyMenu()¸¦ È£ÃâÇØ  falseÀÇ °æ¿ì´Â È£ÃâÇÏÁö ¾Ê½À´Ï´Ù. atluser.hÇì´õ¿¡¼­´Â typedef¿¡ ÀÇÇØ ´ÙÀ½°ú °°ÀÌ ¼±¾ðµÇ°í ÀÖ½À´Ï´Ù.

// atluser.h³»

typedef CMenuT<false>  CMenuHandle;

typedef CMenuT<true>   CMenu;

                      


¡¡WTLÀÇCMenuŬ·¡½º´ÂMFCÀÇ µ¿¸íÀÇ Å¬·¡½º¿Í µ¿µîÀÇ ±â´ÉÀ» °®Ãß°í ÀÖ½À´Ï´Ù. ¿©±â¿¡¼­´Â CMenuŬ·¡½º¸¦ »ç¿ëÇØ  ÀüȸÀÇ µµ±¸¸ðÀ½À» Ãß°¡ÇÑ ¡¸Hello, ATL/WTL¡¹ÇÁ·Î±×·¥¿¡ pop-up menu¸¦ Ãß°¡ÇÕ´Ï´Ù. ÀÌ ¿¹¿¡¼­´Â , Ŭ¶óÀÌ¾ðÆ® ¿µ¿ª¿¡¼­ ¿À¸¥ÂÊ Å¬¸¯ÇßÀ» ¶§¿¡  ¾Æ·¡ÀÇ ±×¸²°ú °°Àº pop-up menu°¡ Ç¥½ÃµÇµµ·Ï ÇÕ´Ï´Ù.

 

// stdafx.h³»

#include <atlbase.h>

#include <atlapp.h>

extern CAppModule _Module;

#include <atlwin.h>

 

#include <atlcrack.h>

#include <atlmisc.h>

                      

 

// MainWindow.h³»

class CMyWindow : public CWindowImpl<CMyWindow>,

    public CMessageFilter, public CIdleHandler

{

public:

    // À©µµ¿ì Ŭ·¡½º¸í µµ±¸¸ðÀ½À» µî·Ï

    static CWndClassInfo& GetWndClassInfo()

    {

        static CWndClassInfo wc =

        {

            {sizeof(WNDCLASSEX), CS_HREDRAW | CS_VREDRAW, StartWindowProc,

            0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1),

            MAKEINTRESOURCE(IDR_MENU_MAIN),          // µµ±¸¸ðÀ½

            "Hello", NULL},

            NULL, NULL, IDC_ARROW, TRUE, 0, _T("")

        };

        return wc;

    }

 

private:

    // ¸Þ¼¼Áö ÇÊÅÍ Ã³¸®

    virtual BOOL PreTranslateMessage(MSG* pMsg){

        return FALSE;

    }

 

    // ¾ÆÀ̵é ó¸®

    virtual BOOL OnIdle(){

        return FALSE;

    }

 

    // ¸Þ¼¼Áö ¸Ê

    BEGIN_MSG_MAP_EX(CMyWindow)

        MSG_WM_PAINT(OnPaint)

        MSG_WM_CONTEXTMENU(OnContextMenu)

        MSG_WM_CREATE(OnCreate)

        MSG_WM_DESTROY(OnDestroy)

        COMMAND_ID_HANDLER_EX(ID_MENUITEM_HELLO, OnMenuHello)

        COMMAND_ID_HANDLER_EX(ID_MENUITEM_EXIT, OnMenuExit)

    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 OnDestroy(){

        PostQuitMessage(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.Create(NULL, CWindow::rcDefault,

        _T("Hello, ATL/WTL"), WS_OVERLAPPEDWINDOW | WS_VISIBLE);

 

    int nRet = theLoop.Run();

 

    _Module.RemoveMessageLoop();

 

    _Module.Term();

 

    return nRet;

}

                      


¡¡¿ì¼± pop-up menu¸¦ À§ÇÑ ¸Þ´º ÀÚ¿øÀ» ÇÁ·ÎÁ§Æ®¿¡ Ãß°¡ÇÕ´Ï´Ù. ¸Þ´º ÀÚ¿øÀÇ °ÍIDÀº IDR_MENU_POPUPÀ¸·Î ÇØ Åé ·¹º§¿¡[index0]¸¦ ±× ¾Æ·¡¿¡[Hello]¸Þ´º ¾ÆÀÌÅÛ°ú [Á¾·á]¸Þ´º ¾ÆÀÌÅÛÀ» Ãß°¡ÇÕ´Ï´Ù. [Hello]¸Þ´º ¾ÆÀÌÅÛ¿¡´ÂID_MENUITEM_HELLO, [Á¾·á]¸Þ´º ¾ÆÀÌÅÛ¿¡´ÂID_MENUITEM_EXITÀ̶ó°í ÇÏ´ÂIDÀ» ¼³Á¤ÇÕ´Ï´Ù. µ¡ºÙ¿©ID_MENUITEM_EXIT¶ó°í ÇÏ´ÂIDÀº ¹ú½á Àüȸ ÀÛ¼ºÇÑ °ÍÀÔ´Ï´Ù.



¡¡CMenuŬ·¡½º´Âatluser.hÇì´õ¿¡ Á¤Àǵǰí ÀÖ½À´Ï´Ù¸¸  ÀÌ Çì´õ´Âatlapp.hÇì´õ¸¦ ÀÎŬ·çµå ÇÑ ½ÃÁ¡¿¡¼­ ÀÚµ¿ÀûÀ¸·Î ÀÎŬ·çµå µÇ°í ÀÖ½À´Ï´Ù.

¡¡CMyWindowŬ·¡½º¿¡´Â  ¿ì¼±WM_CONTEXTMENU¸Þ¼¼Áö Çڵ鷯¸¦ Ãß°¡ÇØ  ±×·±µ¥ pop-up menu ÀÚ¿øÀ» ·ÎµåÇØTrackPopupMenu()¿¡ ÀÇÇØ pop-up menu¸¦ Ç¥½Ã½Ã۰í ÀÖ½À´Ï´Ù.

¡¡´ÙÀ½¿¡  pop-up menu ¾ÆÀÌÅÛÀÌ ¼±ÅõǾúÀ» ¶§ÀÇ Ä¿¸àµå ¸Þ¼¼Áö Çڵ鷯¸¦ Ãß°¡ÇÕ´Ï´Ù. ¸Þ¼¼Áö ¸Ê¿¡ID°¡ID_MENUITEM_HELLOÀÇ Ä¿¸àµå ¸Þ¼¼Áö¿ëÀÇ ¿£Æ®¸®¸¦ Ãß°¡ÇØ OnMenuHello()¶ó°í ÇÏ´Â ¸Þ¼¼Áö Çڵ鷯¸¦ È£ÃâÇϵµ·Ï ÇÕ´Ï´Ù. µ¡ºÙ¿© ÀÚ¿øIDÀÌID_MENUITEM_EXITÀÇ Ä¿¸àµå ¸Þ¼¼Áö Çڵ鷯´Â  ¹ú½á Àüȸ ÀÛ¼ºÇÏ¿´½À´Ï´Ù.

¡¡±×·±µ¥  À§ÀÇ ¿¹¿¡¼­´Â ¸Þ´º ÀÚ¿øÀ» ·ÎµåÇØ ¸Þ´º¸¦ ÀÛ¼ºÇß½À´Ï´Ù¸¸ ¸Þ´º´Â µ¿ÀûÀ¸·Î ÀÛ¼ºÇÒ ¼öµµ ÀÖ½À´Ï´Ù. ¾Æ·¡¿¡ ³ªÅ¸³»´Â °ÍÀº À§ÀÇ ¿¹¿Í °°Àº pop-up menu¸¦ µ¿ÀûÀ¸·Î ÀÛ¼ºÇÏ´Â ¿¹ÀÔ´Ï´Ù.

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.CreatePopupMenu();

        menuPopup.AppendMenu(MF_STRING, ID_MENUITEM_HELLO, _T("Hello(&H)"));

        menuPopup.AppendMenu(MF_SEPARATOR);

        menuPopup.AppendMenu(MF_STRING, ID_MENUITEM_EXIT, _T("Á¾·á(&X)"));

        menuPopup.TrackPopupMenu(

            TPM_LEFTALIGN | TPM_TOPALIGN | TPM_LEFTBUTTON, pt.x, pt.y, m_hWnd);

    }else{

        SetMsgHandled(false);

    }

}