⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfcstatusdlg.cpp

📁 介绍控制器运动的例子
💻 CPP
字号:
// MFCStatusDlg.cpp : implementation file
//

#include "stdafx.h"
#include "MFCStatus.h"
#include "MFCStatusDlg.h"
#include "ReadStatus.h" // **ADDED** The Event Class

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMFCStatusDlg dialog

CMFCStatusDlg::CMFCStatusDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CMFCStatusDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMFCStatusDlg)
	m_Transport = 2;
	m_BusType = FALSE;
	m_lblConnected = _T("Disconnected");
	m_Ver = _T("v?.?.?.?");
	m_BPS = 38400;
	m_CardNbr = 0;
	m_Clock = -1;
	m_Delta1 = -1;
	m_Delta2 = -1;
	m_GetPPrim = _T("6160");
	m_GetToPrim = 0;
	m_IP = _T("0.0.0.0");
	m_Port = 1;
	m_SetToPrim = 0;
	m_SetPPrim = 6160;
	m_Avg1 = -1;
	m_Avg2 = -1;
	m_Clock2 = -1;
	m_Max1 = -1;
	m_Max2 = -1;
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

  // **ADDED** 
  // Create Interfaces using Prog ID
  m_Cntl = new IControl;
  m_Cntl->CreateDispatch(_T("BoxBridge.Control.1"));
  m_Stat = new IStatus;
  m_Stat->CreateDispatch(_T("BoxBridge.Status.1"));

  // Initialize working data
  m_workerEvent = NULL;
  m_StopWork = true;
  m_lastACRtic = 0;
  m_totACRtic = 0;
  m_ndxACRtic = 0;
  m_lastPCtic = 0;
  m_totPCtic = 0;
  m_ndxPCtic = 0;
  _LARGE_INTEGER x;
  QueryPerformanceFrequency(&x);    // counts per second for timer
  m_secPCtic = x.QuadPart * 0.001;  // use this number to calculate msec for PC counter
  // **ADDED**
}

// **ADDED** 
CMFCStatusDlg::~CMFCStatusDlg()
{
  // Need to Clean up COM
  if(m_Cntl){
    m_Cntl->Disconnect();
    delete m_Cntl;
  }
  if(m_Stat){
    m_Stat->Disconnect();
    delete m_Stat;
  }

  m_StopWork = true;
  if(m_workerEvent){
    delete m_workerEvent;
  } 
  // CoUninitialize();       // Clean up of COM done automatically by MFC
}
// **ADDED** 

void CMFCStatusDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMFCStatusDlg)
	DDX_Radio(pDX, IDC_RDO_TRANSPORT, m_Transport);
	DDX_Check(pDX, IDC_CHK_PCI, m_BusType);
	DDX_Text(pDX, IDC_LBL_CONNECT, m_lblConnected);
	DDX_Text(pDX, IDC_LBL_VER, m_Ver);
	DDX_Text(pDX, IDC_TXT_BPS, m_BPS);
	DDX_Text(pDX, IDC_TXT_CARDNBR, m_CardNbr);
	DDX_Text(pDX, IDC_TXT_CLOCK, m_Clock);
	DDX_Text(pDX, IDC_TXT_DELTA1, m_Delta1);
	DDX_Text(pDX, IDC_TXT_DELTA2, m_Delta2);
	DDX_Text(pDX, IDC_TXT_GETPPRIM, m_GetPPrim);
	DDX_Text(pDX, IDC_TXT_GETTOPRIM, m_GetToPrim);
	DDX_Text(pDX, IDC_TXT_IP, m_IP);
	DDX_Text(pDX, IDC_TXT_PORT, m_Port);
	DDV_MinMaxLong(pDX, m_Port, 1, 35);
	DDX_Text(pDX, IDC_TXT_SETOPRIM, m_SetToPrim);
	DDX_Text(pDX, IDC_TXT_SETPPRIM, m_SetPPrim);
	DDX_Text(pDX, IDC_TXT_AVG1, m_Avg1);
	DDX_Text(pDX, IDC_TXT_AVG2, m_Avg2);
	DDX_Text(pDX, IDC_TXT_CLOCK2, m_Clock2);
	DDX_Text(pDX, IDC_TXT_MAX1, m_Max1);
	DDX_Text(pDX, IDC_TXT_MAX2, m_Max2);
	DDX_Control(pDX, IDC_PROG_ACRCLOCK, m_ProgClock);
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CMFCStatusDlg, CDialog)
	//{{AFX_MSG_MAP(CMFCStatusDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BTN_CONNECT, OnBtnConnect)
	ON_BN_CLICKED(IDC_BTN_SETPRIM, OnBtnSetPrim)
	ON_BN_CLICKED(IDC_BTN_GETPRIM, OnBtnGetPrim)
	ON_BN_CLICKED(IDC_BTN_CLOCK, OnBtnClock)
	//}}AFX_MSG_MAP
  ON_MESSAGE(WMU_UpdateClock,OnUpdateClock)   // **ADDED**
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMFCStatusDlg message handlers

