我有一个VS 2005 C ++ MFC项目,其中包含几个基于CDialog的窗口。该程序与自定义硬件通信,并在不同的窗口上显示不同的读数。使用名为CTools的类的名为ReadHardWare()的公共静态成员函数从硬件读取数据。 ReadHardWare()将从硬件读取的数据放在具有全局范围的数组中,每个窗口都能够从该数组中读取。在每个窗口上,我有一个指示灯亮起,表示正在进行硬件操作读取。该指标是National Instruments Measurement Studio CNiButton类控件。 CTools有一个名为m_read_in_progress_status的CNiButton类型的公共静态成员变量,我用它来识别读操作是否正在进行(m_read_in_progress_status.Value == 1)或不是(m_read_in_progress_status.Value == 0)。我的目标是让所有打开的窗口上的所有读取指示器同时显示读取是否正在进行中。我经常使用DoDataExchange将变量与控件连接,但始终是一对一的。在这种情况下,我想要几个控件连接单个变量,并自动更新该变量。
我似乎有两个问题:
1)似乎我只能让一个控件同时连接变量。显然,变量与数据共享的唯一控件是第一个实例化的控件(即第一个窗口打开)
2)如果我从打开的第二个窗口发送读取命令,则不仅第二个窗口上的读取指示器仍然不显示读取状态,而且第一个窗口上的读取指示器也不再显示。任何读取指示器工作的唯一时间是从第一个窗口打开时执行读取命令。当第二个窗口发送读取命令时,第一个窗口似乎不想更新其控件。
所以我的问题是:
1)如何允许两个不同窗口上的两个控件共享同一个成员变量,并在该成员变量的值发生变化时立即更新?
2)如何使ReadHardWare()成员函数(或其他一些事件)强制第一个窗口更新其控件,即使它不是主动调用该函数的窗口?
在当前情况下,第一个窗口是第二个窗口的父窗口。然而,并非总是如此。
以下是我的代码的摘录。
// Globalvariables.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);
}
答案 0 :(得分:0)
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;
};