【问题标题】:Best way to reimplement CMFCPropertyGridProperty class (MFC)重新实现 CMFCPropertyGridProperty 类 (MFC) 的最佳方法
【发布时间】:2016-04-14 17:45:34
【问题描述】:

几天前,我试图实现一种方法,该方法可以检测我的属性窗口 (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 后擦除整个更新信息),这可能与 @ 中的其他方法和属性有关987654328@ 仍未在此辅助类中实现。 我想知道:在我的辅助类中实现 CMFCPropertyGridProperty 类中包含的所有内容将是一项艰巨的工作(就像我对构造函数所做的那样)。是否应该有一个关于 OOP 的策略来解决问题?另外,我不知道我的方法是否是最好的。我的意思是,有没有更简单的方法来实现BOOL CMFCPropertyGridProperty::OnUpdateValue() 而无需重写另一个类的代码?欢迎任何想法!

【问题讨论】:

  • 你能继承CMFCPropertyGridProperty 并破解错误吗?我过去曾使用 Winforms 对象做到这一点。
  • “子类”是什么意思?抱歉,我是 C++/MFC 的新手
  • 子类的意思是你要写一个新的类,继承自CMFCPropertyGridProperty啊,对不起。我从您的代码中看到您已经这样做了。
  • OOP 策略称为继承。您继承基类成员并覆盖您想要专门化的虚拟成员,如果需要,可能会调用基类实现。如果有错误,请修复它们。并查看The Definitive C++ Book Guide and List - 这是基本的 C++。

标签: c++ inheritance mfc


【解决方案1】:

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

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

请参阅MSDN 中的文档。

还有一个虚函数 CMFCPropertyGridCtrl::OnPropertyChanged 会在属性发生变化时被调用。

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

【讨论】:

【解决方案2】:

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

PropertiesWnd.h 文件中添加以下代码

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

PropertiesWnd.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;

}

我是使用 Visual Studio 2010 完成的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 2012-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 1970-01-01
    相关资源
    最近更新 更多