|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThis article will explain implementing an ATL COM EXE server with MFC support. As an example, we create an ATL COM EXE server that can create an MFC child window and an ATL child window in the client side’s parent window. BackgroundIn a recent project, we are trying to add MFC Support to an ATL EXE server. We want to create both MFC window using Using the codeThe code consists of two Microsoft Visual C++ 6.0 projects:
These projects support both non-Unicode and Unicode compilation. Server side implementationThis project was first created using ATL COM Wizard, and then modified to support MFC according MSDN's article Q 173974. However, this is not enough; there are other three modifications we should add:
BOOL CMyApp::InitInstance()
{
// Initialize OLE libraries
if (!AfxOleInit())
{
AfxMessageBox(_T("OLE Initialization Failed!"));
return FALSE;
}
AtlAxWinInit();
// Initialize the ATL Module
_Module.Init(ObjectMap,m_hInstance);
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking
// to MFC statically
#endif
// Update the System Registry
COleObjectFactory::UpdateRegistryAll(); // MFC Classes
VERIFY(SUCCEEDED(_Module.RegisterServer(TRUE))); // ATL Classes
// Create the dialog box or other stuff here
// Register OLE Class Factories
// MFC ones are for multiple as specified
// by the IMPLEMENT_OLECREATE() macro
COleObjectFactory::RegisterAll();
// ATL ones specifically register with REGCLS_MULTIPLEUSE
VERIFY(SUCCEEDED(_Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE)));
_Module.StartMonitor();
// Parse the command line to see if launched as OLE server
if (RunEmbedded() || RunAutomated())
{
// Application was run with /Embedding or /Automation.
// Don't show the main window in this case.
return TRUE;
}
return FALSE; // Nothing to do, so exit.
}
Figure 1 //Monitors the shutdown event void CExeModule::MonitorShutdown() { while (1) { WaitForSingleObject(hEventShutdown, INFINITE); DWORD dwWait=0; do { bActivity = false; dwWait = WaitForSingleObject(hEventShutdown, dwTimeOut); } while (dwWait == WAIT_OBJECT_0); // timed out if (!bActivity && m_nLockCnt == 0) // if no activity let's really bail { #if _WIN32_WINNT >= 0x0400 & defined(_ATL_FREE_THREADED) CoSuspendClassObjects(); if (!bActivity && m_nLockCnt == 0) #endif break; } } CloseHandle(hEventShutdown); PostThreadMessage(dwThreadID, WM_QUIT, 0, 0); theApp.PostThreadMessage( WM_QUIT, 0, 0); } Figure 2 We created two COM objects:
Both We also created two window classes :
class CATLWnd : public CWindowImpl<CATLWND, CWindow> { public: DECLARE_WND_CLASS(_T("ATL Window Class")) CATLWnd() { m_hbrBkgnd = CreateSolidBrush(RGB(0,0,255)); } ~CATLWnd() { DeleteObject ( m_hbrBkgnd ); } BEGIN_MSG_MAP(CATLWnd) MESSAGE_HANDLER(WM_PAINT, OnPaint) END_MSG_MAP() LRESULT OnPaint(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { RECT rcClient; PAINTSTRUCT ps; BeginPaint(&ps); HDC dc = GetDC(); GetClientRect ( &rcClient ); FillRect ( dc, &rcClient, m_hbrBkgnd ); TextOut(dc,2,10,_T("ATL Window"),10); EndPaint(&ps); return 0; } protected: HBRUSH m_hbrBkgnd; }; Figure 3 Client side implementationThe function Likely, the function Note that both windows are the child windows of void CATLMFCCOMClientView::OnMfcWindow() { if(m_pMFCWindowObject) return; HRESULT hResult = S_OK; hResult = CoCreateInstance(CLSID_MFCWindowObject, NULL,CLSCTX_LOCAL_SERVER,IID_IMFCWindowObject, (LPVOID*)&m_pMFCWindowObject); m_pMFCWindowObject->CreateMFCWindow((long)m_hWnd); } void CATLMFCCOMClientView::OnAtlWindow() { if(m_pATLWindowObject) return; HRESULT hResult = S_OK; hResult = CoCreateInstance(CLSID_ATLWindowObject, NULL,CLSCTX_LOCAL_SERVER,IID_IATLWindowObject, (LPVOID*)&m_pATLWindowObject); m_pATLWindowObject->CreateATLWindow((long)m_hWnd); } Figure 4 In server side implementation section, we mentioned that both the COM objects: void CATLMFCCOMClientView::OnDraw(CDC* pDC) { CATLMFCCOMClientDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(m_pMFCWindowObject) m_pMFCWindowObject->Update(); if(m_pATLWindowObject) m_pATLWindowObject->Update(); } Figure 5
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||