简体   繁体   中英

Accessing member variables of MFC dialog in non-member function

I'm working on a MFC dialog and I'm not sure how to access object's member variables (Edit controls, buttons, check boxes, etc) from a non-member function.

Since the object is created in whatever .cpp, and all the object events are handled in whateverDlg.cpp, and the latter #include 's the former, I can't access Dlg's members by conventional means.

Example for clarification:

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
    //...
}

In other words: What should I do to access m_bEditControl (or any other dialog's member) from the non-member function?

If you want to keep GUI separated from logic, then you can keep your dialog class very thin, basically just for recognizing events that occur ( onBtnSomethingClick , onPaint , onCancel , etc.) and create a class that will be responsible for handling these events once they occur.

One of the simplest possible solutions would be to construct this kind of class by passing your dialog by reference to its constructor:

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

private:
    MainDlg& dlg_;
};

And your dialog class could instantiate object of your class:

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

private:
    MyClass* myClass_;
};

Just don't "spread" references to any GUI classes any further. If you need to directly access some members of your dialog, then you might consider redesigning your code - for example if you are writing method for creating new User s and you are thinking about accessing some text field of your dialog, then it seems to be much better idea, to "collect" input from dialog members and pass it to this kind of function independantly from your dialog class.


To your problem: if you have a helper non-member function that needs to use dialog's CEdit member, then you can change void nonMember() to void nonMember(CEdit& m_bEditControl) and pass the reference to this member when calling it in member function: nonMember(m_bEditControl); But note that that kind of approach is wrong.

In other words: this seems to be a bad design :

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

void MainDlg::someMethod()
{
    nonMember(m_bEditControl);
}

and this seems to be much better:

CString nonMember2()
{
    return L"something";
}

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

Hope this helps :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM