如何使CMFCPropertyGridProperty支持64位整数?

3

我正在使用MFC CMFCPropertyGridProperty编写属性编辑器。看起来它不支持 int64_t/uint64_t类型。当我推送 int64_t/uint64_t的值时,UI显示 ***错误***。

int64_t val = 123456;
COleVariant varValue = (_variant_t)val;

CMFCPropertyGridProperty* pGrid = new CMFCPropertyGridProperty("Int64Val", varValue);
_pParentGrid->AddSubItem(pGrid);
< p > varValue 是正确的,它的 vtVT_I8。 值也是正确的。 有人成功地做过吗?

1
如果CMFCPropertyGridProperty不支持int64,那么一个解决方案是将其转换为其他受支持的类型(例如CString)。这只是一个权宜之计。 - Flaviu_
就此问题,我可以重现它,但是找不到快速或立即的解释或修复方法。您可能可以创建CMFCPropertyGridProperty的自定义版本并覆盖SetValue()成员函数...这很可能是错误发生的地方。 - Adrian Mole
1
从快速查看 atlmfc\src\mfc\afxpropertygridctrl.cpp 来看,这似乎是一个显示问题。由于 CMFCPropertyGridProperty :: FormatProperty 是虚函数,您可以派生自己的类并覆盖FormatProperty以处理 case VT_I8 - dxiv
2个回答

1

@dxiv 是的,我已经检查了CString CMFCPropertyGridProperty::FormatProperty()代码(atlmfc\src\mfc\afxpropertygridctrl.cpp),它不支持VT_I8/VT_UI8。 所以我自己衍生了一个,现在显示很好。但无法编辑。在阅读更多的afxpropertygridctrl.cpp代码后,我发现需要做更多的工作才能使CMFCPropertyGridPropertyInteger64正常工作。

virtual CString FormatProperty() override
{
    ASSERT_VALID(this);
    ASSERT_VALID(m_pWndList);

    COleVariant& var = m_varValue;
    ASSERT(var.vt == VT_I8 || var.vt == VT_UI8);

    CString strVal;

    switch (var.vt)
    {
    case VT_I8:
        strVal.Format(_T("%I64d"), var.llVal);
        break;

    case VT_UI8:
        strVal.Format(_T("%I64u"), var.ullVal);
        break;
    }

    return strVal;
}

1
为了使其正常运行,我制作了一个完整的版本。下面分享代码(使用一些技巧使代码更简单)。
class CMFCPropertyGridInt64Property : public CMFCPropertyGridProperty
{
public:
    CMFCPropertyGridInt64Property(const CString& strName, const COleVariant& varValue, LPCTSTR lpszDescr = NULL, DWORD_PTR dwData = 0,
        LPCTSTR lpszEditMask = NULL, LPCTSTR lpszEditTemplate = NULL, LPCTSTR lpszValidChars = NULL);

    virtual ~CMFCPropertyGridInt64Property();

public:
    void EnableSpinControl(BOOL bEnable, int nMin, int nMax);
    virtual CWnd* CreateInPlaceEdit(CRect rectEdit, BOOL& bDefaultFormat);

    virtual BOOL OnSetCursor() const;
    virtual BOOL PushChar(UINT nChar);
    virtual CString FormatProperty();

protected:

    virtual BOOL TextToVar(const CString& strText);
    virtual BOOL IsValueChanged() const;
    virtual HBRUSH OnCtlColor(CDC* pDC, UINT nCtlColor);
};

#include "stdafx.h"
#include "MFCPropertyGrid.h"


CMFCPropertyGridInt64Property::CMFCPropertyGridInt64Property(const CString& strName, const COleVariant& varValue
    , LPCTSTR lpszDescr /*= NULL*/, DWORD_PTR dwData /*= 0*/, LPCTSTR lpszEditMask /*= NULL*/
    , LPCTSTR lpszEditTemplate /*= NULL*/, LPCTSTR lpszValidChars /*= NULL*/)
    : CMFCPropertyGridProperty(strName, varValue, lpszDescr, dwData, lpszEditMask, lpszEditTemplate, lpszValidChars)
{

}

