在所有Windows上使用DoDataExchange/Force Update控件在一个成员变量和多个控件之间共享数据

Share Data Between One Member Variable and Several Controls w/DoDataExchange /Force Update Controls on All Windows

本文关键字:控件 变量 成员 一个 数据 共享 之间 DoDataExchange Force Update Windows      更新时间:2023-10-16

我有一个VS 2005 C++MFC项目,它包含几个基于CDialog的窗口。该程序与自定义硬件进行通信,并在不同的窗口上显示不同的读数。使用名为CTools的类的名为ReadHardWare()的公共静态成员函数从硬件读取数据。ReadHardWare()将从硬件读取的数据放在一个具有全局作用域的数组中,每个窗口都可以从该数组中读取。在每个窗口上,我都有一个指示灯亮起,显示从硬件读取操作正在进行中。该指标是国家仪器Measurement Studio CNiButton类控件。CTools有一个名为m_read_in_progress_status的CNiButton类型的公共静态成员变量,我用它来识别读取操作是否正在进行(m_read_in.progress_ststatus.Value==1)或是否在进行(m_read_in_progress _status.Value==0)。我的目标是让所有打开的窗口上的所有读取指示器同时显示读取正在进行或未进行。我经常使用DoDataExchange将变量与控件连接起来,但始终是一对一的。在这种情况下,我希望几个控件与单个变量连接,并使用该变量自动更新。

我似乎有两个问题:

1) 我似乎只能让一个控件同时与变量连接。显然,变量共享数据的唯一控件是第一个实例化的(即打开的第一个窗口)

2) 如果我从打开的第二个窗口发送读取命令,不仅第二个窗上的读取指示器仍然不显示读取状态,而且第一个窗的读取指示器也不再显示读取状态。只有当我从打开的第一个窗口执行读取命令时,读取指示器才会工作。当第二个窗口发送读取命令时,第一个窗口似乎不想更新其控件。

所以我的问题是:

1) 如何允许两个不同窗口上的两个控件共享同一成员变量,并在该成员变量的值更改时立即更新?

2) 如何使ReadHardWare()成员函数(或其他事件)强制第一个窗口更新其控件,即使它不是主动调用该函数的窗口?

在当前情况下,第一个窗口是第二个窗口的父窗口。然而,情况并非总是如此。

下面是我的代码摘录。

//全局变量.cpp

NI::CNiButton CTools::m_read_in_progress_status;  

//Tools.h

class CTools  
{  
public:  
    static ReadHardWare();  
public:  
    static  NI::CNiButton m_read_in_progress_status;  
}   

//Tools.cpp

CTools::ReadHardWare()  
{  
    //Declare and initialize variables and other setup code is here  
    m_read_in_progress_status.Value == 1  //Set read in progress flag high  
    //Read operations here  
    m_read_in_progress_status.Value == 0  //Reset read in progress flag low  
}    

//FirstWindow.cpp

#include "Tools.h"  
#include "SecondWindow.h"  
void CFirstWindow::DoDataExchange(CDataExchange* pDX)  
{  
    CDialog::DoDataExchange(pDX);  
    DDX_Control(pDX, IDC_First_Window_Read_in_Progress_Indicator,   CTools::m_read_in_progress_status);  
}    

//SecondWindow.cpp

#include "Tools.h"  
#include "FirstWindow.h"  
void CSecondWindow::DoDataExchange(CDataExchange* pDX)  
{  
    CDialog::DoDataExchange(pDX);  
    DDX_Control(pDX, IDC_Second_Window_Read_in_Progress_Indicator, CTools::m_read_in_progress_status);  
}  

DDX_Control在对话框中的控件标识符和基于CWnd的对象的特定实例之间建立关联。我不确定共享表示两个窗口的按钮的同一对象是否是个好主意。我建议稍微修改一下设计。您应该为池读取操作状态创建一个计时器。如果状态发生更改,您将更新按钮。

class CTools  
{  
public:  
    static void ReadHardWare();
public:  
    static int m_read_in_progress_status;  
}   
class CFirstWindow: CDialog
{
public:
    void OnTimer(UINT nIDEvent)
    {
        if(m_read_in_progress_status != CTools::m_read_in_progress_status)
        {
            m_read_in_progress_status = CTools::m_read_in_progress_status;
            m_button.SetCheck(m_read_in_progress_status);
        }
    }
private:
    int m_read_in_progress_status;  // Cached status
    NI::CNiButton m_button;
};