// 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);
};