MFCPropertyGridCtrl 是VC 2008 pack中的控件类。
CMFCPropertyGridProperty这个控件类中的属性值类类。
针对修改属性后,对属性值改变的消息处理:
方法一:
当用到CMFCPropertyGridProperty这个类控件的时候出现了一个很白痴的问题,CMFCPropertyGridProperty更改属性值触发的是哪个事件,如何获得他被更改时的通知?
难道要设置回调?我看了这个类的所有的方法,都没有找到设置回调的函数.因为CMFCPropertyGridProperty这个类控件是在属性页CMFCPropertyGridCtrl中活动,所以我就又看了CMFCPropertyGridCtrl这个的方法,唯一找到一个名字稍微靠谱的就是OnPropertyChanged(字面意思就是属性更改),接着我找到MFC的源文件afxpropertygridctrl.cpp,定位到OnPropertyChanged这个函数,发现源代码中有一行GetOwner()->SendMessage(AFX_WM_PROPERTY_CHANGED, GetDlgCtrlID(), LPARAM(pProp));
难道是发送消息来通知的,赶紧回到项目里面在CPropertiesWnd里面加了个自定义消息AFX_WM_PROPERTY_CHANGED(注意要把下面的(Registered message)勾选上)试了试,当更改值的时候果然收到了通知.于是乎赶紧GOOGLE->AFX_WM_PROPERTY_CHANGED终于在MS的网站找找到了AFX_WM_PROPERTY_CHANGED的用法,消息处理函数的第二个参数lParam就是被更改值的那个控件的指针(CMFCPropertyGridProperty*)(CMFCPropertyGridColorProperty*)..等。 问题终于解决...
方法二:
利用回调函数,继承于CMFCPropertyGridProperty。
头文件:
class PropertyGridCallback; class PropertyGridProperty : public CMFCPropertyGridProperty { DECLARE_DYNAMIC(PropertyGridProperty) friend class CMFCPropertyGridCtrl; public: PropertyGridProperty(PropertyGridCallback* pCallback, int itemID, const CString& strGroupName, DWORD_PTR dwData = 0, BOOL bIsValueList = FALSE); PropertyGridProperty(PropertyGridCallback* pCallback, int itemID, const CString& strName, const COleVariant& varValue, int textLimit = 0, LPCTSTR lpszDescr = NULL, DWORD_PTR dwData = 0, LPCTSTR lpszEditMask = NULL, LPCTSTR lpszEditTemplate = NULL, LPCTSTR lpszValidChars = NULL); virtual ~PropertyGridProperty(); virtual BOOL OnUpdateValue(); virtual BOOL CheckValue(const COleVariant& newValue, std::string& errorString); protected: PropertyGridCallback* _pCallback; bool _updatingValue; COleVariant _lastValue; int _textLimit; int _itemID; };
实现文件:
IMPLEMENT_DYNAMIC(PropertyGridProperty, CMFCPropertyGridProperty) PropertyGridProperty::PropertyGridProperty(PropertyGridCallback* pCallback, int itemID, const CString& strGroupName, DWORD_PTR dwData /*= 0*/, BOOL bIsValueList /*= FALSE*/ ) : CMFCPropertyGridProperty(strGroupName, dwData, bIsValueList) ,_itemID(itemID) ,_updatingValue(false) ,_pCallback(pCallback) { } PropertyGridProperty::PropertyGridProperty(PropertyGridCallback* pCallback, int itemID, const CString& strName, const COleVariant& varValue, int textLimit, LPCTSTR lpszDescr /*= NULL*/, DWORD_PTR dwData /*= 0*/, LPCTSTR lpszEditMask /*= NULL*/, LPCTSTR lpszEditTemplate /*= NULL*/, LPCTSTR lpszValidChars /*= NULL*/ ) : CMFCPropertyGridProperty(strName, varValue, lpszDescr, dwData, lpszEditMask, lpszEditTemplate, lpszValidChars) ,_textLimit(textLimit) ,_itemID(itemID) ,_updatingValue(false) ,_pCallback(pCallback) { _lastValue = varValue; } PropertyGridProperty::~PropertyGridProperty() { } BOOL PropertyGridProperty::OnUpdateValue() { if (_updatingValue) { return TRUE; } _updatingValue = true; CString text; m_pWndInPlace->GetWindowText(text); text.Trim(); COleVariant newValue(text); if (newValue == _lastValue) { _updatingValue = false; return TRUE; } std::string errorString; if (!CheckValue(text, errorString)) { AfxMessageBox(errorString.c_str()); } else { _pCallback->SetValue(_itemID, newValue); _lastValue = newValue; } SetValue(_lastValue); _updatingValue = false; return TRUE; } BOOL PropertyGridProperty::CheckValue( const COleVariant& newValue, std::string& errorString ) { DWORD errorID = _pCallback->CheckValue(_itemID, newValue); if (errorID != 0) { CString errorInfo; errorInfo.LoadString(errorID); errorString = errorInfo.GetBuffer(); return FALSE; } return TRUE; }
使用方法:定义个一个对话框,使其继承于回调函数类:
class ControllerPage : public CDialogEx, public PropertyGridCallback { DECLARE_DYNAMIC(ControllerPage) public: ControllerPage(CfgMgr* pCfgMgr, CTreeCtrl* pTreeCtrl, CWnd* pParent = NULL); // standard constructor virtual ~ControllerPage(); virtual DWORD CheckValue(DWORD itemID, const COleVariant& newValue); virtual void SetValue(DWORD itemID, COleVariant& newValue); // Dialog Data enum { IDD = IDD_CONTROLLER_PAGE }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support virtual BOOL OnInitDialog(); DECLARE_MESSAGE_MAP() private: void _InitPropertyCtrl(); PropertyGridCtrl _propertyGrid; };