ÇÁ·¹ÀÓ À©µµ¿ìÀÇ °æ¿ì´Â °¡¼Ó±â Å×À̺í ÀÚ¿øÀ» ¸ÅÅ©·Î¿¡ ÀÇÇØ ¼³Á¤ÇÒ ¼ö ÀÖ¾ú½À´Ï´Ù. ±×¸®°í  ÇÁ·¹ÀÓ À©µµ¿ì¸¦ ¼­Æ÷Æ®ÇÏ´ÂCFrameWindowImplŬ·¡½º´Â  Å°º¸µå °¡¼Ó±â¸¦ À¯È¿ÇϰÔÇϱâ À§ÇÑ ±â´ÉÀ» °®Ãß°í ÀÖ¾ú½À´Ï´Ù.

¡¡±×·±µ¥  ´ÙÀ̾ó·Î±×¸¦ ¼­Æ÷Æ®ÇÏ´ÂCDialogImpl Ŭ·¡½º´Â  ±×·¯ÇÑ ¸ÅÅ©·Î³ª ±â´ÉÀ» °®Ãß°í ÀÖÁö ¾Ê½À´Ï´Ù. ±×·±µ¥ À̹øÀº  Àüȸ À©µµ¿ì¿ëÀÇ UI°»½Å Çڵ鷯¸¦ Ãß°¡ÇÑ ¸ð´Þ¸®½º ´ÙÀ̾ó·Î±×¿¡  Å°º¸µå °¡¼Ó±â¸¦ Ãß°¡ÇÏ´Â ¹æ¹ýÀ» ³ªÅ¸³À´Ï´Ù. µ¡ºÙ¿© ¿©±â¿¡¼­´Â ¹ú½á Ãß°¡ÇÑ ¸Þ´ºÀÇ [Ç×»ó ¾Õ¿¡ Ç¥½Ã]¿¡ [Ctrl+T] ¶ó°í ÇÏ´Â °¡¼Ó±â ۸¦ ÇÒ´çÇÕ´Ï´Ù.

// stdafx.h

#include <atlbase.h>

#include <atlapp.h>

extern CAppModule _Module;

#include <atlwin.h>

 

#include <atlcrack.h>

#include <atlmisc.h>

#include <atlframe.h>

                      

 

// MainDlg.h

class CMainDlg : public CDialogImpl<CMainDlg>,

    public CMessageFilter, public CIdleHandler, public CUpdateUI<CMainDlg>

{

public:

    enum { IDD = IDD_DIALOG1 };

 

    HACCEL m_hAccelTable;    // °¡¼Ó±â Å×À̺íÀÇ ÇÚµé

 

    // constructor¡¡ ¡¡

    CMainDlg() : m_hAccelTable(NULL)

    {}

 

    virtual BOOL PreTranslateMessage(MSG* pMsg){

        // °¡¼Ó±â

        if(m_hAccelTable != NULL){

            if(::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg))

                return TRUE;

        }

 

        return IsDialogMessage(pMsg);

    }

 

    virtual BOOL OnIdle(){

        UIUpdateChildWindows();

        return FALSE;

    }

 

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

    BEGIN_UPDATE_UI_MAP(CMyWindow)

        UPDATE_ELEMENT(ID_MENUITEM_TOPMOST, UPDUI_MENUPOPUP)

        UPDATE_ELEMENT(IDCANCEL, UPDUI_CHILDWINDOW)

    END_UPDATE_UI_MAP()

 

    // ¸Þ¼¼Áö ¸Ê

    BEGIN_MSG_MAP_EX(CMainDlg)

        MSG_WM_INITDIALOG(OnInitDialog)

        COMMAND_ID_HANDLER_EX(ID_MENUITEM_TOPMOST, OnMenuTopmost)

        COMMAND_ID_HANDLER_EX(IDOK, OnOK)

        COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)

        CHAIN_MSG_MAP(CUpdateUI<CMainDlg>) 

    END_MSG_MAP()

 

    LRESULT OnInitDialog(HWND hWnd, LPARAM lParam){

        // ½ºÅ©¸°ÀÇ Áß¾Ó¿¡ ¹èÄ¡

        CenterWindow();

 

        // Å« ¾ÆÀÌÄÜ ¼³Á¤

        HICON hIcon = AtlLoadIconImage(IDI_ICON_MAIN, LR_DEFAULTCOLOR,

            ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON));

        SetIcon(hIcon, TRUE);

       

        // ÀÛÀº ¾ÆÀÌÄÜ ¼³Á¤

        HICON hIconSmall = AtlLoadIconImage(IDI_ICON_MAIN, LR_DEFAULTCOLOR,

            ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON));

        SetIcon(hIconSmall, FALSE);

 

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

        CMessageLoop* pLoop = _Module.GetMessageLoop();

        pLoop->AddMessageFilter(this);

        pLoop->AddIdleHandler(this);

 

        // ´ÙÀ̾ó·Î±× ÇÚµéÀ» ¾ÆÀÌ À©µµ¿ì¿ëÀÇUI°»½Å Çڵ鷯¿¡ Ãß°¡

        UIAddChildWindowContainer(m_hWnd);

       

        // [ĵ½½]¹öưÀÇ »ç¿ë °¡ºÎ ¼³Á¤

        UIEnable(IDCANCEL, FALSE);

       

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

        UISetCheck(ID_MENUITEM_TOPMOST, false);

 

        // °¡¼Ó±â Å×À̺íÀ» ·Îµå

        m_hAccelTable = AtlLoadAccelerators(IDR_ACCELERATOR_MAIN);

 

        return TRUE;

    }

 

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

 

        // [ĵ½½]¹öưÀÇ »ç¿ë °¡ºÎ ¼³Á¤

        UIEnable(IDCANCEL, bTopmost);

    }

 

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

        DestroyWindow();

        ::PostQuitMessage(nID);

    }

 

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

        DestroyWindow();

        ::PostQuitMessage(nID);

    }

};

                      

 

