Click here to Skip to main content
15,896,557 members
Articles / Desktop Programming / ATL

An Example of ATL 7.0 ActiveX Control Simulating A PS (Particle Swarm) Dynamic System

Rate me:
Please Sign up or sign in to vote.
3.86/5 (4 votes)
14 Nov 20047 min read 53.1K   1.6K   34  
An article on ATL 7.0 and dynamic system simulation.
// SmartGravityBubble.h : CSmartGravityBubble
#pragma once
#include "resource.h"      
#include <atlctl.h>
#include <complex>
#include <time.h>
#include "SmartBubble.h"
#include "BubbleContainer.h"
#include "VCUE_StockProperty.h"

using namespace std;
typedef complex<double> DoubleVector;
typedef DoubleVector PosVector;
typedef DoubleVector ForceVector;


// ISmartGravityBubble
[
	object,
	uuid(A46F8D32-1925-405B-A678-6555D8BEA018),
	dual,
	helpstring("ISmartGravityBubble interface"),
	pointer_default(unique)
]
__interface ISmartGravityBubble : public IDispatch
{
	[propputref, bindable, requestedit, id(DISPID_FONT)]
	HRESULT Font([in]IFontDisp* pFont);
	[propput, bindable, requestedit, id(DISPID_FONT)]
	HRESULT Font([in]IFontDisp* pFont);
	[propget, bindable, requestedit, id(DISPID_FONT)]
	HRESULT Font([out, retval]IFontDisp** ppFont);
	[propputref,id(DISPID_PICTURE)]
	HRESULT Picture([in]IPictureDisp* pPicture);
	[propput, id(DISPID_PICTURE)]
	HRESULT Picture([in]IPictureDisp* pPicture);
	[propget,id(DISPID_PICTURE)]
	HRESULT Picture([out, retval]IPictureDisp** ppPicture);

	[propget, id(1), helpstring("property  GravityPara")] HRESULT GravityPara([out, retval] DOUBLE* pVal);
	[propput, id(1), helpstring("property  GravityPara")] HRESULT GravityPara([in] DOUBLE newVal);
	[propget, id(2), helpstring("property  ChargePara")] HRESULT ChargePara([out, retval] DOUBLE* pVal);
	[propput, id(2), helpstring("property  ChargePara")] HRESULT ChargePara([in] DOUBLE newVal);
	[propget, id(3), helpstring("property  Started")] HRESULT Started([out, retval] VARIANT_BOOL* pVal);
	[propput, id(3), helpstring("property  Started")] HRESULT Started([in] VARIANT_BOOL newVal);
	[id(4), helpstring("method AddBubble")] HRESULT AddBubble(ISmartBubble * pBubble);
	[id(5), helpstring("method DeleteBubble")] HRESULT DeleteBubble(LONG ID);
	[id(6), helpstring("method GetBubble")] HRESULT GetBubble(LONG ID, [out,retval] ISmartBubble ** pBubble);
	[propget, id(7), bindable, helpstring("property  TimerInterval")] HRESULT TimerInterval([out, retval] LONG* pVal);
	[propput, id(7), bindable, helpstring("property  TimerInterval")] HRESULT TimerInterval([in] LONG newVal);
	[propget, id(8), bindable, helpstring("property  DumpPara")] HRESULT DumpPara([out, retval] DOUBLE* pVal);
	[propput, id(8), bindable, helpstring("property  DumpPara")] HRESULT DumpPara([in] DOUBLE newVal);
	[propget, id(9), bindable, helpstring("property  MinSpeed")] HRESULT MinSpeed([out, retval] DOUBLE* pVal);
	[propput, id(9), bindable, helpstring("property  MinSpeed")] HRESULT MinSpeed([in] DOUBLE newVal);
	[propget, id(10), bindable, helpstring("property  MinASpeed")] HRESULT MinASpeed([out, retval] DOUBLE* pVal);
	[propput, id(10), bindable, helpstring("property  MinASpeed")] HRESULT MinASpeed([in] DOUBLE newVal);
	[propget, id(11), bindable, requestedit, helpstring("property  BackColor")] HRESULT BackColor([out, retval] OLE_COLOR* pVal);
	[propput, id(11), bindable, requestedit, helpstring("property  BackColor")] HRESULT BackColor([in] OLE_COLOR newVal);
	[id(12), helpstring("method EmptyBubbles")] HRESULT EmptyBubbles(void);
};


// _ISmartGravityBubbleEvents
[
	uuid("03F610DD-F71C-497B-938E-7DB25A411F2D"),
	dispinterface,
	helpstring("_ISmartGravityBubble event interface")
]
__interface _ISmartGravityBubbleEvents
{
	[id(1), helpstring("method OnBubbleClicked")] HRESULT OnBubbleClicked(LONG ID);
	[id(2), helpstring("method OnLeftButtonDown")] HRESULT OnLeftButtonDown(LONG X,LONG Y);
	[id(3), helpstring("method OnRightButtonDown")] HRESULT OnRightButtonDown(LONG x, LONG y);
};