BOOL CMFCStatusDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CMFCStatusDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CMFCStatusDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

// **ADDED** 
// Code behind buttons
//
void CMFCStatusDlg::OnBtnConnect() 
{
  try{
  //******************
  // Connect to the Device on all interfaces
  UpdateData();

  m_Ver = CString("v") + m_Cntl->GetBstrVersion();  // Version

  m_Cntl->SetNBPS(m_BPS);               // Set BPS
  m_Cntl->SetNPort(m_Port);             // Set Port
  m_Cntl->SetBstrIP(m_IP);              // Set IP Address
  m_Cntl->SetNBus(m_BusType?1:0);       // Set Bus, checked(true) is ISA, else PCI
  m_Cntl->Connect(m_Transport,m_CardNbr);//Connect to Transport
  m_CardNbr = m_Cntl->GetNCard();       // One way to use USB is to grab the first unit, but then need to directly connect after that

  m_Stat->SetNStatusWaitRate(7);        // Minimum time between status events
  m_Stat->SetNBPS(m_BPS);               // Set BPS
  m_Stat->SetNPort(m_Port);             // Set Port
  m_Stat->SetBstrIP(m_IP);              // Set IP Address
  m_Stat->SetNBus(m_BusType?1:0);       // Set Bus, checked(true) is ISA, else PCI
  m_Stat->Connect(m_Transport,m_CardNbr);//Connect to Transport

  if(!(m_Cntl->GetIsOffline() || m_Stat->GetIsOffline())) // Verify Connection
    m_lblConnected = _T("Connected");

  UpdateData(FALSE);

  // *** 
  // Error Handling should go everywhere a call to Communications Server is made 
  // In this sample it is only placed here to aid readablility.
  // ***
  // Error Handling - the errors specifically thrown by Communications Server
  // show up as COM exceptions and can be caught with the COleDispatchException class.
  }catch(COleDispatchException* e) {
    ostringstream errmsg;
    unsigned short errnbr = e->m_scError;
    errmsg << "ERROR NO: " << hex << e->m_scError << dec << "(" << errnbr << ")\nERROR DESC: " << string(e->m_strDescription) << "\nERROR INTERFACE: " << string(e->m_strSource);
    MessageBox(errmsg.str().c_str(), "COM Error", MB_OK);
	}
	catch(CException *e) { 
		TCHAR szCause[1024];
		e->GetErrorMessage(szCause, 1024);   
    MessageBox(szCause, "non-COM Error", MB_OK);
	}
}

void CMFCStatusDlg::OnBtnSetPrim() 
{
  //******************
  // Assign a value to a p_Parm
  UpdateData();

  // Set the ACR p_Parm in first parameter to value in second parameter using a Binary call
  m_Cntl->SetParmLong(m_SetPPrim,m_SetToPrim,TRUE);

  UpdateData(FALSE);
}