// modaless.cpp

#include "stdafx.h"

 

#include "resource.h"

 

#include "MainDlg.h"

 

CAppModule _Module;

 

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

{

    _Module.Init(NULL, hInstance);

 

    CMessageLoop theLoop;

    _Module.AddMessageLoop(&theLoop);

 

    CMainDlg dlgMain;

    dlgMain.Create(NULL);

    dlgMain.ShowWindow(nCmdShow);

 

    int nRet = theLoop.Run();

 

    _Module.RemoveMessageLoop();

 

    _Module.Term();

 

    return nRet;

}

                      


¡¡¿ì¼±Àº ÇÁ·ÎÁ§Æ®¿¡ °¡¼Ó±â Å×À̺í ÀÚ¿øÀ» Ãß°¡ÇØ  ÀÚ¿ø IDÀ¸·Î¼­ IDR_ACCELERATOR_MAINÀ»  ¼³Á¤ÇÕ´Ï´Ù. ±×¸®°í ¾ÆÀÌÅÛÀ¸·Î¼­ID_MENUITEM_TOPMOST¶ó°í ÇÏ´Â ID ¸¦ Ãß°¡ÇØ   Ctrl£«T ¶ó°í Çϴ Ű¸¦ µî·ÏÇÕ´Ï´Ù. µ¡ºÙ¿©ID_MENUITEM_TOPMOST¶ó°í ÇÏ´Â IDÀº  ¹ú½á  pop-up menu ¿ëÀÇ °»½Å Çڵ鷯¸¦ ÀÛ¼ºÇßÀ» ¶§¿¡ »ç¿ëÇϰí ÀÖ´ÂIDÀÔ´Ï´Ù.



¡¡´ÙÀ½¿¡ CMainDlg Ŭ·¡½º¿¡ °¡¼Ó±â Å×À̺íÀÇ ÇÚµéÀ» ¸â¹ö º¯¼ö·Î¼­ ¼±¾ðÇÕ´Ï´Ù. ÀÌ º¯¼ö´Â CMainDlg Ŭ·¡½ºÀÇ constructor À¸·Î NULL·Î ¼³Á¤ÇÕ´Ï´Ù.

¡¡OnInitDialog() ¾È¿¡¼­´Â AtlLoadAccelerators() ¿¡ ÀÇÇØ °¡¼Ó±â Å×À̺íÀ» ·ÎµåÇØ  ±× ÇÚµéÀ» ¸â¹ö º¯¼ö¿¡ ´ëÀÔÇÕ´Ï´Ù.

¡¡¸¶Áö¸·À¸·Î  PreTranslateMessage() ¾È¿¡¼­ TranslateAccelerator() ¸¦ È£ÃâÇÕ´Ï´Ù.