📄 document.cpp
字号:
CString strName (pGroup->GetName ());
// Generate a unique name for the group:
if (pServer->GenerateGroupName (strName))
pGroup->SetName (strName);
// Add the group to the selected server:
pServer->AddGroup (pGroup);
// Start the group (add all OPC items):
pGroup->Start ();
// Notify all views that new group has been added:
UpdateAllViews (NULL, HINT_ADD_GROUP, pGroup);
// Set the document modified flag:
SetModified ();
}
// **************************************************************************
// CloneGroup ()
//
// Description:
// Allows for the cloning of a new group from an existing group. The new
// group will be attached the server's group list.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKDocument::CloneGroup ()
{
// Get currently selected group object:
CKGroup *pSelGroup = GetSelectedGroup ();
ASSERT (pSelGroup != NULL);
// Clone group and save pointer to clone:
CKGroup *pNewGroup = pSelGroup->Clone ();
// If group was sucessfully cloned, indicated by non-NULL pointer, then
// we need to update group view and set document modified flag:
if (pNewGroup != NULL)
{
UpdateAllViews (NULL, HINT_ADD_GROUP, pNewGroup);
SetModified ();
}
}
// **************************************************************************
// EditGroup ()
//
// Description:
// Allows for the propeties of a group to be modified.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKDocument::EditGroup (CKGroup *pGroup)
{
// Check that pointer to group is not NULL (for debug only):
ASSERT (pGroup != NULL);
// Create a group property sheet. Pass it a pointer of group object to
// edit:
CKGroupPropertySheet psh (pGroup);
// Show as modal property sheet. If user hits "OK", we need to update
// group view and set document modified flag. Property sheet object will
// apply edits to group object if "OK" is hit.
if (psh.DoModal () == IDOK)
{
SetModified ();
UpdateAllViews (NULL, HINT_REFRESH_GROUPVIEW, NULL);
}
}
// **************************************************************************
// RemoveGroup ()
//
// Description:
// Allows for the removal of a group from a server item.
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKDocument::RemoveGroup (CKGroup *pGroup)
{
// Check that pointer to group is not NULL (for debug only):
ASSERT (pGroup != NULL);
// Notify all views that group has been removed:
UpdateAllViews (NULL, HINT_REMOVE_GROUP, pGroup);
// Set document modified flag:
SetModified ();
// Get the server this group belongs to:
CKServer *pServer = pGroup->GetParentServer ();
ASSERT (pServer != NULL);
// Remove the group from the server:
pServer->RemoveGroup (pGroup);
}
// **************************************************************************
// AddItem ()
//
// Description:
// Allows for the addition of a group's item(s).
//
// Parameters:
// none
//
// Returns:
// void
// **************************************************************************
void CKDocument::AddItem ()
{
// Get currently selected group:
CKGroup *pGroup = GetSelectedGroup ();
ASSERT (pGroup != NULL);
// Get pointer to server that selected group belongs to:
CKServer *pServer = pGroup->GetParentServer ();
ASSERT (pServer != NULL);
// Create an item add dialog. Pass it a pointer to the group object
// items are to be added to, and the associated OPC Server's browser
// interface:
CKItemAddDlg dlg (pGroup, pServer->GetIBrowse ());
// Show as modal dialog. If user hits "OK", we need to add items to
// project:
if (dlg.DoModal () == IDOK)
{
// Get the number of items to add specified in dialog:
int cnItems = dlg.GetItemCount ();
// If number of items is non-zero, then add them to project:
if (cnItems > 0)
{
// Get an object array containing the list of items to be added:
CObArray &cList = dlg.GetItemList ();
// If the number of items is large, then use a worker thread
// to add them:
if (cnItems > LARGE_ADDITEM_COUNT)
{
// Update status bar to indicate that we are adding items:
CKStatusBarText cText (IDS_ADDING_ITEMS);
// Create and fill a structure to pass to worker thread that
// contains the items to add and specifies the "add items" task:
WORKERTHREADARG tArg;
tArg.eTask = WORKERTHREADARG::ADD_ITEMS;
tArg.pvObjectA = (void *)&cList;
tArg.pvObjectB = (void *)&cnItems;
// Run a worker thread to add the items:
RunWorkerThread (&tArg);
}
// Else if number of items is small, add them directly:
else
pGroup->AddItems (cList, cnItems);
// Notify all views that item has been added:
UpdateAllViews (NULL, HINT_ADD_ITEM, &cList);
// Set document modified flag:
SetModified ();
}
}
}
// **************************************************************************
// AddItem ()
//
// Description:
// Allows for the addition of a group's item(s).
//
// Parameters:
// CObArray &cList Object array of items to add.
// DWORD dwCount Number of items in cList.
//
// Returns:
// void
// **************************************************************************
void CKDocument::AddItems (CObArray &cList, DWORD dwCount)
{
// Get the currently selected group:
CKGroup *pGroup = GetSelectedGroup ();
ASSERT (pGroup != NULL);
// Add the items to the group:
pGroup->AddItems (cList, dwCount);
// Notify all views that items have been added:
UpdateAllViews (NULL, HINT_ADD_ITEM, &cList);
// Set the document modified flag:
SetModified ();
}
// **************************************************************************
// RemoveItems ()
//
// Description:
// Allows for the removal of items on the selected group.
//
// Parameters:
// CObArray &cList Object array of items to remove.
// DWORD dwCount Number of items in cList.
//
// Returns:
// void
// **************************************************************************
void CKDocument::RemoveItems (CObArray &cList, DWORD dwCount)
{
// Check that we specify a non-zero number of items (for debug only):
ASSERT (dwCount > 0);
// Get the currently selected group:
CKGroup *pGroup = GetSelectedGroup ();
ASSERT (pGroup != NULL);
// Remove the items from the group:
pGroup->RemoveItems (cList, dwCount);
// Update the group view by reselecting the group:
UpdateAllViews (NULL, HINT_SELECT_GROUP, (CObject *)pGroup);
// Set the document modified flag:
SetModified ();
}
// **********************************************************************
// Worker Threads
// **********************************************************************
// **************************************************************************
// RunWorkerThread ()
//
// Description:
// Creates a worker thread to perform a specified task. This function will
// block until worker thread completes its task.
//
// Parameters:
// WORKERTHREADARG *pArg Pointer to a structure that contains information
// about task to be performed.
//
// Returns:
// void
// **************************************************************************
void CKDocument::RunWorkerThread (WORKERTHREADARG *pArg)
{
// Load standard arrow and small hourglass cursor reource:
HCURSOR hCursor = ::LoadCursor (NULL, IDC_APPSTARTING);
ASSERT (hCursor);
// Set the hourglass cursor:
::SetCursor (hCursor);
// Lock document to prevent edits while worker thread is doing its thing:
SetLocked (true);
// Start the worker thread:
unsigned int uAddress = 0;
HANDLE hThread = (HANDLE) _beginthreadex (NULL, 0, WorkerThread, pArg, 0, &uAddress);
// If thread was created successfully, we need to wait for it to complete
// its task. This will guarentee that pArg will remain valid while the
// thread completes its task. We will need to process the message queue
// while the thread runs to keep everybody up to date.
if (hThread)
{
MSG stMsg;
// Proccess messages while waiting for the thread to stop.
// hThread event will be set when thread stops. Timeout every
// 10 ms to process message queue, and then resume wait.
while (WaitForSingleObject (hThread, 10) == WAIT_TIMEOUT)
{
// Process message queue by removing the next message, and then
// dispatching it. This will insure that important Windows
// notifiactions get processed by their target windows while this
// thread is running.
if (PeekMessage (&stMsg, NULL, 0, 0, PM_REMOVE))
DispatchMessage (&stMsg);
// Make sure hourglass cursor stays:
::SetCursor (hCursor);
}
// When we break out of look, we know worker thread has stopped.
// We can now close the thread handle:
CloseHandle (hThread);
}
// We can now unlock document for edits:
SetLocked (false);
// Replace normal cursor:
::DestroyCursor (hCursor);
}
// **************************************************************************
// WorkerThread ()
//
// Description:
// Worker thread function.
//
// Parameters:
// void *pvArgs Pointer to a WORKERTHREADARG structure which
// describes task to be performed.
//
// Returns:
// unsigned int - 0
// **************************************************************************
unsigned _stdcall CKDocument::WorkerThread (void *pvArgs)
{
// Cast argument to proper type so we can extract the required data
// about the task we are to perform:
WORKERTHREADARG *pWTA = (WORKERTHREADARG *)pvArgs;
ASSERT (pWTA);
// Execute specified task:
switch (pWTA->eTask)
{
case WORKERTHREADARG::START_SINGLE_SERVER:
case WORKERTHREADARG::STOP_SINGLE_SERVER:
{
// Extract pointer to server we are to start or stop from
// argument structure:
CKServer *pServer = (CKServer *)pWTA->pvObjectA;
ASSERT (pServer);
// Start or stop the server as the case may be:
if (pWTA->eTask == WORKERTHREADARG::START_SINGLE_SERVER)
pServer->Start ();
else
pServer->Stop ();
}
break;
case WORKERTHREADARG::START_MULTIPLE_SERVER:
case WORKERTHREADARG::STOP_MULTIPLE_SERVER:
{
// Extract the list (object array) of servers to start or stop
// from argument structure:
CObArray *pList = (CObArray *)pWTA->pvObjectA;
ASSERT (pList);
// Get the number of server in the list:
int cnServers = pList->GetSize ();
CKServer *pServer = NULL;
// Loop over the servers in the list:
while (--cnServers >= 0)
{
// Get pointer to next server in list:
pServer = (CKServer *) pList->GetAt (cnServers);
ASSERT (pServer);
// Start or stop that server as the case may be:
if (pWTA->eTask == WORKERTHREADARG::START_MULTIPLE_SERVER)
pServer->Start ();
else
pServer->Stop ();
}
}
break;
case WORKERTHREADARG::ADD_ITEMS:
{
// Extract the list (object array) of items to add from
// argument structure:
CObArray *pList = (CObArray *)pWTA->pvObjectA;
ASSERT (pList);
// Extract the number of items from the argument structure:
int cnItems = *(int *)pWTA->pvObjectB;
// Get pointer to first item from list. We will use it to
// get the group object these items will be added to:
CKItem *pItem = (CKItem *)pList->GetAt (0);
ASSERT (pItem);
// Get group that we are adding the items to:
CKGroup *pGroup = pItem->GetParentGroup ();
ASSERT (pGroup);
// Add the items to this group:
pGroup->AddItems (*pList, cnItems);
}
break;
default:
// unhandled task ?
ASSERT (FALSE);
break;
}
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -