Text position in CMFCPropertyGridCtrl

58 Views Asked by At

When editing (or clicking with AllowEdit set to false) the text is moved left:

enter image description here

But Visual Studio itself does not suffer from this issue:

enter image description here

The text stays exactly where it is before getting focus.

How do we achieve this?

I should clarify that my CMFCPropertyGridEditProperty is doing this:

CWnd* CMFCPropertyGridEditProperty::CreateInPlaceEdit(CRect rectEdit, BOOL& bDefaultFormat)
{
    CEdit *pEdit = (CEdit*)CMFCPropertyGridProperty::CreateInPlaceEdit(rectEdit, bDefaultFormat);
    CString strClassName;

    // Note that CreateInPlaceEdit can also return a CMFCMaskedEdit.
    // But we are only supporting the CEdit.
    GetClassName(pEdit->GetSafeHwnd(), strClassName.GetBuffer(_MAX_PATH), _MAX_PATH);
    strClassName.ReleaseBuffer();

    if (pEdit != NULL && strClassName == _T("Edit"))
        pEdit->SetLimitText(m_iTextLimit);

    return (CWnd*)pEdit;
}

But it does the same even if I use CMFCPropertyGridProperty.

To answer question 1 in the comments, I use the COLeVariant overload:

auto AddProperty = [&](CMFCPropertyGridProperty* pMeeting, CString strLabel, CString strValue)
    {
        if (pMeeting != nullptr)
        {
            COleVariant vString(strValue);
            //CMFCPropertyGridEditProperty* pProperty = nullptr;
            CMFCPropertyGridProperty* pProperty = nullptr;

            //pProperty = new CMFCPropertyGridEditProperty(strLabel, vString, L"", 0, 50);
            pProperty = new CMFCPropertyGridProperty(strLabel, vString, L"", 0);
            if (pProperty != nullptr)
            {
                pProperty->AllowEdit(false);
                pMeeting->AddSubItem(pProperty);
            }
        }
    };

To answer question 2, the answer is no. This is a property grid control dragged onto a CDialog in the resource IDE.


If I create a Visual Studio style MDI then the built-in prop grid on the right behaves. Click a cell and text does not move.

Add a prop grid to the about dialog and display about window:

about

Get same behaviour as for me in my dialog app.

1

There are 1 best solutions below

0
Andrew Truckle On BEST ANSWER

This is a working solution (for me on my PC) but I would still like more information about this matter.

I decided to use my CMFCPropertyGridEditProperty class after all with one minor tweak to CreateInPlaceEdit:

CWnd* CMFCPropertyGridEditProperty::CreateInPlaceEdit(CRect rectEdit, BOOL& bDefaultFormat)
{
    rectEdit.OffsetRect(3, 0);
    CEdit *pEdit = (CEdit*)CMFCPropertyGridProperty::CreateInPlaceEdit(rectEdit, bDefaultFormat);
    CString strClassName;

    // Note that CreateInPlaceEdit can also return a CMFCMaskedEdit.
    // But we are only supporting the CEdit.
    GetClassName(pEdit->GetSafeHwnd(), strClassName.GetBuffer(_MAX_PATH), _MAX_PATH);
    strClassName.ReleaseBuffer();

    if (pEdit != nullptr && strClassName == L"Edit")
        pEdit->SetLimitText(m_iTextLimit);

    return (CWnd*)pEdit;
}

I inserted this line to offset the rectangle:

rectEdit.OffsetRect(3, 0);

Now the text does not shift when I click on a property.


Things I have learned:

  • Using a property grid inside a CDialog causing the moving of the text.

Things I am curious about:

  • What is causing this issue?
  • Will offsetting by 3 pixels be correct for all PC configurations?
  • Can this issue be prevented to avoid the need of this workaround?

After more thinking on the matter I have come up with:

CWnd* CMFCPropertyGridEditProperty::CreateInPlaceEdit(CRect rectEdit, BOOL& bDefaultFormat)
{
    rectEdit.OffsetRect(::GetSystemMetrics(SM_CXDLGFRAME), 0);
    CEdit *pEdit = (CEdit*)CMFCPropertyGridProperty::CreateInPlaceEdit(rectEdit, bDefaultFormat);
    CString strClassName;

    // Note that CreateInPlaceEdit can also return a CMFCMaskedEdit.
    // But we are only supporting the CEdit.
    GetClassName(pEdit->GetSafeHwnd(), strClassName.GetBuffer(_MAX_PATH), _MAX_PATH);
    strClassName.ReleaseBuffer();

    if (pEdit != nullptr && strClassName == L"Edit")
        pEdit->SetLimitText(m_iTextLimit);

    return (CWnd*)pEdit;
}

I have adjust the first line of code to:

rectEdit.OffsetRect(::GetSystemMetrics(SM_CXDLGFRAME), 0);

I now use ::GetSystemMetrics(SM_CXDLGFRAME). To quote:

The thickness of the frame around the perimeter of a window that has a caption but is not sizable, in pixels. SM_CXFIXEDFRAME is the height of the horizontal border, and SM_CYFIXEDFRAME is the width of the vertical border.

This value is the same as SM_CXDLGFRAME.

I have reported this issue:

https://developercommunity.visualstudio.com/t/Using-CMFCPropertyGridCtrl-inside-a-CDia/10565729