重新实现CMFCPropertyGridProperty类(MFC)的最佳方式

Best way to reimplement CMFCPropertyGridProperty class (MFC)

本文关键字:MFC 最佳 方式 CMFCPropertyGridProperty 实现 新实现      更新时间:2023-10-16

几天前,我试图实现一种方法,该方法可以检测"属性窗口"(CPropertiesWnd)中的值何时更新,并在我的MFC应用程序中执行一些其他操作。由于我主要使用CMFCPropertyGridProperty实例来处理属性窗口中包含的信息,所以我决定实现方法BOOL CMFCPropertyGridProperty::OnUpdateValue()(虚拟),每当我的属性网格中发生变化时,框架就会自动调用它。因此,由于我无法修改CMFCPropertyGridProperty类(以及其他类似afxpropertygridctrl.h的文件),我创建了一个辅助类来进行修改:

#pragma once

// CMFCPropertyGridPropertyAux
class CMFCPropertyGridPropertyAux : public CMFCPropertyGridProperty
{
public:
    CMFCPropertyGridPropertyAux(const CString& strGroupName, DWORD_PTR dwData=0, BOOL bIsValueList=FALSE);
    CMFCPropertyGridPropertyAux(const CString& strName, const COleVariant& varValue, LPCTSTR lpszDescr = NULL, DWORD_PTR dwData = 0,
        LPCTSTR lpszEditMask = NULL, LPCTSTR lpszEditTemplate = NULL, LPCTSTR lpszValidChars = NULL);
    virtual ~CMFCPropertyGridPropertyAux();
    BOOL OnUpdateValue();
};

// MFCPropertyGridPropertyAux.cpp : implementation file
//
#include "stdafx.h"
#include "MFCProject.h"
#include "MFCPropertyGridPropertyAux.h"

// CMFCPropertyGridPropertyAux
CMFCPropertyGridPropertyAux::CMFCPropertyGridPropertyAux(const CString& strGroupName, DWORD_PTR dwData,BOOL bIsValueList):CMFCPropertyGridProperty(strGroupName, dwData, bIsValueList)
{
}
CMFCPropertyGridPropertyAux::CMFCPropertyGridPropertyAux(const CString& strName, const COleVariant& varValue, LPCTSTR lpszDescr, DWORD_PTR dwData,
        LPCTSTR lpszEditMask, LPCTSTR lpszEditTemplate, LPCTSTR lpszValidChars):CMFCPropertyGridProperty(strName, varValue, lpszDescr, dwData, lpszEditMask, lpszEditTemplate, lpszValidChars)
{
}

CMFCPropertyGridPropertyAux::~CMFCPropertyGridPropertyAux()
{
}

BOOL CMFCPropertyGridPropertyAux::OnUpdateValue() //virtual method implementation
{
    AfxMessageBox(L"Value Changed");
        //do other stuff
    return true;
}

我能够检测到一个属性实际上何时发生了更改,但有一些错误(比如在MessageBox出现后擦除整个更新的信息),这些错误可能与CMFCPropertyGridProperty中的其他方法和属性有关,这些方法和属性仍然没有在这个辅助类中实现。我想知道:在辅助类中实现CMFCPropertyGridProperty类中包含的所有内容将是一项艰巨的工作(就像我对构造函数所做的那样)。是否应该有一个关于OOP的策略来做到这一点?此外,我不知道我的方法是否是最好的。我的意思是,有没有一种更简单的方法可以在不重写其他类代码的情况下实现BOOL CMFCPropertyGridProperty::OnUpdateValue()?欢迎有任何想法!

MFC已经实现了这样的"消息"。你不需要自己做这样的事情。

有一个已注册的窗口消息AFX_WM_PROPERTY_CHANGED,在属性更改时发送。它被发送给网格的所有者。

请参阅MSDN中的文档。

此外,已经有一个虚拟函数CMFCPropertyGridCtrl::OnPropertyChanged在属性更改时被调用。

即使您希望调用您的内部OnUpdateValue值。这很容易。实现您自己的CMFCPropertyGridCtrl::OnPropertyChanged。使用DYNAMIC_DOWNCAST获取指向Aux类的指针,然后只调用OnUpdateValue。。。没什么大不了的。

在我的属性窗口中实现值更改和更新。

属性Wnd.h文件中添加以下代码

afx_msg LRESULT OnPropertyChanged( __in WPARAM wparam, __in LPARAM lparam );

属性Wnd.cpp文件中添加以下代码

ON_REGISTERED_MESSAGE(AFX_WM_PROPERTY_CHANGED, OnPropertyChanged)

一旦任何属性值更改,将调用以下代码

//[in]lparam:指向CMFCPropertyGridProperty 的指针

LRESULT CPropertiesWnd::OnPropertyChanged(__in WPARAM wparam,__in LPARAM lParam )

// pProp will have all the variables and info of the active or change property
CMFCPropertyGridProperty* pProp = (CMFCPropertyGridProperty*) lParam;
int pID = pProp->GetData();
CString str = pProp->GetName() ; // get the change property name.
COleVariant i = pProp->GetValue();// get the change value.
//below is the code to change COleVariant to other variable type
LPVARIANT pVar = (LPVARIANT)i;
    int x;
    short y;
    double d;
    float f;
    bool status;
    CString str1;
    switch(pVar->vt)
    {
        case VT_I2:    // short
            y = pVar->iVal;
            break;
        case VT_I4:     // int
            x = pVar->lVal;
           break;
        case VT_R4:    // float
            f = pVar->fltVal;
            break;
        case VT_R8:    // double
            d = pVar->dblVal;
            break;
        case VT_INT:
            x = pVar->lVal;
            break;
        case VT_BOOL:
            status = pVar->boolVal;
            break;
        case VT_BSTR:
            str1 = pVar->bstrVal;
            break;
        // etc.
    }
return 0;

}

我使用visualstudio2010完成了这项工作。