【问题标题】:Accessing member variables of MFC dialog in non-member function在非成员函数中访问 MFC 对话框的成员变量
【发布时间】:2013-01-30 11:47:41
【问题描述】:

我正在处理 MFC 对话框,但我不确定如何从非成员函数访问对象的成员变量(编辑控件、按钮、复选框等)。

由于对象是在whatever.cpp中创建的,而所有对象事件都在whateverDlg.cpp中处理,而后者#include是前者,所以我无法访问Dlg的成员通过常规方式。

说明示例:

void BlahDlg::OnBnClickedblah()
{
    //...
    CString text = L"blahblahblah";
    m_bEditControl.SetWindowTextW(text.GetBuffer()); //works fine
    //...
}

void nonMember()
{
    //...
    CString text = L"blahblahblah";
    m_bEditControl.SetWindowTextW(text.GetBuffer()); //m_bEditControl is unknown
    //...
}

换句话说:我应该怎么做才能从非成员函数访问m_bEditControl(或任何其他对话框的成员)?

【问题讨论】:

    标签: c++ visual-c++ object mfc scope


    【解决方案1】:

    如果你想保持 GUI 与逻辑分离,那么你可以保持你的对话框类非常薄,基本上只是为了识别发生的事件(onBtnSomethingClick、onPaint、onCancel 等)并创建一个类将负责处理这些事件一旦发生。

    最简单的解决方案之一是通过将对话框传递给它的构造函数来构造这种类:

    class MyClass
    {
    public:
        MyClass(MainDlg& dlg) : dlg_(dlg) { }
    
    private:
        MainDlg& dlg_;
    };
    

    你的对话类可以实例化你的类的对象:

    class MainDlg : public CDialog
    {
    public:
        BOOL MainDlg::OnInitDialog()
        {
            //...
            myClass_ = new MyClass(*this);
            return TRUE;
        }
        ~MainDlg()
        {
            //...
            delete myClass_;
        }
    
    private:
        MyClass* myClass_;
    };
    

    只是不要进一步“传播”对任何 GUI 类的引用。如果您需要直接访问对话框的某些成员,那么您可能会考虑重新设计代码 - 例如,如果您正在编写创建新 Users 的方法并且您正在考虑访问对话框的某些文本字段,那么看起来更好的主意是,从对话框成员“收集”输入并将其传递给这种函数,而与您的对话框类无关。


    对于您的问题:如果您有一个需要使用对话框的CEdit 成员的辅助非成员函数,那么您可以将void nonMember() 更改为void nonMember(CEdit& m_bEditControl) 并在成员函数中调用它时传递对该成员的引用:nonMember(m_bEditControl); 但请注意,这种做法是错误的。

    换句话说:这似乎是一个糟糕的设计:

    void nonMember(CEdit& m_bEditControl)
    {
        CString text = L"something";
        m_bEditControl.SetWindowTextW(text.GetBuffer());
    }
    
    void MainDlg::someMethod()
    {
        nonMember(m_bEditControl);
    }
    

    这似乎好多了:

    CString nonMember2()
    {
        return L"something";
    }
    
    void MainDlg::someMethod()
    {
        CString str = nonMember2();
        m_bEditControl.SetWindowTextW(str.GetBuffer());
    }
    

    希望这会有所帮助:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-29
      • 1970-01-01
      • 2022-01-03
      • 2013-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多