void CMFCStatusDlg::OnBtnGetPrim() 
{
  //******************
  // Get a value from a p_Parm (extract from a safearray)

  SAFEARRAY* pSA;
  long lBound = 0; 
  CComVariant vItem;  // The CComVariant is found in the atlbase.h include file
  CComVariant status; // it will clean up SAFEARRAY when it goes out of scope.

  UpdateData();

  // Get the value of the p_Parm, returned in a safearray
  status = m_Stat->GetACRCustom(CString(_T("P")) + m_GetPPrim);

  if(status.vt & VT_ARRAY){ 
    pSA = status.parray;
    SafeArrayGetElement(pSA, &lBound, &vItem);
    if(vItem.vt!=VT_EMPTY) 
      m_GetToPrim = vItem.lVal;
  }else
    m_GetToPrim = -1;

  UpdateData(FALSE);
}

void CMFCStatusDlg::OnBtnClock() 
{
  //******************
  // Start Event Generator to update global clock
  UpdateData();

  if(m_StopWork){ // Thread must not have started
    m_StopWork = false;
	  m_workerEvent = new ReadStatus(this);
  }
}

LONG CMFCStatusDlg::OnUpdateClock(UINT,LONG xtime)
{
  //******************
  // Update the clock
  // This method is called by the ReadAlert Method in the ReadStatus class,
  // when the Communications Server finds there is new data to be read.  The
  // ReadAlert Method reads that data (the global system clock on the ACR)
  // and passes it to this method.  In this method, the following fields are
  // updated:
  // m_Clock  :This is the time reported by the ACR (global system clock)
  //
  // m_Delta1 :If the m_Clock value is greater than the last known  ACR
  //            clock time, the difference goes in here.
  //
  // m_Avg1   :All the m_Delta1 times are added up and divided by the number
  //            of m_Delta1 times, creating an average delta time.  This is
  //            an easier number to read on the screen than any single m_Delta1
  //            value, since they (the m_Delta1 data) change very quickly.
  //            
  // m_Max1   :The highest m_Delta1 is captured here. To eliminate early spikes, 
  //            the first 100 measurements are discarded.
  //
  // m_ProgClock is the progress bar displaying m_Delta1 when it is between 0 and 100 msec.
  //
  // The second set of numbers uses the PC clock as a base instead of the passed
  // in ACR system clock.  The deltas of the two clocks can differ if the ACR was
  // feeding data, but the PC was unable to work fast enough to update it, or if
  // the data from the ACR was not getting a changed updated as fast as the PC.
  //
  UpdateData();

  m_Clock = xtime;
  if(m_Clock > m_lastACRtic && m_lastACRtic != 0){
    m_Delta1 = m_Clock - m_lastACRtic;
    m_totACRtic += m_Delta1;
    ++m_ndxACRtic;
    m_Avg1 = m_totACRtic / m_ndxACRtic;
    if(m_ndxACRtic > 100)         // ignore start up numbers
      if(m_Max1 < m_Delta1) m_Max1 = m_Delta1;
  }
  if(m_Delta1>0 && m_Delta1<100)
    m_ProgClock.SetValue(m_Delta1);
  m_lastACRtic = m_Clock;

  _LARGE_INTEGER PCtic;
  QueryPerformanceCounter(&PCtic);
  m_Clock2 = PCtic.QuadPart / m_secPCtic;
  if(m_Clock2 > m_lastPCtic && m_lastPCtic != 0){
    m_Delta2 = m_Clock2 - m_lastPCtic;
    m_totPCtic += m_Delta2;
    ++m_ndxPCtic;
    m_Avg2 = m_totPCtic / m_ndxPCtic;
    if(m_ndxPCtic > 100)         // ignore start up numbers
      if(m_Max2 < m_Delta2) m_Max2 = m_Delta2;
  } 
  m_lastPCtic = m_Clock2;

  UpdateData(FALSE);

  return 0;
}
// **ADDED** 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -