WTL初步:定制控件外观

/** 在ATL中,变量关联控件共有3种方法: */ // 1》 使用CWindow派生类Attach一个控件 HWND hWnd = GetDlgItem(IDC_LIST); CListView lst; lst.Attach(hWnd); CListView lst2(hWnd); CListView lst3 = lst2;// 甚至可以直接使用 lst = lstother 进行赋值 //2》 使用CContainedWindow,SubclassWindow 一个空间 //注意:使用它不能处理WM_COMMAND, WM_NOTIFY和其他通知消息, // 这些消息都被发往了父窗口 class CMyDlg : public CDialogImpl { private: //1 添加成员变量 CContainedWindow m_btn1;//如果还想使用Button的特性,要 CContainedWindow m_btn1; public: //2 添加 ALT_MSG_MAP 小节 BEGIN_MSG_MAP_EX(CMyDlg) ALT_MSG_MAP(1) // 小节号要和下面构造函数的号码一致 MSG_WM_SETCURSOR(OnSetCursor) END_MSG_MAP() //3 构造函数中初始化变量 CMyDlg() : m_btn1(this,1) {} protected //4 SuclassWindow LRESULT OnInitDialog(..) { m_btn1.SubclassWindow(GetDlgItem(IDC_BTN1)); } //5 消息响应函数 LRESULT OnSetCursor() { ... } }; // 3》 使用自己派生的类,派生自CWindowImpl,然后使用SubclassWindow class CMyButton : public CWindowImpl { protected: BEGIN_MSG_MAP_EX(CMyButton) MSG_WM_SETCURSOR(OnSetCursor) END_MSG_MAP() LRESULT OnSetCursor() { ... } }; ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// /** * 在 WTL 中,变量关联控件的方式有一种,数据交换 DDX,这很像MFC 1》 派生自己的类 2》 加入DDX支持 */ class CMyDlg : public CDialogImpl, //1> 一定要加入DDX支持的类 public CWinDataExchange { private: //2> 定义变量 CMyButton m_btn1; protected: //3> DDX 宏支持 BEGIN_DDX_MAP(CMyDlg) DDX_CONTROL(IDC_BTN1,m_btn1) END_DDX_MAP() protected: //4> SubclassWindow 和 数据交换初始化 LRESULT OnInitDialog(...) { m_btn1.SubclassWindow(GetDlgItem(IDC_BTN1)); // 必须的 DoDataExchange(false); } }; /** 3>关于数据交换,有以下几点需要注意: */ //1 可用的DDX 宏有下面几个, // DDX_TEXT DDX_INT DDX_UINT DDX_CHECK DDX_RADIO // DDX_FLOAT 使用此宏在所有WTL头文件包含之前添加: // #define _ATL_USE_DDX_FLOAT,默认状态为了优化程序的大小而不支持浮点数。 // 2: 《!!!可以对一个控件关联数个变量!!!》,比如对一个Edit同时使用DDX_TEXT ,DDX_INT,DDX_CONTROL // 3: 当数据交换失败的时候会触发 对方法OnDataExchangeError()的调用 /** 4> 数据校验 DDV,3个可用宏 a> DDX_TEXT_LEN , DDX_INT_RANGE and DDX_UINT_RANGE ,DDX_FLOAT_RANGE b> 数据验证失败,触发OnDataValidateError */ class CMyDlg : public ... { BEGIN_DDX_MAP(CMainDlg) //... DDX_INT_RANGE(IDC_FAV_SEASON, m_nSeason, 1, 7) // 这样就不需要 DDX 了 END_DDX_MAP() void OnDataValidateError ( UINT nCtrlID, BOOL bSave, _XData& data ); }; /** 5>控件通知消息的处理 */ // WM_COMMAND消息处理原型:void func ( UINT uCode, int nCtrlID, HWND hwndCtrl );有以下几个可用宏: // COMMAND_HANDLER_EX // COMMAND_ID_HANDLER_EX // COMMAND_CODE_HANDLER_EX // COMMAND_RANGE_HANDLER_EX // COMMAND_RANGE_CODE_HANDLER_EX // WM_NOTIFY 和 WM_COMMAND 类同,只是前缀为 NOTIFY,原型:LRESULT func ( NMHDR* phdr ); /** 5> 反射通知消息 */ // 消息反射得以让控件自己处理自己的通知消息,而不是其父窗口处理。 // 使用宏 REFLECT_NOTIFICATIONS class CMyDlg: public CDialogImpl { BEGIN_MSG_MAP_EX(CMyDlg) REFLECT_NOTIFICATIONS() // REFLECT_NOTIFICATIONS 将消息反射回控件自己 END_MSG_MAP() }; class CMyButton : public CWindowImpl { BEGIN_MSG_MAP_EX(CMyButton) MSG_OCM_DRAWITEM(OnDrawItem) // 注意消息反射是 MSG_OCM_xxx 不是 MSG_WM_XXX DEFAULT_REFLECTION_HANDLER() // 注意此处使用默认的消息反射处理宏 END_MSG_MAP() }; // 共有18 个消息反射宏  

你可能感兴趣的:(WTL初步:定制控件外观)