MFC :: передача данных с использованием структуры - PullRequest
0 голосов
/ 21 января 2012

Итак, у меня есть диалоговая программа MFC, с которой я работаю. Диалоги написаны, но теперь у меня возникают трудности с передачей данных из диалога в диалог. У меня есть следующая структура _dlgDataHandler, настроенная в классе, производном от CWinApp, и я создал «новый» оператор для указателя на этот тип.

// ....... файл SRK.h

class CSRK_App : public CWinApp
    {
public:

    CFSB_App();

     // added the following data structure for data passing withing the program

    typedef struct _dlgDataHandler {
      char RepetitionRadio[24];
          // another member
          // yet another member and so on as necessary
    } *dlgDataHandlerPtr;

      // extern dlgDataHandlerPtr dlgDataHandler;

// Overrides
     // ClassWizard generated virtual function overrides
     //{{AFX_VIRTUAL(CSRK_App)
     public:
     virtual BOOL InitInstance();
     //}}AFX_VIRTUAL

// Implementation

    //{{AFX_MSG(CSRK_App)
    // NOTE - the ClassWizard will add and remove member functions here.
        //    DO NOT EDIT what you see in these blocks of generated code !
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
 }; 

// ....... SRK.cpp Указатель на новый dataHandler, созданный в этом блоке примерно на 2/3 пути вниз

// CSRK_App initialization

BOOL CSRK_App::InitInstance()
{
AfxEnableControlContainer();

// Standard initialization
// If you are not using these features and wish to reduce the size
//  of your final executable, you should remove from the following
//  the specific initialization routines you do not need.
//SetRegistryKey(_T("Local AppWizard-Generated Aplications"));

#ifdef _AFXDLL
Enable3dControls();         // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic();   // Call this when linking to MFC statically
#endif

//CSRK_Dlg dlg;
CDialogMain dlg("SRK - Beta");    // added 12/27 **
m_pMainWnd = &dlg;

//const char* m_pszHelpFilePath = NULL;
//free((void*)m_pszHelpFilePath);
//m_pszHelpFilePath=_tcsdup(_T("c:\SRKHelp.rtf"));

// the following line added to allocate memory for the structure
    dlgDataHandlerPtr dlgDataHandler = new _dlgDataHandler;

dlg.SetWizardMode();          // added 12/27 **
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
    // TODO: Place code here to handle when the dialog is
    //  dismissed with OK
}
else if (nResponse == IDCANCEL)
{
    // TODO: Place code here to handle when the dialog is
    //  dismissed with Cancel
}

// Since the dialog has been closed, return FALSE so that we exit the
//  application, rather than start the application's message pump.
return FALSE;
}

В диалоговом окне .cpp файлов есть пять, мне нужно иметь возможность получать данные из переменных AFX "m_" и загружать их в эту структуру dataHandler (или другую подобную), чтобы их можно было использовать в другие диалоги и части программы, в частности мой реальный код, когда весь сбор данных диалога сделан. Кто-то сказал, чтобы использовать AfxGetApp (), чтобы я мог иметь дескриптор на текущем экземпляре, но я не понимаю, о чем они говорят. И да, я читал об этом на многих форумах, я просто не понимаю. Я также понимаю, что это, вероятно, не лучший способ сделать это. Я пытаюсь узнать MFC / OOP, сколько у меня есть времени, но сейчас я просто пытаюсь разобраться с базовым процессом, так как я могу настроить его позже, когда пойму, как собирать и передавать простые данные.

Я также не понимаю, как вызов AfxGetApp () поможет мне разобраться с членами CSRK_App. Он унаследовал общедоступные члены CWinApps, но AfxGetapp () не может видеть, что имеет CSRK_App ... не так ли?

1 Ответ

3 голосов
/ 21 января 2012

Сначала объясните полученный вами совет AfxGetApp. Есть некоторые дополнительные ручные помахивания с использованием «new» и указателя, но это в основном использует глобальную переменную для структуры, которая содержит ваши данные. Это не лучший способ сделать то, что вы пытаетесь сделать. Есть много подводных камней.

AfxGetApp () - это вызов MFC, который возвращает указатель на ваш основной класс приложения, полученный из CWinApp. Если вы хотите использовать этот возвращенный указатель, вам нужно привести его как указатель CSRK_App * с:

CSRK_App* pApp = static_cast <CSRK_App*> ( AfxGetApp());

Затем вы можете использовать pApp-> dlgDataHandlerPtr -> ... для доступа к нужным вам переменным.

Теперь о подводных камнях. Кто-то другой может вмешаться с причиной, по которой «new» и указатель полезны, но я не вижу никакого преимущества в этом подходе по сравнению с наличием локальной переменной dlgDataHandler внутри вашего класса CSRK_App. Это упростит код.

Следующая проблема заключается в том, что все ваши данные являются открытыми в структуре. Любой класс диалога, который может вызывать AfxGetApp, может читать или записывать любые данные в этой структуре. У вас нет возможности контролировать доступ.

Кроме того, все ваши диалоговые классы теперь должны включать SRK_App.h, чтобы они знали структуру и имели доступ ко всем другим переменным в этом классе приложения.

Более чистый, объектно-ориентированный подход состоял бы в том, чтобы объявить структуру (класс) для данных в отдельном файле .h, который мог бы быть включен в классы диалога. Затем вы должны передать указатель / ссылку на эти данные в конструктор диалоговых классов. Диалоговому классу не нужно ничего знать о классе App.

Для еще более высокого уровня сегрегации классы диалогов могут быть написаны так, что они получают только копию класса dlgDataHandler, переданную перед вызовом .DoModal (), а затем после того, как вызов DoModal возвращается с IDOK, класс App может иметь возможность контролировать, какие данные из диалога обновляются в классе dlgDataHandler. Преимущество этого подхода состоит в том, что он гарантирует, что независимо от того, как запрограммирован класс диалога, пользователь всегда может «отменить» диалог без изменения каких-либо данных.

...