// Comp2.cpp
#include "stdafx.h"
#include "interface.h"
#include <afxdllx.h>
#include <objbase.h>
#include <assert.h>
#include "component2wnd.h"
#include "resource.h"
#include <objbase.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////
BOOL APIENTRY DllMain(HINSTANCE InsModule,
DWORD dwReason,
void* lpReserved)
{
return TRUE ;
}
//------------------------------------------//
//Definition of the class of the component 1
//-----------------------------------------//
class CComponent2 :public IComponent2
{
private:
long m_cRef;
CComponent2Wnd* m_pWnd;
public:
virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv);
virtual ULONG __stdcall AddRef();
virtual ULONG __stdcall Release();
virtual void __stdcall DefineWindow_Com2(bool inner);
virtual void __stdcall ShowWndBackground_Com2(COLORREF bgcolor);
virtual IUnknown* __stdcall Queryitself2();
virtual void __stdcall MenuitemNotselected2();
virtual void __stdcall StopFlying();
virtual void __stdcall StartFlying();
CComponent2();
~CComponent2();
};
///////////////////////////////////////////////
IUnknown* __stdcall CComponent2::Queryitself2()
{
IUnknown* pIunkown=NULL;
QueryInterface(IID_IUnknown,(void**)&pIunkown);
m_cRef-=3;
return pIunkown;
}
///////////////
//Counstructor
CComponent2::CComponent2():m_cRef(1),m_pWnd(NULL)
{
TRACE(_T("Component2:constructor is called\n"));
TRACE(_T("Initializing the Refrance conut to one\n"));
}
//////////////
//Destructor
CComponent2::~CComponent2()
{
TRACE(_T("~CComponent2: Destructor is called\n"));
}
////////////////////////////////////////////////////////////////////////
HRESULT __stdcall CComponent2::QueryInterface(const IID& iid,void** ppv)
////////////////////////////////////////////////////////////////////////
{
if(iid==IID_IUnknown)
{
TRACE(_T("Returning a pointer to IUnkown interface\n"));
*ppv=static_cast<IComponent2*>(this);
}
else if(iid==IID_IComponent2)
{
TRACE(_T("Returing a pointer to IComponent interface\n"));
*ppv=static_cast<IComponent2*>(this);
}
else
{
TRACE(_T("Interface is not supported\n"));
*ppv=NULL;
return E_NOINTERFACE;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
return S_OK ;
}
/////////////////////////////////////
//AddRef
ULONG __stdcall CComponent2::AddRef()
////////////////////////////////////
{
CPoint point;
CRect rect;
char buf[10];
TRACE(_T("Increamenting the Refrance count\n"));
//TRACE(_T("The Refrance count is:\n"));
//TRACE(_T(itoa(m_cRef+1,buf,10)));
if(NULL!=m_pWnd)
{
m_pWnd->m_cRef++;
CRect rect;
CDC* pDC=m_pWnd->GetDC();
pDC->GetClipBox (&rect);
pDC->DrawText(itoa(m_pWnd->m_cRef,buf,10),&rect,DT_RIGHT);
}
return ++m_cRef;
}
/////////////////////////////////////
//Release
/////////////////////////////////////
ULONG __stdcall CComponent2::Release()
{
char buf[10];
CStdioFile fw;
if(NULL!=m_pWnd)
{
m_pWnd->m_cRef--;
CRect rect;
CDC* pDC=m_pWnd->GetDC();
pDC->GetClipBox (&rect);
pDC->DrawText(itoa(m_pWnd->m_cRef,buf,10),&rect,DT_RIGHT);
}
// Win32 functions InterlockedDecrement and InterlockedIncrement are used
// to make sure that only one thread accesses the refrance count variable at a time
if(InterlockedDecrement(&m_cRef)==0)
{
TRACE(_T("Deleting of component 2 in progress..."));
delete this;
//if(NULL!=m_pWnd)delete m_pWnd;
::DestroyWindow (::GetActiveWindow());
//The client uses this file in order to know the componet exsists,
//befor using the interfaces
fw.Open ("C:\\Comp2IUnknown.txt",CFile::modeWrite);
fw.WriteString ("0");
fw.Close();
return 0;
}
TRACE(_T("Decermenting the Refrance count\n"));
return m_cRef;
}
//////////////////////////////////////////
void __stdcall CComponent2::DefineWindow_Com2(bool inner)
{
CString wndtxt="COM Component 2";
if(inner)
wndtxt+=",inner";
//Registering the windows class
CString strWndClass= AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW,
LoadCursor(NULL, IDC_ARROW),
(HBRUSH)GetStockObject(WHITE_BRUSH),
0);
//Create a window object
m_pWnd = new CComponent2Wnd();
//Creating the component2 window with popup style
m_pWnd->CreateEx(WS_OVERLAPPED,//windows syle
strWndClass,//class name
wndtxt,//Windows text
WS_EX_TOOLWINDOW,//windows extended style
330,//rect.right,
330,//rect.bottom,
180,//widows width
120,//windows hight
0,//top-level window and no parent
0,//no menu loaded yet
0);//no data
//pointing to the own interface from the components own inner window
//in order to be able to handel menuitem selections
m_pWnd->m_pComponent2sIUnknown=Queryitself2();
//loading a menu resource from the application�s executable file and
//attach it to the m_WndMenu object
if(!inner)
{
m_pWnd->m_WndMenu.LoadMenu("IDR_COM2MENU");
m_pWnd->SetMenu(&m_pWnd->m_WndMenu);
}
//showing component2s window
m_pWnd->ShowWindow(SW_SHOW);
}
void __stdcall CComponent2::MenuitemNotselected2()
{
TRACE(_T("Menu item not selected\n"));
if(NULL!=m_pWnd)
//(white color code).. client area of the clients view window
m_pWnd->m_color_hittest=16777215;
}
////////////////////////////////////////
void __stdcall CComponent2::ShowWndBackground_Com2(COLORREF bgcolor)
{
CRect rect;
CDC* pDC=m_pWnd->GetDC();
m_pWnd->GetClientRect (&rect);
CBrush brush;
brush.CreateSolidBrush (bgcolor);
pDC->FillRect(&rect,&brush);
CBitmap bmp, *poldbmp;
CDC memdc;
bmp.LoadBitmap("IDB_BITMAP");
memdc.CreateCompatibleDC( pDC );
poldbmp = memdc.SelectObject( &bmp );
pDC->BitBlt( rect.right -100,rect.bottom/4, 100, 100, &memdc, 0, 0, SRCCOPY );
memdc.SelectObject( poldbmp );
}
////////////////////////////////////
void __stdcall CComponent2::StopFlying ()
{
m_pWnd->m_bStop=true;
m_pWnd->_KillTimer ();
}
////////////////////////////////////
void __stdcall CComponent2::StartFlying ()
{
m_pWnd->StartTimer ();
m_pWnd->m_bStop=false;
}
///////////////////////////////////////////////////////////
//
// Class factory
//
class CFactory : public IClassFactory
{
public:
// IUnknown
virtual HRESULT __stdcall QueryInterface(const IID& iid,void** ppv) ;
virtual ULONG __stdcall AddRef() ;
virtual ULONG __stdcall Release() ;
// Interface IClassFactory
virtual HRESULT __stdcall CreateInstance(IUnknown* pUnkOuter,
const IID& iid,
void** ppv) ;
virtual HRESULT __stdcall LockServer(BOOL bLock) ;
// Constructor
CFactory() : m_cRef(1) {}
// Destructor
~CFactory() {}
private:
long m_cRef ;
} ;
//
// Class factory IUnknown implementation
////////////////////////////////////////////////////////////////////////
HRESULT __stdcall CFactory::QueryInterface(const IID& iid,LPVOID* ppv)
{
if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
*ppv = static_cast<IClassFactory*>(this) ;
else
{
*ppv = NULL ;
return E_NOINTERFACE ;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
return S_OK ;
}
ULONG __stdcall CFactory::AddRef()
{
return ::InterlockedIncrement(&m_cRef) ;
}
ULONG __stdcall CFactory::Release()
{
TRACE(_T("Release() from CFactroy in progress..."));
if (::InterlockedDecrement(&m_cRef) == 0)
{
delete this ;
return 0 ;
}
return m_cRef ;
}
//
// IClassFactory implementation
//
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnkOuter,
const IID& iid,
void** ppv)
{
TRACE(_T("CreateInstance is called\n"));
// Cannot aggregate
if (pUnkOuter != NULL)
{
return CLASS_E_NOAGGREGATION ;
}
// Create component.
TRACE(_T("Creating Component2 \n"));
CComponent2* pComponent2 = new CComponent2 ;
if (pComponent2 == NULL)
{
TRACE(_T("No memory available\n"));
return E_OUTOFMEMORY ;
}
// Get the requested interface.
TRACE(_T("Calling QueryInterface(IID_Component2,(void**)&pIComponent2\n"));
HRESULT hr = pComponent2->QueryInterface(iid,(void**) ppv) ;
//if Query faild the comp will delete itself
if(FAILED(hr))
{
TRACE(_T("Problem in calling Queryinterface\n"));
pComponent2->Release() ;
}
return hr ;
}
// LockServer
HRESULT __stdcall CFactory::LockServer(BOOL bLock)
{
return S_OK ;
}
//
// Get class factory
///////////////////////////////////////////
STDAPI DllGetClassObject(const CLSID& clsid,
const IID& iid,
void** ppv)
{
TRACE(_T("DllGetClassObject:\tCreate class factory.\n")) ;
// Can we create this component?
if (clsid != CLSID_Component2)
{
TRACE(_T("Unable to create Component2\n"));
return CLASS_E_CLASSNOTAVAILABLE ;
}
// Create class factory.
CFactory* pFactory = new CFactory ; // No AddRef in constructor
if (pFactory == NULL)
{
TRACE(_T("No memory available\n"));
return E_OUTOFMEMORY ;
}
TRACE(_T("Getting the requested interface\n"));
// Get requested interface.
HRESULT hr = pFactory->QueryInterface(iid, ppv) ;
TRACE(_T("Calling Release() member of CFactory object\n"));
pFactory->Release() ;
TRACE(_T("CFactory: Releasing itself,done\n"));
return hr ;
}