【问题标题】:CMFCPropertyGrid: How to catch dropdown event of combobox propertyCMFCPropertyGridctrl:如何捕获组合框属性的下拉事件
【发布时间】:2021-12-06 09:50:21
【问题描述】:

我有 CMFCPropertyGrid 控件,我已向其中添加了带有 CMFCPropertyGridProperty::AddOption() 的 Combobox 属性:

    foreach(auto i, list)
    {
        str.Format(_T("<%s> %s"), i.first, i.second);
        pProp->AddOption(str);
    }

现在,当用户在此CMFCPropertyGrid 中下拉列表时,我需要执行一些代码。

如果CBN_DROPDOWN 是对话框窗口中的组合框控件,我会使用它(它有 ID)。但是如果是CMFCPropertyGrid,我该怎么做呢?

【问题讨论】:

    标签: c++ visual-studio combobox mfc


    【解决方案1】:

    对于组合框样式的CMFCPropertyGridProperty,当用户单击控件右上角附近的向下箭头按钮(这会导致出现下拉列表)时,框架会调用OnClickButton 成员。

    因此,为您的控件创建一个类(派生自CMFCPropertyGridProperty)并覆盖OnClickButton 成员以添加您要运行的代码。以下是您可以执行的操作的概要:

    class MyComboControl : public CMFCPropertyGridProperty
    {
        public:
            // Constructor: add some options ...
            MyComboControl(void) : CMFCPropertyGridProperty(L"Choice:", _variant_t(L""), L"Description Text") {
                AllowEdit(FALSE);
                for (int i = 0; i < 3; ++i) {
                    CString text;
                    text.Format(L"Option #%d", i);
                    AddOption(text.GetString());
                    if (i == 0) SetValue(text.GetString());
                }
            }
            // Override to handle the dropdown activation ...
            void OnClickButton(CPoint pt) override {
                //... Add any pre-drop code here.
                CMFCPropertyGridProperty::OnClickButton(pt); // Call base class
                //... Add any post-drop code here
            }
    };
    

    【讨论】:

      【解决方案2】:

      MFC 将通过AFX_WM_PROPERTY_CHANGED 通知父窗口属性更改

      发送给属性网格的所有者 控制 (CMFCPropertyGridCtrl) 当用户更改 选定的属性。

      BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
          ON_REGISTERED_MESSAGE(AFX_WM_PROPERTY_CHANGED, OnPropertyChanged)
      END_MESSAGE_MAP()
      
      afx_msg LRESULT CMyDialog::OnPropertyChanged(WPARAM wparam, LPARAM lparam)
      {
          if (!lparam)
              return 0;
          auto prop = reinterpret_cast<CMFCPropertyGridProperty*>(lparam);
          if (prop != m_pProp) 
          {
              auto str_variant = prop->GetValue();
              CString str;
              if(str_variant.vt == VT_BSTR)
                  str = CString(str_variant.bstrVal);
          }
          return 0;
      }
      

      如果您使用网格控件有多个控件,您希望将pProp 声明为类成员m_pProp,以便可以测试其值。

      【讨论】:

      • 当下拉列表打开时是否会发送该消息?当列表关闭并更改选择时,似乎就是这样。
      • 是的,更改后发送。对于可编辑的组合框,用户可以修改文本,然后单击下拉按钮,在这种情况下会报告正确的值。否则我不认为这意味着任何覆盖。
      猜你喜欢
      • 1970-01-01
      • 2011-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-01
      相关资源
      最近更新 更多