// CSmartGravityBubble
[
	coclass,
	threading("apartment"),
	vi_progid("SmartGravityBubbleCtrl.SmartGravityBubb"),
	progid("SmartGravityBubbleCtrl.SmartGravityBu.1"),
	version(1.0),
	uuid("D49DA833-A6DB-4DB1-B30A-BD0FE1CB4750"),
	helpstring("SmartGravityBubble Class"),
	event_source("com"),
	support_error_info(ISmartGravityBubble),
	registration_script("control.rgs")
]
class ATL_NO_VTABLE CSmartGravityBubble : 
	public CStockPropImpl<CSmartGravityBubble, ISmartGravityBubble>,
	public VCUE::CStockFontImpl<CSmartGravityBubble>,
	public IPersistStreamInitImpl<CSmartGravityBubble>,
	public IOleControlImpl<CSmartGravityBubble>,
	public IOleObjectImpl<CSmartGravityBubble>,
	public IOleInPlaceActiveObjectImpl<CSmartGravityBubble>,
	public IViewObjectExImpl<CSmartGravityBubble>,
	public IOleInPlaceObjectWindowlessImpl<CSmartGravityBubble>,
	public IPersistStorageImpl<CSmartGravityBubble>,
	public ISpecifyPropertyPagesImpl<CSmartGravityBubble>,
	public IQuickActivateImpl<CSmartGravityBubble>,
	public IDataObjectImpl<CSmartGravityBubble>,
	public CComControl<CSmartGravityBubble>
{
public:

	CSmartGravityBubble()
	{
		m_SimulationTimer=-1;
		m_lTimerInterval=50;
		m_bStarted=FALSE;
		m_bWindowOnly=TRUE;
		m_dfGravityPara=1;
		m_dfChargePara=1e6;
		m_dfDumpPara=0.1;
		m_hBufferBitmap=NULL;
		m_ForceArrayLen=20;
		m_pForceArray=new ForceVector[m_ForceArrayLen];
		m_dfMinSpeed=1;
		m_dfMinASpeed=1;
		m_BackColor=RGB(0,0,0);
		m_dfTime=1;
		m_pHighlightBubble=0;
		m_pPicture=0;
		VCUE::AtlOleCreateFont(&m_pFont, OLESTR("Comic Sans MS"), 24);
		srand(time(NULL));
	}
	~CSmartGravityBubble()
	{
		if(m_pForceArray)
			delete [] m_pForceArray;
	}
DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE | 
	OLEMISC_CANTLINKINSIDE | 
	OLEMISC_INSIDEOUT | 
	OLEMISC_ACTIVATEWHENVISIBLE | 
	OLEMISC_SETCLIENTSITEFIRST
)


BEGIN_PROP_MAP(CSmartGravityBubble)
	PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
	PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
	PROP_DATA_ENTRY("_color",m_BackColor,VT_UI4)
	PROP_DATA_ENTRY("_chargePara",m_dfChargePara,VT_R8)
	PROP_DATA_ENTRY("_dumpPara",m_dfDumpPara,VT_R8)
	PROP_DATA_ENTRY("_gravityPara",m_dfGravityPara,VT_R8)
	PROP_DATA_ENTRY("_minASpeed",m_dfMinASpeed,VT_R8)
	PROP_DATA_ENTRY("_minSpeed",m_dfMinSpeed,VT_R8)
	PROP_DATA_ENTRY("_timerInterval",m_lTimerInterval,VT_I4)
	PROP_DATA_ENTRY("_started",m_bStarted,VT_I2)
	PROP_ENTRY("Font", DISPID_FONT, CLSID_StockFontPage)
	PROP_ENTRY("Picture",DISPID_PICTURE,CLSID_StockPicturePage)
END_PROP_MAP()


BEGIN_MSG_MAP(CSmartGravityBubble)
	MESSAGE_HANDLER(WM_TIMER,TimerProc)
	MESSAGE_HANDLER(WM_CREATE,OnCreate)
	MESSAGE_HANDLER(WM_SIZE,OnReSize)
	MESSAGE_HANDLER(WM_ERASEBKGND,OnEraseBackground)
	MESSAGE_HANDLER(WM_LBUTTONDOWN,OnLeftButtonDown)
	MESSAGE_HANDLER(WM_RBUTTONDOWN,OnRightButtonDown)
	MESSAGE_HANDLER(WM_MOUSEMOVE,OnMouseMove)
	MESSAGE_HANDLER(WM_CLOSE,OnClose)
	CHAIN_MSG_MAP(CComControl<CSmartGravityBubble>)
	DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
//  LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
//  LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
//  LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);

	//__event __interface _ISmartGravityBubbleEvents;
// IViewObjectEx
	DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)

