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

📄 itkplcdlg.cpp

📁 工业强度的PLC模拟程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	//
	this->ShowWindow(SW_HIDE);
	
	//
	// If Timers are being used, then free up that timer as well
	//
	if (this->IsUsingTimers())
	{
		KillTimer(REGISTER_TIMER);
	}

	//
	// If we are sending unsolicited messages, wait for both threads
	// to expire. If not, wait for just the IO thread.
	//
	if (this->m_hUnsolThread)
	{
		HANDLE	hArray[2] = { this->m_hIoThread, this->m_hUnsolThread };


		this->m_bShutdown = TRUE;
		SetEvent(this->m_hNotifyEvt);

		WaitForMultipleObjects(2,
							   hArray,
							   TRUE,
							   FIVE_SECONDS);
	}
	else
	{
		WaitForSingleObject(this->m_hIoThread, FIVE_SECONDS);
	}

	//
	//  Free the critical section
	//
	DeleteCriticalSection(&this->m_Lock);

	CDialog::OnOK();
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | OnTriggers |
//
// Called when the user clicks the Timers button. This handler performs
// the DoModal() for the CTriggerDlg object.
//
void CItkPlcDlg::OnTriggers() 
{
	UINT	nTempRefresh;


	m_pdlgTriggers->m_nCurrentRefreshRate = this->m_nTimerRefreshRate;

	if (m_pdlgTriggers->DoModal() == IDOK)
	{
		m_pdlgTriggers->GetTimerMap((int *)&this->m_nTimerMap);
		nTempRefresh = this->m_nTimerRefreshRate;
		this->m_nTimerRefreshRate = m_pdlgTriggers->GetRefreshRate();

		//
		// If there are timers in the timer map, then get a Timer
		// from the system to process them.
		//
		if (m_pdlgTriggers->GetNumTimers() > 0)
		{
			//
			// If we are currently using timers, kill the current and
			// create a new one for the new refresh rate
			//
			if ((this->IsUsingTimers()) && 
				(nTempRefresh != this->m_nTimerRefreshRate))
			{
				KillTimer(REGISTER_TIMER);
				SetTimer(REGISTER_TIMER, this->m_nTimerRefreshRate, NULL);
			}
			else if (!this->IsUsingTimers())
			{			
				SetTimer(REGISTER_TIMER, this->m_nTimerRefreshRate, NULL);
			}

			this->IsUsingTimers(TRUE);
		}
		else
		{
			//
			// If we are currently using timers, then free the timer
			// to the system because we don't need it
			//
			if (this->IsUsingTimers())
			{
				KillTimer(REGISTER_TIMER);
			}

			this->IsUsingTimers(FALSE);
		}
	}
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | OnSettingsButton |
//
// Called when the user clicks the Settings button. This handler performs
// the DoModal() for the CSettingsDlg object. It also initializes the objects
// members 
//
void CItkPlcDlg::OnSettingsButton() 
{
	BOOL	bOldUnsol = this->m_bUnsolicited;


	if (IDOK == m_pdlgSettings->DoModal())
	{
		this->m_bUnsolicited = m_pdlgSettings->GetSendUnsol();
		this->m_dwRemoteStation = m_pdlgSettings->GetRemoteStation();
		this->m_dwLocalStation = m_pdlgSettings->GetLocalStation();
		this->m_dwUnsolFrequency = m_pdlgSettings->GetUnsolFrequency();
		this->m_bSourceStn = m_pdlgSettings->IsUsingSourceStation();
		this->m_bTransNum = m_pdlgSettings->IsUsingTransactionNumbers();

		if (m_pdlgSettings->IsSerial())
		{
			this->m_dwProtocol = SERIAL_PROTOCOL;
			this->m_szPortName = m_pdlgSettings->GetPortName();
			this->m_szPortMode = m_pdlgSettings->GetPortMode();
			this->GetBCCMask();
		}
		else if (m_pdlgSettings->IsUdpIp())
		{
			this->m_dwProtocol = UDPIP_PROTOCOL;
			this->m_szIpAddress = m_pdlgSettings->GetIpAddress();
			this->m_uPortNumber = m_pdlgSettings->GetPortNumber();
		}
		else
		{
			this->m_dwProtocol = TCPIP_PROTOCOL;
			this->m_szIpAddress = m_pdlgSettings->GetIpAddress();
			this->m_uPortNumber = m_pdlgSettings->GetPortNumber();
		}

		//
		// Check to see if we were not using unsolicited, but now we are
		//		OR
		// we were using unsolicited, but not now.
		//
		if (!bOldUnsol && this->m_bUnsolicited)
		{
			this->m_bShutdown = TRUE;
			SetEvent(this->m_hNotifyEvt);

			WaitForSingleObject(this->m_hIoThread, FIVE_SECONDS);

			this->m_hIoThread = NULL;
		}
		else if (bOldUnsol && !this->m_bUnsolicited)
		{
			HANDLE	hArray[2] = { this->m_hIoThread, this->m_hUnsolThread };


			this->m_bShutdown = TRUE;
			SetEvent(this->m_hNotifyEvt);

			WaitForMultipleObjects(2,
								   hArray,
								   TRUE,
								   FIVE_SECONDS);

			this->m_hIoThread = NULL;
			this->m_hUnsolThread = NULL;
		}

		//
		// Kick off the thread that actually does all the work. It will
		// create the unsolicited thread, if necessary.
		//
		this->m_bShutdown = FALSE;
		if (NULL == this->m_hIoThread)
		{
			DWORD	dwIoThreadId = 0;
			this->m_hIoThread = CreateThread(NULL,
							 				 0,
											 (LPTHREAD_START_ROUTINE)IoHandler, 
											 (LPVOID)this, 
											 0, 
											 &dwIoThreadId); 
		}
	}
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | OnShowStats |
//
// Displays and hides a modeless dialog box with the communications 
// statistics for the ITKPLC.
//
void CItkPlcDlg::OnShowStats() 
{
	if (FALSE == m_pdlgCommStats->m_bDisplayed)
	{
		m_pdlgCommStats->Create();

		//
		// Change the text on the button
		//
		SetDlgItemText(IDC_SHOW_STATS, "Hide Stats");
	}
	else
	{
		m_pdlgCommStats->CloseDialog();

		//
		// Change the text on the button
		//
		SetDlgItemText(IDC_SHOW_STATS, "Show Stats");
	}
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | OnDblclkPlcData |
//
// Called when the user double clicks in the PLC Memory Map window. This
// function determines which row was clicked and performs a DoModal for a
// CPlcMemDlg object. This object then allows the user to enter data to
// be written to the memory map of the PLC. It then updates the row and calls
// OnPaint to update the screen.
//
void CItkPlcDlg::OnDblclkPlcData() 
{
	int			nLoc;

	CPlcMemDlg	dlgPlcMem;

	CString		csDlgText;

	ChangedVal	*ChangedValuesMap;

	BOOL		bChangedFlag = FALSE;


	//
	// Get the row number that the user clicked on...
	//
	nLoc = m_DataList.GetCurSel();
	
	//
	// ...Pass that to the CPlcMemDlg object
	//
	dlgPlcMem.SetLocation(nLoc);

	if (dlgPlcMem.DoModal() != IDOK)
	{
		return;
	}

	//
	// Return a ChangedVal structure array containing what was changed
	//
	ChangedValuesMap = dlgPlcMem.GetChangedValues();

	//
	// Loop through the Changed Value array. If a value was modified,
	// then write it to the PLC memory map. If it didn't change, then
	// don't change the memory map.
	//
	for (int nOffset = 0; nOffset < REGISTERS_PER_ROW; nOffset++)
	{
		if (ChangedValuesMap[nOffset].bChanged == TRUE)
		{
			PlcMemory[nLoc*10 + nOffset] = ChangedValuesMap[nOffset].nNewVal;
			bChangedFlag = TRUE;
		}
	}

	//
	// Update the row in the memory map if anything changed
	//
	if (bChangedFlag)
	{
		this->UpdateRow(nLoc);

		//
		// Repaint the window
		//
		CDialog::OnPaint();
	}

	//
	// Set the focus back to the current row
	//
	m_DataList.SetCurSel(nLoc);
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | OnDatatypeAscii |
//
// Called when the user clicks the ASCII datatype view. This will set the view
// of the ITK PLC memory map to ASCII format with bytes swapped!!
//

void CItkPlcDlg::OnDatatypeAscii() 
{
	int nRow = 0;
	
	
	if (m_datatype == DT_ASCII)
	{
		//
		// Nothing has changed
		//
		return;
	}

	this->SetDlgItemText(IDC_REGISTER_LABELS, "  0      1      2      3      4      5      6      7      8      9");

	m_datatype = DT_ASCII;

	UpdateData(FALSE);
	
	//
	// Update the memory map with the new format
	//
	this->UpdateMemoryMap();	
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | OnDatatypeFloat |
//
// Called when the user clicks the Float datatype view. This will set the view
// of the ITK PLC memory map to IEEE float format.
//
void CItkPlcDlg::OnDatatypeFloat() 
{
	int nRow = 0;


	if (m_datatype == DT_FLOAT)
	{
		//
		// Nothing has changed
		//
		return;
	}

	this->SetDlgItemText(IDC_REGISTER_LABELS, "       0             2              4              6               8");

	m_datatype = DT_FLOAT;

	UpdateData(FALSE);

	//
	// Update the memory map with the new format
	//
	this->UpdateMemoryMap();
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | OnDatatypeHex |
//
// Called when the user clicks the Hex datatype view. This will set the view
// of the ITK PLC memory map to a 16-bit Hexadecimal format.
//
void CItkPlcDlg::OnDatatypeHex() 
{
	int nRow = 0;
	
	
	if (m_datatype == DT_HEX)
	{
		//
		// Nothing has changed
		//
		return;
	}

	this->SetDlgItemText(IDC_REGISTER_LABELS, "  0      1      2      3      4      5      6      7      8      9");

	m_datatype = DT_HEX;

	UpdateData(FALSE);
	
	//
	// Update the memory map with the new format
	//
	this->UpdateMemoryMap();
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | OnDatatypeLong |
//
// Called when the user clicks the Long datatype view. This will set the view
// of the ITK PLC memory map to unsigned 32-bit integer format.
//
void CItkPlcDlg::OnDatatypeLong() 
{
	int nRow = 0;


	if (m_datatype == DT_LONG)
	{
		//
		// Nothing has changed
		//
		return;
	}

	this->SetDlgItemText(IDC_REGISTER_LABELS, "       0             2              4              6               8");

	m_datatype = DT_LONG;

	UpdateData(FALSE);	

	//
	// Update the memory map with the new format
	//
	this->UpdateMemoryMap();
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | OnDatatypeSigned |
//
// Called when the user clicks the Signed datatype view. This will set the view
// of the ITK PLC memory map to signed integer format.
//
void CItkPlcDlg::OnDatatypeSigned() 
{
	int nRow = 0;


	if (m_datatype == DT_SIGNED)
	{
		//
		// Nothing has changed
		//
		return;
	}

	this->SetDlgItemText(IDC_REGISTER_LABELS, "  0      1      2      3      4      5      6      7      8      9");

	m_datatype = DT_SIGNED;

	UpdateData(FALSE);	

	//
	// Update the memory map with the new format
	//
	this->UpdateMemoryMap();
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | OnDatatypeUnsigned |
//
// Called when the user clicks the Unsigned datatype view. This will set the view
// of the ITK PLC memory map to unsigned integer format.
//
void CItkPlcDlg::OnDatatypeUnsigned() 
{
	int nRow = 0;


	if (m_datatype == DT_UNSIGNED)
	{
		//
		// Nothing has changed
		//
		return;
	}

	this->SetDlgItemText(IDC_REGISTER_LABELS, "  0      1      2      3      4      5      6      7      8      9");

	m_datatype = DT_UNSIGNED;

	UpdateData(FALSE);

	//
	// Update the memory map with the new format
	//
	this->UpdateMemoryMap();
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | UpdateMemoryMap |
//
// Updates the entire memory map.
//
void CItkPlcDlg::UpdateMemoryMap(unsigned char cClear /* default is FALSE */)
{
	unsigned int	nRow = 0,
					nReg = 0;


	switch(cClear)
	{
	case CLEAR_MEMORY:
		//
		// Set the memory map to 0. 
		// We multiply by 2 because memset clears bytes, not words.
		//
		memset(this->PlcMemory, 0, PLC_MEMORY_SIZE * 2);
		break;

	case SET_MEMORY:
		//
		//  Set the data array to equal there register number
		//
		for (nReg = 0; nReg < PLC_MEMORY_SIZE; nReg++ )
		{
			this->PlcMemory[nReg] = nReg;
		}
		break;

	case UPDATE_ONLY:
	default:
		break;
	}

	while (nRow <= NUM_ROWS)
	{
		this->UpdateRow(nRow);
		nRow++;
	}
}



⌨️ 快捷键说明

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