Search code examples
visual-c++structmfccdialog

Associated dialog controls with a structure member variables


I have this struct definition:

typedef struct tagPublicTalkInfo
{
    CString     strAwayCong1;
    CString     strAwayCong2;
    CString     strAwayBrother1;
    CString     strAwayBrother2;
    CString     strChairman;
    CString     strCong;
    CString     strHosp;
    CString     strReader;
    CString     strBrother;
    CString     strTheme;
    CString     strWTConductor;          
    CString     strInterpreter;          
    CString     strMisc;                 
    CString     strWatchtowerStudyTheme; 
    CString     strServiceTalkTheme;     
    CString     strBibleVersesReader;    
    CString     strVideoHost;            
    CString     strVideoCohost;          
    CString     strOpeningPrayer;        
    CString     strClosingPrayer;        
    int         iSongStart;              
    int         iSongMiddle;             
    int         iSongEnd;                
    int         iThemeNumber;            

} S_TALK_INFO;

This structure is passed into a dialog and retrieved like this:

void CWeekendMeetingDlg::SetWeekendMeetingInfo(S_TALK_INFO &rsTalkInfo)
{
    m_sWeekendMeetingInfo = rsTalkInfo;
}

S_TALK_INFO CWeekendMeetingDlg::GetWeekendMeetingInfo()
{
    return m_sWeekendMeetingInfo;
}

At the moment I am mapping the dialog controls to distinct variables and transfer to / from my structure. For example:

m_strChairman = m_sWeekendMeetingInfo.strChairman;
m_sWeekendMeetingInfo.strChairman = m_strChairman;

Is possible to map my controls directly to the structure member CString variables or would that be considered bad practice?


Solution

  • Yes, as Adrian says, you don't have to confine yourself to using the variables that the wizard would hand you. I used my test project to do this with the about dialog.

    struct data_type {
        CString a_data;
        CString b_data;
    };
    
    class CAboutDlg : public CDialogEx
    {
        data_type& dlg_data;
    public:
        CAboutDlg(data_type&);
        //CString dummy;
        enum { IDD = IDD_ABOUTBOX };
    protected:
        virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    protected:
        DECLARE_MESSAGE_MAP()
    public:
    };
    
    CAboutDlg::CAboutDlg(data_type& data) : CDialogEx(IDD_ABOUTBOX), dlg_data(data)
    {
    }
    
    void CAboutDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialogEx::DoDataExchange(pDX);
        DDX_Text(pDX, IDC_EDIT1_ABOUT, dlg_data.a_data);
        DDX_Text(pDX, IDC_EDIT2_ABOUT, dlg_data.b_data);
    }
    
    // App command to run the dialog
    void CMFCApplicationApp::OnAppAbout()
    {
        data_type data{ L"this", L"that" };
        CAboutDlg aboutDlg(data);
        aboutDlg.DoModal();
        assert(false);
    }
    

    Here I passed a reference to the external data to work on it directly. Because of the DoDataExchange mechanism, The data will only be modified if the user pushes OK. I added the first DDX_Text handler with the wizard, hence the commented value dummy. I just copied and pasted that handler to add the second.

    I put the assert in the app command so the program would break there and could examine the data.