Automation Server Questions
-
I'm using VC++ 6 service pack 6 on Windows 2000. I'm working with an automation server MDI application with the following requirements. 1) Can be started by user with visible interface. 2) Only one instance at a time. 3) If controlled by client, runs in background (invisible) initially. 4) Client(s) has option to make application visible. 5) If visible and user attempts to close with client(s) connections, warning is given with choice to close or not. 6) Has menu item that allows user to disconnect from all clients. 7) If invisible, closes when last client disconnects. I have no problem with 1-4, the questions arise with 5-7. In order to implement these, the server needs to know if there are clients connected to it. My main automation class (CAutoApp) is instantiated every time a client contacts it. In the constructor I add to a static array of LPUNKOWNs (m_lpUnk[MAXNUMCONN]) using GetInterface(&IID_IUnknown):
LPUNKNOWN CAutoApp::m_lpUnk[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
CAutoApp::CAutoApp()
{
EnableAutomation();
for (int i=0; i < MAXNUMCONN && NULL != m_lpUnk[i]; i++);
if (i < MAXNUMCONN)
m_lpUnk[i] = GetInterface(&IID_IUnknown);
}Whenever a client closes, CMainFrame::OnClose is called in the server. So I have the following code to implement 5 and 7 in OnClose():
//see if any clients are still connected int i=0; while(i < MAXNUMCONN && NULL != CAutoApp::m\_lpUnk\[i\]) { try { CAutoApp::m\_lpUnk\[i\]->AddRef(); CAutoApp::m\_lpUnk\[i++\]->Release(); } catch(...) { //connection no longer exists, remove from array for(int j=i; j<MAXNUMCONN-1 && NULL != CAutoApp::m\_lpUnk\[j\]; j++) CAutoApp::m\_lpUnk\[j\] = CAutoApp::m\_lpUnk\[j+1\]; } } //if connected to at least one client if (NULL != CAutoApp::m\_lpUnk\[0\]) { if (IsWindowVisible()) { if (IDNO == AfxMessageBox("One or more remote connections is still active. Exit anyway?", MB\_YESNO)) //user decides not to close application return; } else //a client disconnected but do not close because other client(s) remain return; } ..... CMDIFrameWnd::OnClose();
This works, although maybe it's a no-no to use a try-catch this way. If there's a better way to do it, I'd like to know. To implement (6), I have the following:
void CMainFrame::OnCloseconnections()
{
if (IDNO == AfxMessageBox("This will close all connections. Are y