CMFCPropertyGridInt64Property::~CMFCPropertyGridInt64Property()
{

}

void CMFCPropertyGridInt64Property::EnableSpinControl(BOOL bEnable, int nMin, int nMax)
{

    VARTYPE backVT = m_varValue.vt;
    m_varValue.vt = VT_I4;

    CMFCPropertyGridProperty::EnableSpinControl(bEnable, nMin, nMax);

    m_varValue.vt = backVT;

    return;
}

BOOL CMFCPropertyGridInt64Property::TextToVar(const CString& strText)
{
    CString strVal = strText;

    switch (m_varValue.vt)
    {
    case VT_I8:
#ifdef _UNICODE
        m_varValue.llVal = wcstoll(strText, NULL, 10);
#else
        m_varValue.llVal = _strtoi64(strText, NULL, 10);
#endif
        return TRUE;

    case VT_UI8:
#ifdef _UNICODE
        m_varValue.ullVal = wcstoull(strText, NULL, 10);
#else
        m_varValue.ullVal = _strtoui64(strText, NULL, 10);
#endif
        return TRUE;
    }

    return FALSE;
}

BOOL CMFCPropertyGridInt64Property::IsValueChanged() const
{
    ASSERT_VALID(this);

    if (m_varValueOrig.vt != m_varValue.vt)
    {
        return FALSE;
    }

    const COleVariant& var = m_varValue;
    const COleVariant& var1 = m_varValueOrig;

    switch (m_varValue.vt)
    {
    case VT_I8:
        return var.llVal != var1.llVal;

    case VT_UI8:
        return var.ullVal != var1.ullVal;
    }

    return FALSE;
}

CWnd* CMFCPropertyGridInt64Property::CreateInPlaceEdit(CRect rectEdit, BOOL& bDefaultFormat)
{
    VARTYPE backVT = m_varValue.vt;
    m_varValue.vt = VT_I4;

    CWnd* pWnd = CMFCPropertyGridProperty::CreateInPlaceEdit(rectEdit, bDefaultFormat);

    m_varValue.vt = backVT;

    return pWnd;
}

BOOL CMFCPropertyGridInt64Property::OnSetCursor() const
{
    if (m_bInPlaceEdit)
    {
        return FALSE;
    }

    if (m_bIsValueList)
    {
        SetCursor(AfxGetApp()->LoadStandardCursor(IDC_IBEAM));
        return TRUE;
    }

    switch (m_varValue.vt)
    {
    case VT_I8:
    case VT_UI8:
        SetCursor(AfxGetApp()->LoadStandardCursor(IDC_IBEAM));
        return TRUE;
    }

    return FALSE;
}

BOOL CMFCPropertyGridInt64Property::PushChar(UINT nChar)
{
    VARTYPE backVT = m_varValue.vt;
    m_varValue.vt = VT_I4;

    BOOL b = CMFCPropertyGridProperty::PushChar(nChar);

    m_varValue.vt = backVT;

    return b;
}


HBRUSH CMFCPropertyGridInt64Property::OnCtlColor(CDC* pDC, UINT nCtlColor)
{
    VARTYPE backVT = m_varValue.vt;
    m_varValue.vt = VT_I4;

    HBRUSH b = CMFCPropertyGridProperty::OnCtlColor(pDC, nCtlColor);

    m_varValue.vt = backVT;

    return b;
}

CString CMFCPropertyGridInt64Property::FormatProperty()
{
    ASSERT_VALID(this);
    ASSERT_VALID(m_pWndList);

    COleVariant& var = m_varValue;
    ASSERT(var.vt == VT_I8 || var.vt == VT_UI8);

    CString strVal;

    switch (var.vt)
    {
    case VT_I8:
        strVal.Format(_T("%I64d"), var.llVal);
        break;

    case VT_UI8:
        strVal.Format(_T("%I64u"), var.ullVal);
        break;
    }

    return strVal;
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接