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

📄 document.cpp

📁 VisualC OPC Client Example C 程序开发
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	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 + -