ºä À©µµ¿ì¶õ  ÇÁ·¹ÀÓ À©µµ¿ìÀÇ Å¬¶óÀÌ¾ðÆ® ¿µ¿ªÀ» °¡¸®µµ·Ï ÇØ Ç¥½ÃµÇ´Â ¾ÆÀÌ À©µµ¿ìÀÔ´Ï´Ù. ¿©±â¿¡¼­´Â  Áö±Ý±îÁö ÀÛ¼ºÇØ ¿Â ÇÁ·¹ÀÓ À©µµ¿ì¿¡ ºäÀ©µå¿ì¸¦ Ãß°¡ÇØ  ±× ºäÀ©µå¿ì¿¡ ¡¸Hello, ATL/WTL¡¹À̶ó°í Çϴ ij¸¯ÅÍ ¶óÀÎÀ» ¹¦È­ ÇÕ´Ï´Ù.

 

// stdafx.h

#include <atlbase.h>

#include <atlapp.h>

extern CAppModule _Module;

#include <atlwin.h>

 

#include <atlcrack.h>

#include <atlmisc.h>

#include <atlframe.h> // CFrameWindowImplŬ·¡½º¸¦ »ç¿ëÇϱâ À§ÇØ(¶§¹®¿¡)

                      

 

// View.h

class CView : public CWindowImpl<CView>

{

public:

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

    BOOL PreTranslateMessage(MSG* pMsg){

        return FALSE;

    }

 

private:

    // ¸Þ¼¼Áö ¸Ê

    BEGIN_MSG_MAP_EX(CView)

        MSG_WM_PAINT(OnPaint)

        MSG_WM_CONTEXTMENU(OnContextMenu)

    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,

                GetParent()  // Ä£À©µµ¿ìÀÇ ÇÚµé

            );

        }else{

            SetMsgHandled(false);

        }

    }

};

                      

 

// MainWindow.h³»

// ¸ÞÀÎ À©µµ¿ìÀÇ base class¸¦CFrameWindowImpl·Î º¯°æ

class CMyWindow : public CFrameWindowImpl<CMyWindow>,

    public CMessageFilter, public CIdleHandler, public CUpdateUI<CMyWindow>

{

public:

    // À©µµ¿ì Ŭ·¡½º¸í , °øÅë ÀÚ¿øIDÀ» µî·Ï

    DECLARE_FRAME_WND_CLASS(_T("Hello"), IDR_MAINFRAME)

 

    // UI°»½Å Çڵ鷯 ¸Ê

    BEGIN_UPDATE_UI_MAP(CMyWindow)

        UPDATE_ELEMENT(ID_MENUITEM_TOPMOST, UPDUI_MENUPOPUP | UPDUI_TOOLBAR)

    END_UPDATE_UI_MAP()

 

private:

    CView m_view;

 

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

    virtual BOOL PreTranslateMessage(MSG* pMsg){

        // base classÀÇ °ÍPreTranslateMessageÀ» È£ÃâÇÏ´Â

        if(CFrameWindowImpl<CMyWindow>::PreTranslateMessage(pMsg))

            return TRUE;

 

        // ºäÀ©µå¿ìÅ©¶ó½ºÀÇ °ÍPreTranslateMessageÀ» È£ÃâÇÏ´Â

        return m_view.PreTranslateMessage(pMsg);

    }

 

    // ¾ÆÀ̵é ó¸®

    virtual BOOL OnIdle(){

        UIUpdateToolBar();

        return FALSE;

    }

 

    // ¸Þ¼¼Áö ¸Ê

    BEGIN_MSG_MAP_EX(CMyWindow)

        MSG_WM_CREATE(OnCreate)

        COMMAND_ID_HANDLER_EX(ID_MENUITEM_TOPMOST, OnMenuTopmost)

        COMMAND_ID_HANDLER_EX(ID_MENUITEM_HELLO, OnMenuHello)

        COMMAND_ID_HANDLER_EX(ID_MENUITEM_EXIT, OnMenuExit)

        CHAIN_MSG_MAP(CUpdateUI<CMyWindow>)         // CUpdateUIŬ·¡½º¿¡ üÀÎ

        CHAIN_MSG_MAP(CFrameWindowImpl<CMyWindow>)  // CFrameWindowImplŬ·¡½º¿¡ üÀÎ

    END_MSG_MAP()

 

    LRESULT OnCreate(LPCREATESTRUCT lpcs){

        // ¸®¹ö¸¦ ÀÛ¼º

        CreateSimpleReBar();

 

        // Åø¹Ù¸¦ ÀÛ¼ºÇØ ¹êµå¿¡ Ãß°¡

        HWND hWndToolBar = CreateSimpleToolBarCtrl(m_hWnd,

            IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE);

        AddSimpleReBarBand(hWndToolBar);

        UIAddToolBar(hWndToolBar);

 

        // »óÅ ¹Ù¸¦ ÀÛ¼º

        CreateSimpleStatusBar();

 

        // ºäÀ©µå¿ì¸¦ ÀÛ¼º

        m_hWndClient = m_view.Create(m_hWnd, rcDefault, NULL,

            WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,

            WS_EX_CLIENTEDGE);

 

        // [Ç×»ó ¾Õ¿¡ Ç¥½Ã]¸Þ´ºÀÇ Ã¼Å© ¸¶Å© ¼³Á¤

        UISetCheck(ID_MENUITEM_TOPMOST, false);

 

        // ¸Þ½ÃÁö ·çÇÁ¿¡ ¸Þ¼¼Áö ÇÊÅÍ¿Í ¾ÆÀ̵¹ Çڵ鷯¸¦ Ãß°¡

        CMessageLoop* pLoop = _Module.GetMessageLoop();

        pLoop->AddMessageFilter(this);

        pLoop->AddIdleHandler(this);

        return 0;

    }

 

    void OnMenuTopmost(UINT uNotifyCode, int nID, HWND hWndCtl){

        bool bTopmost = !(UIGetState(nID) & UPDUI_CHECKED);

        SetWindowPos(bTopmost ? HWND_TOPMOST : HWND_NOTOPMOST,

            0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);

        UISetCheck(nID, bTopmost);

    }

 

    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 "View.h"

#include "MainWindow.h"

 

CAppModule _Module;

 

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR lpCmdLine, int nCmdShow)

{

    // ÄÚ¸Õ ÄÁÆ®·Ñ ¹× ¸®¹ö ÃʱâÈ­

    AtlInitCommonControls(ICC_WIN95_CLASSES | ICC_COOL_CLASSES);

 

    _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;

}

                      


¡¡¿ì¼±, ºäÀ©µå¿ì¸¦ À§ÇÑ Å¬·¡½º¸¦ Á¤ÀÇÇÕ´Ï´Ù. À§ÀÇ ¿¹¿¡¼­´Â ÇÁ·ÎÁ§Æ®¿¡View.h¶ó°í ÇÏ´Â Çì´õ ÆÄÀÏÀ» Ãß°¡ÇØ  °Å±â¿¡ CView¶ó°í Çϴ Ŭ·¡½º¸¦ Á¤ÀÇÇϰí ÀÖ½À´Ï´Ù.  CViewŬ·¡½º´ÂCWindowImplŬ·¡½º·ÎºÎÅÍ ÆÄ»ýÇÏ´Â Åë»óÀÇ À©µµ¿ìÀÔ´Ï´Ù.  CViewŬ·¡½º³»¿¡¼­´Â , µ¶ÀÚÀûÀÎ ¸Þ¼¼Áö ÇÊÅ͸¦ ÁغñÇØ  ¸Þ¼¼Áö ¸ÊÀ¸·Î WM_PAINT¸Þ½ÃÁö ¿Í WM_CONTEXTMENU¸Þ¼¼Áö¸¦ ¸ÅÇÎ Çϰí ÀÖ½À´Ï´Ù. ÀÌ°Íµé µÎ °³ÀÇ ¸Þ¼¼Áö´Â  Áö±Ý±îÁö ÇÁ·¹ÀÓ À©µµ¿ìÃø¿¡¼­ ó¸®Çϰí ÀÖ¾ú½À´Ï´Ù¸¸  ºäÀ©µå¿ì¿¡ ÀÇÇØ ÇÁ·¹ÀÓ À©µµ¿ìÀÇ Å¬¶óÀÌ¾ðÆ® ¿µ¿ªÀÌ ¼û¾î ¹ö¸®±â ¶§¹®¿¡  ºä À©µµ¿ì Ãø¿¡¼­ ó¸®ÇÕ´Ï´Ù. µû¶ó¼­ ÇÁ·¹ÀÓ À©µµ¿ìÀÎCMyWindowŬ·¡½º·ÎºÎÅÍ´Â  ÀÌ°Íµé µÎ °³ÀÇ ¸Þ¼¼Áö ¸Ê ¿£Æ®¸® ¹× ¸Þ¼¼Áö Çڵ鷯¸¦ »èÁ¦Çϰí ÀÖ½À´Ï´Ù.

µ¡ºÙ¿©WM_CONTEXTMENU¸Þ¼¼Áö Çڵ鷯·Î È£ÃâÇϰí ÀÖ´Â TrackPopupMenu()ÀÇ Á¦4Àμö´Â  ºÎ¸ð À©µµ¿ìÀÇ ÇÚµé·Î º¯°æÇÕ´Ï´Ù.

¡¡CMyWindowŬ·¡½º³»¿¡¼­´Â , ¿ì¼± ÇÁ·¹ÀÓ À©µµ¿ì Ŭ·¡½º¸í µî·Ï ¸ÅÅ©·Î¸¦ DECLARE_FRAME_WND_CLASS_EX·ÎºÎÅÍ DECLARE_FRAME_WND_CLASS·Î º¯°æÇϰí ÀÖ½À´Ï´Ù. À̰ÍÀº  ºäÀ©µå¿ì¸¦ »ç¿ëÇÏ´Â °Í¿¡ ÀÇÇØ  ÇÁ·¹ÀÓ À©µµ¿ìÀÇ Å¬¶óÀÌ¾ðÆ® ¿µ¿ª¿¡ Á÷Á¢ ¡¸Hello, ATL/WTL¡¹À̶ó°í Çϴ ij¸¯ÅÍ ¶óÀÎÀ» ¹¦È­ ÇÏÁö ¾Ê°Ô µÇ±â ¶§¹®¿¡  CS_HREDRAW | CS_VREDRAW ¶ó°í ÇÏ´Â ½ºÅ¸ÀÏÀ» ÁöÁ¤ÇÒ ÇÊ¿ä ¾ø°Ô µÇ±â ¶§¹®ÀÔ´Ï´Ù.

¡¡´ÙÀ½¿¡  ºäÀ©µå¿ìÀÎCViewŬ·¡½ºÀÇ ÀνºÅϽº¸¦  CMyWindowŬ·¡½ºÀÇ ¸â¹ö º¯¼ö·Î¼­ ¼±¾ðÇÕ´Ï´Ù. CMyWindow::OnCreate()±×·³ ÀÌ ºä À©µµ¿ì¸¦ ÀÛ¼ºÇØ  CFrameWindowImplŬ·¡½ºÀÇ base classÀÎ CFrameWindowImplBase Ŭ·¡½ºÀÇ m_hWndClientÀ̶ó°í ÇÏ´ÂHWND ÇüÅÂÀÇ ¸â¹ö º¯¼ö¿¡ ´ëÀÔÇÕ´Ï´Ù.

CFrameWindowImplŬ·¡½º¿¡´ÂWM_SIZE¸Þ¼¼Áö Çڵ鷯°¡ ÁغñµÇ¾î ÀÖ½À´Ï´Ù. ÀÌ ¶§¹®¿¡  ¸ÞÀÎ À©µµ¿ìÀÇ »çÀÌÁ º¯°æÇßÀ» ¶§ÀÇWM_SIZE¸Þ¼¼Áö°¡ üÀÎóÀÇCFrameWindowImplŬ·¡½º¿¡ º¸³»Áö¸é  CFrameWindowImplŬ·¡½ºÀÇ WM_SIZE¸Þ¼¼Áö Çڵ鷯°¡ ºÒ·Á °©´Ï´Ù. ÀÌ Çڵ鷯¿¡¼­´ÂUpdateLayout()À̶ó°í ÇÏ´Â ÇÔ¼ö¸¦ È£ÃâÇϰí ÀÖ¾î ÀÌ ÇÔ¼ö´Â °¢ m_hWndClient¿¡¼­ ½Äº°µÇ´Â ºäÀ©µå¿ì¸¦ ÀÚµ¿ÀûÀ¸·Î ÇÁ·¹ÀÓ À©µµ¿ìÀÇ »çÀÌÁî¿¡ ¸ÂÃä´Ï´Ù.

±×¸®°í CMyWindowŬ·¡½ºÀÇ ¸Þ¼¼Áö ÇÊÅÍ¿¡¼­´Â  CViewŬ·¡½ºÀÇ µ¶ÀÚ ¸Þ¼¼Áö ÇÊÅÍ ÇÔ¼ö¸¦ È£ÃâÇϰí ÀÖ½À´Ï´Ù. À̰Ϳ¡ ÀÇÇØ ºäÀ©µå¿ì¿¡µµ ¸Þ¼¼Áö ÇÊÅ͸µÀÇ ±âȸ¸¦ ÁÖ°í ÀÖ½À´Ï´Ù.

¡¡hello.cppÆÄÀϳ»¿¡¼­´Â ,MainWindow.hÇì´õ¸¦ ÀÎŬ·çµå Çϱâ Àü¿¡View.hÇì´õ¸¦ ÀÎŬ·çµå ÇÕ´Ï´Ù.