?? itkplcdlg.cpp
字號:
//
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 + -