MFC :: 使用结构传递数据

发布于 2024-12-28 10:36:33 字数 2802 浏览 2 评论 0原文

所以我有一个正在使用的 MFC 对话框程序。对话框已编写,但现在我很难在对话框之间传递数据。我在从 CWinApp 派生的类中设置了以下结构 _dlgDataHandler ,并为指向此类型的指针创建了一个“新”语句。

//.......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 有什么......可以吗?

So I have this MFC dialog program I am working with. The dialogs are written but now I am having difficulty passing data around from dialog to dialog. I have the following structure _dlgDataHandler set up in a class derived from CWinApp and have have created a "new" statement for a pointer to this type.

//.......SRK.h file

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 A pointer to a new dataHandler created in this block about 2/3 the way down

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

In the dialog .cpp files, there are five, I need to be able to get data from the AFX variables "m_" and load them into this dataHandler Structure (or another one like it) so that they can be used in other dialogs and parts of the program, specifically my actual code when all the dialog data collection is done. Someone said to use AfxGetApp() so that I could have a handle on the current instance but I do not understand what they are talking about. And yes I have read about it in many forums, I just don't get it. I further realize this is probably not the best way to do it. I am trying to learn MFC/OOP with what time I have available, but for now, I am just trying to get a handle on the basic process as I can tune it later once I understand how to collect and pass simple data around.

I further don't understand how calling AfxGetApp() will help me get a handle on the members of CSRK_App. It inherited CWinApps public members but AfxGetapp() can't see what CSRK_App has... can it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧梦荧光笔 2025-01-04 10:36:33

首先,解释一下您收到的 AfxGetApp 建议。使用“new”和指针需要一些额外的操作,但这基本上是使用全局变量来保存数据的结构。这不是做你想做的事情的最好方法。有很多陷阱。

AfxGetApp() 是一个 MFC 调用,它返回一个指向从 CWinApp 派生的主 App 类的指针。
如果要使用返回的指针,则需要使用以下命令将其转换为 CSRK_App* 指针:

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

然后你可以使用 pApp->dlgDataHandlerPtr->... 来访问你需要的变量。

现在,针对陷阱。其他人可能会插话为什么“new”和指针很有用,但与仅在 CSRK_App 类中使用局部变量 dlgDataHandler 相比,我认为这种方法没有任何优势。这会简化代码。

下一个问题是所有数据在结构中都是公开的。任何可以调用 AfxGetApp 的对话框类都可以读取或写入该结构中的任何数据。您无法控制访问。

此外,所有对话框类现在都必须包含 SRK_App.h,以便它们了解结构,并可以访问该 App 类中的所有其他变量。

一种更简洁、面向对象的方法是在单独的 .h 文件中声明数据的结构(类),该文件可以包含在对话框类中。然后,您可以将此数据的指针/引用传递到对话框类的构造函数中。对话框类不需要了解有关 App 类的任何信息。

对于更高级别的隔离,可以编写对话框类,以便它们仅获取在调用 .DoModal() 之前传入的 dlgDataHandler 类的副本,然后在 DoModal 调用返回 IDOK 后,App 类可以控制对话框中的哪些数据被更新到 dlgDataHandler 类中。这种方法的优点是,它确保无论对话框类如何编程,用户始终可以“取消”对话框而不修改任何数据。

First, to explain the AfxGetApp advice you have received. There is some extra hand-waving using 'new' and a pointer, but this is basically using a global variable for the structure that holds your data. This is not the best way to do what you are trying to do. There are many pitfalls.

AfxGetApp() is an MFC call that returns a pointer to your main App class derived from CWinApp.
If you want to use that returned pointer, you need to cast it as a CSRK_App* pointer with:

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

Then you can use pApp->dlgDataHandlerPtr->... to access the variables you need.

Now, for the pitfalls. Someone else may chime in with a reason why the 'new' and the pointer are helpful, but I do not see any advantage to this approach as compared to just having a local variable dlgDataHandler inside your CSRK_App class. That would simplify the code.

The next issue is that all your data is public in a struct. Any dialog class that can call AfxGetApp can read or write any data in that struct. You have no way to control access.

Also, all of your dialog classes must now include SRK_App.h so they know the structure, and have access to all other variables in that App class.

A cleaner, object-oriented approach would be to declare the struct (class) for the data in a separate .h file that could be included in the dialog classes. Then, you would pass a pointer/reference to this data into the constructor of the dialog classes. The dialog class would have no need to know anything about the App class.

For an even higher level of segregation, the dialog classes can be written so they only get a copy of the dlgDataHandler class passed in before calling .DoModal(), and then after the DoModal call returns with IDOK, the App class can have control over which data from the dialog gets updated into the dlgDataHandler class. The advantage of this approach is that it insures that no matter how the dialog class is programed, the user can always "Cancel" the dialog without modifying any data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文