代码改变世界

WTL学习笔记(3)对话框和控件

2011-08-08 17:47  Clingingboy  阅读(1536)  评论(0编辑  收藏  举报

 

1.初始化控件

int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR lpstrCmdLine, int nCmdShow)
{
   …
    AtlInitCommonControls ( ICC_WIN95_CLASSES );

   …
  
    return nRet;
}
// Common Controls initialization helper
inline BOOL AtlInitCommonControls(DWORD dwFlags)
{
    INITCOMMONCONTROLSEX iccx = { sizeof(INITCOMMONCONTROLSEX), dwFlags };
    BOOL bRet = ::InitCommonControlsEx(&iccx);
    ATLASSERT(bRet);
    return bRet;
}

2.继承自ATL的CDialogImpl

3.使用DDX,继承自CWinDataExchange

class CMainDlg : public CDialogImpl<CMainDlg>,
                 public CWinDataExchange<CMainDlg>
{
public:
    enum { IDD = IDD_MAINDLG };

    CMainDlg();
    ~CMainDlg();
}
BEGIN_DDX_MAP(CMainDlg)
    DDX_CONTROL(IDC_EDIT, m_wndEdit)
    DDX_TEXT(IDC_EDIT, m_sEditContents)
    DDX_FLOAT(IDC_EDIT, m_fEditFloat)
    DDX_FLOAT(IDC_EDIT, m_dEditDouble)
    DDX_CHECK(IDC_SHOW_MSG, m_bShowMsg)
    DDX_CONTROL(IDC_TREE, m_wndTree)
END_DDX_MAP()

使用Attach方法获取控件句柄

// Attach m_wndList to the list control.
m_wndList.Attach ( GetDlgItem(IDC_LIST) );

4.处理子控件消息

(1)使用Command

COMMAND_ID_HANDLER_EX(ID_APP_ABOUT, OnAppAbout)
COMMAND_ID_HANDLER_EX(IDOK, OnOK)
COMMAND_ID_HANDLER_EX(IDCANCEL, OnCancel)

(2)使用CContainedWindow

一共需要4个步骤

  • 定义CContainedWindow
  • 定义消息节点
  • 构造CContainedWindow接收特定的消息节点
  • 通过子类继承的方式将相关句柄传递给CContainedWindow
CContainedWindow m_wndOKBtn, m_wndExitBtn;

CMainDlg::CMainDlg() : m_wndOKBtn(this, 1), m_wndExitBtn(this, 2)
{
}

ALT_MSG_MAP(1)
MSG_WM_SETCURSOR(OnSetCursor_OK)
ALT_MSG_MAP(2)
MSG_WM_SETCURSOR(OnSetCursor_Exit)

m_wndOKBtn.SubclassWindow ( GetDlgItem(IDOK) );
m_wndExitBtn.SubclassWindow ( GetDlgItem(IDCANCEL) );

(3)空消息处理,可以收到消息不处理

ALT_MSG_MAP(3)
    // no msg handlers for the list control
END_MSG_MAP()

(4)使用CWindowImplBaseT的子类继承

调用方法相同,还是SubclassWindow,子窗体自己处理消息,而不是交给父窗体

// CButtonImpl - CWindowImpl-derived class that implements a button.  We need a
// class like this to do subclassing or DDX.
class CButtonImpl : public CWindowImpl<CButtonImpl, CButton>
{
    BEGIN_MSG_MAP(CButtonImpl)
        MSG_WM_SETCURSOR(OnSetCursor)
    END_MSG_MAP()

    LRESULT OnSetCursor(HWND hwndCtrl, UINT uHitTest, UINT uMouseMsg)
    {
    static HCURSOR hcur = LoadCursor ( NULL, IDC_SIZEALL );

        if ( NULL != hcur )
            {
            SetCursor ( hcur );
            return TRUE;
            }
        else
            {
            SetMsgHandled(false);
            return FALSE;
            }
    }
};
CButtonImpl      m_wndAboutBtn;

// CButtonImpl: subclass the About button
m_wndAboutBtn.SubclassWindow ( GetDlgItem(ID_APP_ABOUT) );

(5)更新DDX数据状态

调用DoDataExchange方法来更新双向状态