// ISmartGravityBubble
public:
	HRESULT OnDraw(ATL_DRAWINFO& di)
	{
		this->GetAmbientUserMode(m_bUserMode);
		RECT& rc = *(RECT*)di.prcBounds;

		HRGN hRgnOld = NULL;
		if (GetClipRgn(di.hdcDraw, hRgnOld) != 1)
			hRgnOld = NULL;
		bool bSelectOldRgn = false;

		HRGN hRgnNew = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);

		if (hRgnNew != NULL)
		{
			bSelectOldRgn = (SelectClipRgn(di.hdcDraw, hRgnNew) != ERROR);
			DeleteObject(hRgnNew);
		}
		

		if(m_hBufferBitmap)
		{
			BITMAP Bmp;
			GetObject(m_hBufferBitmap,sizeof(BITMAP),&Bmp);
			CRect rect;
			rect.left=0;
			rect.top=0;
			rect.right=Bmp.bmWidth;
			rect.bottom=Bmp.bmHeight;
			::BitBlt(di.hdcDraw,0,0,
				Bmp.bmWidth,Bmp.bmHeight,m_hBufferDC,0,0,SRCCOPY);
		}
		

		if(!m_bUserMode)
		{
			SIZE size1;
			int y=20;
			char* copyright[]={
				"Copy right reserved for smartnose@gmail.com",
				"Contact smartnose@gmail.com for more information",
			};

			SetBkMode(di.hdcDraw,TRANSPARENT);
			for(int i=0;i<sizeof(copyright)/sizeof(char *);i++)
			{
				GetTextExtentPoint(di.hdcDraw,copyright[i],strlen(copyright[i]),&size1);
				TextOut(di.hdcDraw,(rc.right-rc.left-size1.cx)/2,y,copyright[i],strlen(copyright[i]));
				y+=2*size1.cy;
			}
		}
		if (bSelectOldRgn)
			SelectClipRgn(di.hdcDraw, hRgnOld);
		
		return S_OK;
	}


	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}
	
	void FinalRelease() 
	{
	}
	__event __interface _ISmartGravityBubbleEvents;
	STDMETHOD(get_GravityPara)(DOUBLE* pVal);
	STDMETHOD(put_GravityPara)(DOUBLE newVal);
	STDMETHOD(get_ChargePara)(DOUBLE* pVal);
	STDMETHOD(put_ChargePara)(DOUBLE newVal);
	STDMETHOD(get_Started)(VARIANT_BOOL* pVal);
	STDMETHOD(put_Started)(VARIANT_BOOL newVal);
	STDMETHOD(AddBubble)(ISmartBubble * pBubble);
	STDMETHOD(DeleteBubble)(LONG ID);
	STDMETHOD(GetBubble)(LONG ID, ISmartBubble ** pBubble);
	STDMETHOD(get_TimerInterval)(LONG* pVal);
	STDMETHOD(put_TimerInterval)(LONG newVal);
	STDMETHOD(get_DumpPara)(DOUBLE* pVal);
	STDMETHOD(put_DumpPara)(DOUBLE newVal);
	STDMETHOD(get_MinSpeed)(DOUBLE* pVal);
	STDMETHOD(put_MinSpeed)(DOUBLE newVal);
	STDMETHOD(get_MinASpeed)(DOUBLE* pVal);
	STDMETHOD(put_MinASpeed)(DOUBLE newVal);
	STDMETHOD(get_BackColor)(OLE_COLOR* pVal);
	STDMETHOD(put_BackColor)(OLE_COLOR newVal);
	
public:
	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
	LRESULT OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
	LRESULT OnLeftButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
	LRESULT OnRightButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
	LRESULT OnReSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
	LRESULT OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
	LRESULT OnClose(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
	void PaintAllToBuffer(HDC & di);
	void PaintOneBubbleToBuffer(HDC & di, LPISMARTBUBBLE p);
	void InvalidateBubbleRect(LPISMARTBUBBLE p);
	void RenderBackground(void);
	void EraseBackground(LPISMARTBUBBLE p);
	CComPtr<IPictureDisp>  m_pPicture;
private:
	void EmptyBuffer(void);
	inline double ComplexModule(DoubleVector vec);
	BOOL IsPtInBubble(int x, int y, LPISMARTBUBBLE p);
	void ComputeDumpForces(void);
	ForceVector * m_pForceArray;
	int m_ForceArrayLen;
	void ComputeGravityAndExpellForces(void);
	void MoveBubbles(void);


	//private data members;
	UINT_PTR m_SimulationTimer;
	UINT_PTR m_DemoTimer;
	BOOL m_bStarted;
	LONG m_lTimerInterval;
	LRESULT TimerProc(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL & bHandled);
	CBubbleContainer m_BubbleContainer;	
	DOUBLE m_dfGravityPara;
	DOUBLE m_dfChargePara;
	DOUBLE m_dfDumpPara;
	DOUBLE m_dfMinSpeed;
	DOUBLE m_dfMinASpeed;
	DOUBLE m_dfTime;
	HBITMAP m_hBufferBitmap;
	HBITMAP m_hBackgroundBitmap;
	HBITMAP m_hOldBmp;
	HBITMAP m_hOldBGBmp;
	HDC m_hBufferDC;
	HDC m_hBackDC;
	OLE_COLOR m_BackColor;
	LPISMARTBUBBLE m_pHighlightBubble;
	BOOL m_bUserMode;
public:
	STDMETHOD(EmptyBubbles)(void);
	void OnPictureChanged(void);
};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions