用于EagleEye3.0 规则集漏报和误报测试的示例项目,项目收集于github和gitee
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

547 lines
14 KiB

// SSmileyCtrl.cpp : Implementation of SSmileyCtrl
#include <Windows.h>
#include "../controls.extend/smiley/SSmileyCtrl.h"
#include <TOM.h>
#include <richedit.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlwin.h>
#include <atltypes.h>
#include <atlctl.h>
#include <atlhost.h>
const GUID CLSID_SSmileyCtrl =
{0xd29e0bde,0xcfda,0x4b93,{0x92,0x9a,0x87,0x7a,0xb4,0x55,0x7b,0xd9}};
DWORD _GenerateID()
{
static DWORD s_id=1;
return s_id++;
}
// CCSmiley
class ATL_NO_VTABLE SSmileyCtrl :
public CComObjectRootEx<CComSingleThreadModel>,
public CComControl<SSmileyCtrl>,
public IOleObjectImpl<SSmileyCtrl>,
public IOleInPlaceObjectWindowlessImpl<SSmileyCtrl>,
public IViewObjectExImpl<SSmileyCtrl>,
public IPersistStreamInitImpl<SSmileyCtrl>,
public IPersistStorageImpl<SSmileyCtrl>,
public IOleControlImpl<SSmileyCtrl>,
public ITimerHandler,
public ISmileyCtrl
{
public:
DECLARE_OLEMISC_STATUS(OLEMISC_RECOMPOSEONRESIZE |
OLEMISC_CANTLINKINSIDE |
OLEMISC_INSIDEOUT |
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST
)
BEGIN_COM_MAP(SSmileyCtrl)
COM_INTERFACE_ENTRY(ITimerHandler)
COM_INTERFACE_ENTRY(ISmileyCtrl)
COM_INTERFACE_ENTRY(IOleControl)
COM_INTERFACE_ENTRY(IOleObject)
COM_INTERFACE_ENTRY(IViewObject)
COM_INTERFACE_ENTRY(IViewObject2)
COM_INTERFACE_ENTRY(IViewObjectEx)
COM_INTERFACE_ENTRY(IPersistStreamInit)
COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
COM_INTERFACE_ENTRY(IPersistStorage)
END_COM_MAP()
BEGIN_PROP_MAP(SSmileyCtrl)
END_PROP_MAP()
BEGIN_MSG_MAP(SSmileyCtrl)
CHAIN_MSG_MAP(CComControl<SSmileyCtrl>)
DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
public:
SSmileyCtrl();
~SSmileyCtrl();
static CLSID GetObjectCLSID(){
return CLSID_SSmileyCtrl;
}
public://ISoSmileyCtrl
STDMETHOD(Insert2Richedit)(IRichEditOle * ole);
STDMETHOD(SetSource)(ISmileySource * pSource);
STDMETHOD(GetSource)(ISmileySource ** ppSource);
public://IOleObject
STDMETHOD(SetClientSite)(IOleClientSite *pClientSite);
STDMETHOD(GetMiscStatus)(DWORD dwAspect, DWORD *pdwStatus);
public://IPersistStreamInitImpl
#if _MSC_VER>1400
HRESULT IPersistStreamInit_Load(LPSTREAM pStm, const ATL_PROPMAP_ENTRY* pMap);
HRESULT IPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty, const ATL_PROPMAP_ENTRY* pMap);
#else
HRESULT IPersistStreamInit_Load(LPSTREAM pStm, ATL_PROPMAP_ENTRY* pMap);
HRESULT IPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty, ATL_PROPMAP_ENTRY* pMap);
#endif
HRESULT FireViewChange();
HRESULT OnDraw(ATL_DRAWINFO& di);
public://IPersistStorage
STDMETHOD(Load)(IStorage* pStorage);//<EFBFBD><EFBFBD><EFBFBD><EFBFBD>IPersistStorage::Load<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD>д<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־λ
public://ITimerHander
STDMETHOD(OnTimer)(HDC hdc);
STDMETHOD(Clear)();;
STDMETHOD(GetRect)(LPRECT pRect){memcpy(pRect,&m_rcPos,sizeof(RECT));return S_OK;};
private:
void UpdateSmiley(HDC hdc);
void UpdateSmileyFlag();
DWORD GetSmileyFlag(IRichEditOle *ole,int iFirst,int iLast);
CComPtr<ISmileyHost> m_pSmileyHost;
CComPtr<ISmileySource> m_pSmileySource;
int m_iFrameIndex;
DWORD m_dwID;
DWORD m_dwDrawFlag;
};
SSmileyCtrl::SSmileyCtrl():m_iFrameIndex(0),m_dwDrawFlag(0)
{
m_dwID = _GenerateID();
memset(&m_rcPos,0,sizeof(RECT));
m_bRecomposeOnResize=1;
}
SSmileyCtrl::~SSmileyCtrl()
{
if(m_pSmileyHost)
{//<EFBFBD><EFBFBD>֤<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD>
m_pSmileyHost->KillTimer(this);
}
}
STDMETHODIMP SSmileyCtrl::Insert2Richedit(IRichEditOle * ole)
{
if(!m_pSmileySource) return E_FAIL;
HRESULT hr;
//insert this to host
CComPtr<IOleObject> pOleObject;
CComPtr<IOleClientSite> pClientSite;
// Get site
ole->GetClientSite(&pClientSite);
ATLASSERT(pClientSite != NULL);
CComPtr<IRichEditOleCallback> pCallback;
hr=ole->QueryInterface(IID_IRichEditOleCallback,(void**)&pCallback);
if(!SUCCEEDED(hr)) return E_FAIL;
//get the IOleObject
hr = _InternalQueryInterface(IID_IOleObject, (void**)&pOleObject);
if (FAILED(hr))
{
return E_FAIL;
}
//to insert into richedit, you need a struct of REOBJECT
REOBJECT reobject;
ZeroMemory(&reobject, sizeof(REOBJECT));
reobject.cbStruct = sizeof(REOBJECT);
CLSID clsid;
pOleObject->GetUserClassID(&clsid);
//get storage
pCallback->GetNewStorage(&reobject.pstg);
//set clsid
reobject.clsid = clsid;
//can be selected
reobject.cp = REO_CP_SELECTION;
//content, but not static
reobject.dvaspect = DVASPECT_CONTENT;
//goes in the same line of text line
reobject.dwFlags = REO_BELOWBASELINE;
reobject.dwUser = (DWORD)m_dwID;
//the very object
reobject.poleobj = pOleObject;
//client site contain the object
reobject.polesite = pClientSite;
SIZEL sizel={0};
reobject.sizel = sizel;
hr = pOleObject->SetClientSite(pClientSite);
if(SUCCEEDED(hr))
{
hr = ole->InsertObject(&reobject);
FireViewChange();
}
if(reobject.pstg)
{
reobject.pstg->Release();
}
return hr;
}
STDMETHODIMP SSmileyCtrl::SetSource(ISmileySource * pSource)
{
m_pSmileySource = pSource;
if(m_pSmileySource)
{
//<EFBFBD><EFBFBD><EFBFBD>±<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
SIZE sz;
m_pSmileySource->GetSize(&sz);
HDC hDC = ::GetDC(NULL);
m_sizeExtent.cx = ::MulDiv(sz.cx, 2540, GetDeviceCaps(hDC, LOGPIXELSX));
m_sizeExtent.cy = ::MulDiv(sz.cy, 2540, GetDeviceCaps(hDC, LOGPIXELSY));
::ReleaseDC(NULL, hDC);
}
return S_OK;
}
STDMETHODIMP SSmileyCtrl::GetSource(ISmileySource ** ppSource)
{
if(! m_pSmileySource) return E_FAIL;
*ppSource = m_pSmileySource;
(*ppSource)->AddRef();
return S_OK;
}
STDMETHODIMP SSmileyCtrl::OnTimer(HDC hdc)
{
int cFrame = 1;
m_pSmileySource->GetFrameCount(&cFrame);
m_iFrameIndex++;
m_iFrameIndex %= cFrame;
UpdateSmiley(hdc);
return S_OK;
}
#if _MSC_VER>1400
HRESULT SSmileyCtrl::IPersistStreamInit_Load(LPSTREAM pStm, const ATL_PROPMAP_ENTRY* pMap)
#else
HRESULT SSmileyCtrl::IPersistStreamInit_Load(LPSTREAM pStm, ATL_PROPMAP_ENTRY* pMap)
#endif
{
ATLASSERT(!m_pSmileySource);
ATLASSERT(m_pSmileyHost);
CComPtr<ISmileySource> pSource;
HRESULT hr =m_pSmileyHost->CreateSource(&pSource);
if(!SUCCEEDED(hr)) return hr;
hr = pSource->Stream_Load(pStm);
if(!SUCCEEDED(hr)) return hr;
SetSource(pSource);
hr = IPersistStreamInitImpl<SSmileyCtrl>::IPersistStreamInit_Load( pStm, pMap);
if(!SUCCEEDED(hr)) return hr;
FireViewChange();
return hr;
}
#if _MSC_VER>1400
HRESULT SSmileyCtrl::IPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty, const ATL_PROPMAP_ENTRY* pMap)
#else
HRESULT SSmileyCtrl::IPersistStreamInit_Save(LPSTREAM pStm, BOOL fClearDirty, ATL_PROPMAP_ENTRY* pMap)
#endif
{
if(!m_pSmileySource) return E_FAIL;
HRESULT hr = m_pSmileySource->Stream_Save(pStm);
if(!SUCCEEDED(hr)) return hr;
return IPersistStreamInitImpl<SSmileyCtrl>::IPersistStreamInit_Save( pStm, fClearDirty, pMap);
}
HRESULT SSmileyCtrl::FireViewChange()
{
if (m_bInPlaceActive)
{
// Active
if (m_hWndCD != NULL)
::InvalidateRect(m_hWndCD, NULL, TRUE); // Window based
else if (m_bWndLess && m_spInPlaceSite != NULL)
m_spInPlaceSite->InvalidateRect(NULL, TRUE); // Windowless
}
else if (!m_pSmileyHost)
{
SendOnViewChange(DVASPECT_CONTENT);
}
else
{
// UpdateSmiley(NULL);
}
return S_OK;
}
HRESULT SSmileyCtrl::OnDraw(ATL_DRAWINFO& di)
{
if(!m_pSmileySource) return E_FAIL;
RECT rc={di.prcBounds->left,di.prcBounds->top,di.prcBounds->right,di.prcBounds->bottom};
m_pSmileySource->Draw(di.hdcDraw,&rc,m_iFrameIndex);
if(!di.bZoomed)
{//<EFBFBD><EFBFBD>copyʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>bZoomed<EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD>Ѿ<EFBFBD><EFBFBD>ηŴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
m_rcPos = rc;//cache pos, position will be updated in response to EN_UPDATE message come from it's host
}
int nDelay=0;
HRESULT hr = m_pSmileySource->GetFrameDelay(m_iFrameIndex,&nDelay);
if(SUCCEEDED(hr) && m_pSmileyHost)
{
m_pSmileyHost->SetTimer(this,nDelay);
}
return S_OK;
}
void SSmileyCtrl::UpdateSmiley(HDC hdc)
{
if(!m_pSmileyHost) return ;
if(::IsRectEmpty(&m_rcPos)) return;
if(!hdc) return;
UpdateSmileyFlag();
m_pSmileySource->Draw(hdc,&m_rcPos,m_iFrameIndex);
if (m_dwDrawFlag == REO_INVERTEDSELECT)
{
//Invert entire object
InvertRect(hdc, &m_rcPos);
}
else if(m_dwDrawFlag == REO_SELECTED)
{
// Just the border, so use a null brush
SaveDC(hdc);
SetROP2(hdc, R2_NOT);
SelectObject(hdc, GetStockObject(NULL_BRUSH));
Rectangle(hdc, m_rcPos.left, m_rcPos.top, m_rcPos.right, m_rcPos.bottom);
RestoreDC(hdc, -1);
}
int nDelay=0;
HRESULT hr = m_pSmileySource->GetFrameDelay(m_iFrameIndex,&nDelay);
if(SUCCEEDED(hr) && m_pSmileyHost)
{
m_pSmileyHost->SetTimer(this,nDelay);
}
}
HRESULT SSmileyCtrl::Load( IStorage* pStorage )
{
//<EFBFBD><EFBFBD>RichEditFlags<EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><EFBFBD>3<EFBFBD><EFBFBD>REOBJECT<EFBFBD><EFBFBD>־<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Richedit20<EFBFBD><EFBFBD>winceԴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɲ<EFBFBD><EFBFBD><EFBFBD>richeditǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"RichEditFlags"<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>3<EFBFBD><EFBFBD><EFBFBD><EFBFBD>־λ
CComPtr<IStream> spStream;
static LPCOLESTR vszRichEditFlags = OLESTR("RichEditFlags");
HRESULT hr = pStorage->CreateStream(vszRichEditFlags,
STGM_WRITE | STGM_SHARE_EXCLUSIVE | STGM_CREATE,
0, 0, &spStream);
if (FAILED(hr)) return hr;
DWORD dwFlag=REO_BELOWBASELINE,dwUser=m_dwID,dwAspect=DVASPECT_CONTENT;
spStream->Write(&dwFlag,sizeof(dwFlag),NULL);
spStream->Write(&dwUser,sizeof(dwUser),NULL);
spStream->Write(&dwAspect,sizeof(dwAspect),NULL);
return IPersistStorageImpl<SSmileyCtrl>::Load(pStorage);
}
STDMETHODIMP SSmileyCtrl::GetMiscStatus(DWORD dwAspect, DWORD *pdwStatus)
{
(dwAspect);
*pdwStatus = OLEMISC_RECOMPOSEONRESIZE |
OLEMISC_CANTLINKINSIDE |
OLEMISC_INSIDEOUT |
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST;
return S_OK;
}
STDMETHODIMP SSmileyCtrl::SetClientSite(IOleClientSite *pClientSite)
{
if(pClientSite)
{
CComPtr<IRichEditOleCallback> pCallback;
HRESULT hr=pClientSite->QueryInterface(IID_IRichEditOleCallback,(void**)&pCallback);
if(FAILED(hr)) return E_FAIL;
//<EFBFBD><EFBFBD>callback<EFBFBD>л<EFBFBD>ȡhost
hr = pCallback->QueryInterface(__uuidof(ISmileyHost),(LPVOID*)&m_pSmileyHost);
if(FAILED(hr)) return E_FAIL;
}
return __super::SetClientSite(pClientSite);
}
LONG GetOleCP(IRichEditOle *pOle, int iOle)
{
REOBJECT reobj={0};
reobj.cbStruct=sizeof(REOBJECT);
pOle->GetObject(iOle,&reobj,REO_GETOBJ_NO_INTERFACES);
return reobj.cp;
}
//find first Ole Object in char range of [cpMin,cpMax)
int FindFirstOleInrange(IRichEditOle *pOle, int iBegin,int iEnd,int cpMin,int cpMax)
{
if(iBegin==iEnd) return -1;
int iMid = (iBegin + iEnd)/2;
LONG cp = GetOleCP(pOle,iMid);
if(cp < cpMin)
{
return FindFirstOleInrange(pOle,iMid+1,iEnd,cpMin,cpMax);
}else if(cp >= cpMax)
{
return FindFirstOleInrange(pOle,iBegin,iMid,cpMin,cpMax);
}else
{
int iRet = iMid;
while(iRet>iBegin)
{
cp = GetOleCP(pOle,iRet-1);
if(cp<cpMin) break;
iRet --;
}
return iRet;
}
}
//find Last Ole Object in char range of [cpMin,cpMax)
int FindLastOleInrange(IRichEditOle *pOle, int iBegin,int iEnd,int cpMin,int cpMax)
{
if(iBegin==iEnd) return -1;
int iMid = (iBegin + iEnd)/2;
LONG cp = GetOleCP(pOle,iMid);
if(cp < cpMin)
{
return FindLastOleInrange(pOle,iMid+1,iEnd,cpMin,cpMax);
}else if(cp >= cpMax)
{
return FindLastOleInrange(pOle,iBegin,iMid,cpMin,cpMax);
}else
{
int iRet = iMid;
while(iRet<(iEnd-1))
{
cp = GetOleCP(pOle,iRet+1);
if(cp>=cpMax) break;
iRet ++;
}
return iRet;
}
}
//<EFBFBD><EFBFBD><EFBFBD>ñ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD>״̬
DWORD SSmileyCtrl::GetSmileyFlag(IRichEditOle *ole,int iFirst,int iLast)
{
ATLASSERT(m_pSmileyHost);
DWORD dwFlag =0;
for(int i=iFirst;i<=iLast;i++)
{
REOBJECT reobj={0};
reobj.cbStruct=sizeof(REOBJECT);
HRESULT hr=ole->GetObject(i,&reobj,REO_GETOBJ_NO_INTERFACES);
if(FAILED(hr)) break;
if (reobj.clsid==CLSID_SSmileyCtrl && reobj.dwUser==m_dwID)
{
//ѡ<EFBFBD>е<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>Ʊ߿<EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>ɫ
CHARRANGE chr={0};
m_pSmileyHost->SendMessage(EM_EXGETSEL, 0, (LPARAM)&chr,NULL);
if ( chr.cpMin!=chr.cpMax
&& (reobj.cp<chr.cpMax && reobj.cp>=chr.cpMin) )
{
if((chr.cpMax-chr.cpMin) > 1)
dwFlag=REO_INVERTEDSELECT;
else
dwFlag=REO_SELECTED;
}
break;
}
}
return dwFlag;
}
void SSmileyCtrl::UpdateSmileyFlag()
{
if(!m_pSmileyHost) return ;
if(m_dwDrawFlag!=-1) return;
CComPtr<IRichEditOle> ole;
LRESULT lMsgRet = 0;
m_pSmileyHost->SendMessage(EM_GETOLEINTERFACE, 0, (LPARAM)&ole,&lMsgRet);
if (!lMsgRet) return;
//<EFBFBD><EFBFBD><EFBFBD>ÿɼ<EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD>Χ
m_pSmileyHost->SendMessage(EM_GETFIRSTVISIBLELINE,0,0,&lMsgRet);
int iFirstLine = (int)lMsgRet;
RECT rcView;
m_pSmileyHost->SendMessage(EM_GETRECT,0,(LPARAM)&rcView,&lMsgRet);
POINT pt={rcView.right+1,rcView.bottom-2};
m_pSmileyHost->SendMessage(EM_LINEINDEX,iFirstLine,0,&lMsgRet);
LONG cpFirst = (LONG)lMsgRet;
m_pSmileyHost->SendMessage(EM_CHARFROMPOS,0,(LPARAM)&pt,&lMsgRet);
LONG cpLast = (LONG)lMsgRet;
//<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڿɼ<EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD>е<EFBFBD>OLE<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int nCount=ole->GetObjectCount();
int iFirstVisibleOle = FindFirstOleInrange(ole,0,nCount,cpFirst,cpLast);
if(iFirstVisibleOle==-1) return;
int iLastVisibleOle = FindLastOleInrange(ole,iFirstVisibleOle,nCount,cpFirst,cpLast);
m_dwDrawFlag = GetSmileyFlag(ole,iFirstVisibleOle,iLastVisibleOle);
}
STDMETHODIMP SSmileyCtrl::Clear()
{
memset(&m_rcPos,0,sizeof(RECT));
m_dwDrawFlag = -1;
return S_OK;
}
HRESULT CreateSmiley(REFIID riid,void ** ppUnk)
{
SSmileyCtrl * pRet = new SComObject<SSmileyCtrl>;
HRESULT hr = pRet->QueryInterface(riid,ppUnk);
if(hr != S_OK) delete pRet;
return hr;
}