📄 atlvcl.h
字号:
class ATL_NO_VTABLE IDataBrokerImpl: public IDispatchImpl<Intf, piid, plibid>
{
public:
DM* m_DataModule; // The Data Module
IDataBrokerImpl()
{
m_DataModule = new DM(NULL);
}
~IDataBrokerImpl()
{
m_DataModule->Free();
}
HRESULT IDataBroker_GetProviderNames(System::OleVariant &Result)
{
unsigned int TICount;
_di_ITypeInfo TI;
TPtr<Classes::TStringList> ProvProps(new TStringList);
HRESULT hres = GetTypeInfoCount(&TICount);
if (hres != S_OK)
return hres;
if (TICount)
{
hres = GetTypeInfo(0, 0, &TI);
if (hres != S_OK)
return hres;
Databkr::EnumIProviderProps(TI, ProvProps);
::VariantClear(&(VARIANT&)Result);
Result = Databkr::VarArrayFromStrings(ProvProps);
}
return S_OK;
}
// IDataBroker
//
HRESULT STDMETHODCALLTYPE GetProviderNames(System::OleVariant &Result)
{
ATLTRACE(_T("IDataBroker::GetProviderNames\n"));
HRESULT hres;
try
{
hres = static_cast<T*>(this)->IDataBroker_GetProviderNames(Result);
}
catch (Exception& e)
{
return (static_cast<T*>(this))->Error(e.Message.c_str());
}
return hres;
}
};
// ISimpleFrameSite support
//
template <class T>
class ATL_NO_VTABLE ISimpleFrameSiteImpl
{
public:
// IUnknown
STDMETHOD(QueryInterface)(REFIID riid, void ** ppvObject) = 0;
_ATL_DEBUG_ADDREF_RELEASE_IMPL(ISimpleFrameSite)
// ISimpleFrameSite
STDMETHOD(PreMessageFilter)(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp,
LRESULT* plResult, DWORD* pdwCookie)
{
ATLTRACE(_T("ISimpleFrameImpl::PreMessageFilter\n"));
T* pT = static_cast<T*>(this);
return pT->ISimpleFrameSite_PreMessageFilter(hWnd, msg, wp, lp, plResult, pdwCookie);
}
STDMETHOD(PostMessageFilter)(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp,
LRESULT* plResult, DWORD dwCookie)
{
ATLTRACE(_T("ISimpleFrameImpl::PostMessageFilter\n"));
T* pT = static_cast<T*>(this);
return pT->ISimpleFrameSite_PostMessageFilter(hWnd, msg, wp, lp, plResult, dwCookie);
}
};
/* ActiveX control support */
// TVclComControl is an ATL ActiveX control which encapsulates a VCL control
// T is the user's class which implements the OLE Control.
// TVCL is the VCL type which is exposed as an ActiveX Control.
//
template <class T, class TVCL>
class ATL_NO_VTABLE TVclComControl: public CComControlBase, public CMessageMap
{
public:
TVclComControl(void): m_VclCtl(0), m_VclWinCtl(0), m_hWnd(0),
m_CtlWndProc(0), CComControlBase(m_hWnd)
{
m_bWindowOnly = TRUE;
}
~TVclComControl(void)
{
if (m_VclCtl)
{
m_VclCtl->WindowProc = m_CtlWndProc;
delete m_VclCtl;
}
if ((m_VclWinCtl) && ((TWinControl*)m_VclWinCtl != (TWinControl*)m_VclCtl))
delete m_VclWinCtl;
}
// IOleObject support
//
HRESULT IOleObject_SetClientSite(IOleClientSite *pClientSite)
{
HRESULT hres = CComControlBase::IOleObject_SetClientSite(pClientSite);
if (hres == S_OK)
{
if (m_spClientSite != NULL)
{
DWORD MiscFlags;
hres = static_cast<T*>(this)->GetMiscStatus(DVASPECT_CONTENT, &MiscFlags);
if (!SUCCEEDED(hres))
return hres;
// The following double checks that the registry entry indeed corresponds to
// the value specified by our Control. (NOTE: IOleObject's implementation
// looks up the value in the registry).
//
_ASSERTE(MiscFlags == static_cast<T*>(this)->_GetObjectMiscStatus());
if (MiscFlags & OLEMISC_SIMPLEFRAME)
{
m_spClientSite->QueryInterface(IID_ISimpleFrameSite,
(void**)&m_spSimpleFrameSite);
}
// Initialize the helper class used to get ambient properties from the container
m_AmbientDriver.Bind(m_spClientSite);
// Get ambient properties from the container and update the control
static_cast<T*>(this)->OnAmbientPropertyChange(0);
// Enable Ctl3D style
m_VclWinCtl->Perform(CM_PARENTCTL3DCHANGED, 1, 1);
}
else
{
m_spSimpleFrameSite = NULL;
m_AmbientDriver = NULL;
}
}
else
{
m_spClientSite = NULL;
m_AmbientDriver = NULL;
}
return hres;
}
// IPersistStreamInit support
//
// Note: IPersistStreamInit_Load and IPersistStreamInit_Save were in
// CComControlBase in ATL 2.1 but moved to IPersistStreamInitImpl in
// ATL 3.0. As a result, the methods need to be renamed in C++Builder 5.
HRESULT IPersistStreamInit_SaveVCL(LPSTREAM pStm, BOOL /* fClearDirty */, ATL_PROPMAP_ENTRY* pMap)
{
try
{
::SaveVCLComponentToStream((TVCL*)m_VclCtl, pStm);
//!?? Clear fClearDirty flag
}
catch (Exception& e)
{
return (static_cast<T*>(this))->Error(e.Message.c_str());
}
return S_OK;
}
HRESULT IPersistStreamInit_LoadVCL(LPSTREAM pStm, ATL_PROPMAP_ENTRY* pMap)
{
try
{
::LoadVCLComponentFromStream((TVCL*)m_VclCtl, pStm);
}
catch (Exception& e)
{
return (static_cast<T*>(this))->Error(e.Message.c_str());
}
return S_OK;
}
// ISimpleFrameSite support
//
HRESULT ISimpleFrameSite_PreMessageFilter(HWND hWnd, UINT msg, WPARAM wp,
LPARAM lp, LRESULT* plResult, DWORD* pdwCookie)
{
if (m_spSimpleFrameSite)
return m_spSimpleFrameSite->PreMessageFilter(hWnd, msg, wp, lp,
plResult, pdwCookie);
else
return S_OK;
}
HRESULT ISimpleFrameSite_PostMessageFilter(HWND hWnd, UINT msg, WPARAM wp,
LPARAM lp, LRESULT* plResult, DWORD dwCookie)
{
if (m_spSimpleFrameSite)
return m_spSimpleFrameSite->PostMessageFilter(hWnd, msg, wp, lp,
plResult, dwCookie);
else
return S_OK;
}
// IPropertyNotifySink Support methods
//
// NOTE: If your control class derives from IPropertyNotifySink, this method calls
// CFirePropNotifyEvent::FireOnRequestEdit to notify all connected IPropertyNotifySink interfaces
// that the specified control property is about to change. If your control class does not derive
// from IPropertyNotifySink, this method returns S_OK.
//
HRESULT FireOnRequestEdit(DISPID dispID)
{
T* pT = static_cast<T*>(this);
return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnRequestEdit(pT->GetUnknown(), dispID);
}
// If your control class derives from IPropertyNotifySink, this method calls
// CFirePropNotifyEvent::FireOnChanged to notify all connected IPropertyNotifySink interfaces
// that the specified control property has changed. If your control class does not derive from
// IPropertyNotifySink, this method returns S_OK
//
HRESULT FireOnChanged(DISPID dispID)
{
T* pT = static_cast<T*>(this);
return T::__ATL_PROP_NOTIFY_EVENT_CLASS::FireOnChanged(pT->GetUnknown(), dispID);
}
// Retrieves pointer to requested interface
// NOTE: Limited to interfaces listed in COM map table
//
virtual HRESULT ControlQueryInterface(const IID& iid, void** ppv)
{
T* pT = static_cast<T*>(this);
return pT->_InternalQueryInterface(iid, ppv);
}
// Creates underlying window of the control.
// NOTE: You may override this method to do something other than create an window (for
// example, to create two windows, one of which becomes a toolbar for your control).
//
HWND CreateControlWindow(HWND hWndParent, RECT& rcPos)
{
T* pT = static_cast<T*>(this);
return pT->Create(hWndParent, rcPos);
}
// Returns the handle of the control, if successful. Otherwise, returns NULL.
//
HWND Create(HWND hWndParent, RECT& rcPos);
// Sets the Window's show state (See ::ShowWindow of WIN32 SDK for details on 'nCmdShow')
//
BOOL ShowWindow(int nCmdShow)
{
_ASSERTE(m_hWnd);
return ::ShowWindow(m_hWnd, nCmdShow);
}
// Overridable Message Handler method of Control.
// NOTE: You may intercept messages in your control via an ATL Message Map.
// The default implementation of this method is to dispatch messages
// via the Message Map. If the message was not handled via a message
// map, the message is dispatched to the underlying VCL handler.
//
virtual void ControlWndProc(Messages::TMessage& Message);
// Procedure handling messages of this control
//
virtual void __fastcall WndProc(Messages::TMessage& Message);
// Method which destroys and re-create the control's window.
// NOTE: This may be necessary if you need to change the window's style bits.
//
void RecreateWnd();
// Data members
//
HWND m_hWnd; // Underlying Window Handle of our Control
protected:
virtual void InitializeControl();
void Initialize();
TWinControlAccess<TWinControl>* m_VclWinCtl;
TWinControlAccess<TVCL>* m_VclCtl;
TAutoDriver<IDispatch> m_AmbientDriver;
private:
TWndMethod m_CtlWndProc;
CComPtr<ISimpleFrameSite> m_spSimpleFrameSite;
};
// TVclComControl::Initialize
//
template <class T, class TVCL> void
TVclComControl<T, TVCL>::Initialize()
{
// Retrieve handle to reflector Window defined in AXCTRLS unit
//
HWND hwndParkingWindow = Axctrls::ParkingWindow();
// Create VCL Object Wrapper for our Control
//
m_VclCtl = (TWinControlAccess<TVCL>*)(TVCL::CreateParentedControl(__classid(TVCL), hwndParkingWindow));
// Test whether our control requires message reflection and create a reflector window if yes
//
if (m_VclCtl->ControlStyle.Contains(csReflector))
(TWinControl*)m_VclWinCtl = ::CreateReflectorWindow(hwndParkingWindow, m_VclCtl);
else
(TWinControl*)m_VclWinCtl = (TWinControl*)m_VclCtl;
// Update the Window Procedure variables
//
m_CtlWndProc = m_VclCtl->WindowProc;
m_VclCtl->WindowProc = WndProc;
// Invoke virtual allowing Control to perform additional initialization
//
InitializeControl();
ATLTRACE(_T("VCL control created and initialized\n"));
}
// InitializeControl is typically overriden in the derived class.
// It's used to initialize Closures to catch VCL events and turn
// them into OLE events.
//
template <class T, class TVCL> void
TVclComControl<T, TVCL>::InitializeControl(void)
{}
// TVclComControl::ReCreateWnd
//
template <class T, class TVCL> void
TVclComControl<T, TVCL>::RecreateWnd()
{
if (m_VclWinCtl->HandleAllocated())
{
RECT CtlBounds = m_VclWinCtl->BoundsRect;
HWND PrevWnd = ::GetWindow(m_VclWinCtl->Handle, GW_HWNDPREV);
// set ATL window handle to NULL to prevent InPlaceDeactiveate()
// from destroying the VCL control window too soon
//
m_hWndCD = NULL;
IOleInPlaceObject_InPlaceDeactivate();
m_VclWinCtl->DoDestroyHandle();
m_VclWinCtl->UpdateControlState();
if (InPlaceActivate(m_bUIActive ? OLEIVERB_INPLACEACTIVATE : OLEIVERB_HIDE,
&CtlBounds) == S_OK)
::SetWindowPos(m_VclWinCtl->Handle, PrevWnd, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
}
}
// TVclComControl::Create
//
template <class T, class TVCL> HWND
TVclComControl<T, TVCL>::Create(HWND hWndParent, RECT& rcPos)
{
_ASSERTE(m_VclCtl);
// Set the parent handle here because with a parking window of NULL. The
// window is not created until the parent is set.
//
m_VclWinCtl->ParentWindow = hWndParent;
m_VclWinCtl->BoundsRect = rcPos;
// For ActiveForms the window handle will be NULL at this point; so, force create.
//
m_VclWinCtl->HandleNeeded();
// For ActiveForms again, the window will not be visible. So, show it.
//
m_VclWinCtl->Visible = true;
// Update and return handle
//
m_hWnd = m_VclWinCtl->GetWindowHandle();
return m_hWnd;
}
// TVclComControl::ControlWndProc
//
template <class T, class TVCL> void
TVclComControl<T, TVCL>::ControlWndProc(Messages::TMessage& Message)
{
if ((Message.Msg >= OCM_BASE) && (Message.Msg < OCM_BASE + WM_USER))
Message.Msg = Message.Msg + (CN_BASE - OCM_BASE);
// Allow ATL message maps to intercept messages before they are dispatch to VCL handlers
//
if (!ProcessWindowMessage(m_VclCtl->GetWindowHandle(), Message.Msg,
Message.WParam, Message.LParam,
*((LRESULT*)(&Message.Result)), 0))
m_CtlWndProc(Message);
if ((Message.Msg >= CN_BASE) && (Message.Msg < CN_BASE + WM_USER))
Message.Msg = Message.Msg - (CN_BASE - OCM_BASE);
}
// TvclComControl::WndProc
// Procedure handling messages of this control
//
template <class T, class TVCL> void __fastcall
TVclComControl<T, TVCL>::WndProc(Messages::TMessage& Message)
{
DWORD dwCookie;
HWND Handle = m_VclCtl->GetWindowHandle();
bool FilterMessage = ((Message.Msg < CM_BASE) || (Message.Msg >= 0xC000)) &&
m_spSimpleFrameSite && m_bInPlaceActive;
if (FilterMessage)
{
if (m_spSimpleFrameSite->PreMessageFilter(Handle,
Message.Msg, Message.WParam,
Message.LParam, (LRESULT*)&Message.Result,
&dwCookie) == S_FALSE)
return;
}
T* pT = static_cast<T*>(this);
CComPtr<IOleControlSite> spSite;
switch (Message.Msg)
{
case WM_SETFOCUS:
case WM_KILLFOCUS:
ControlWndProc(Message);
m_spClientSite->QueryInterface(IID_IOleControlSite, (void**)&spSite);
if (spSite)
spSite->OnFocus(Message.Msg == WM_SETFOCUS);
break;
case CM_VISIBLECHANGED:
if ((TWinControl*)m_VclCtl != (TWinControl*)m_VclWinCtl)
m_VclWinCtl->Visible = m_VclCtl->Visible;
if (!(m_VclWinCtl->Visible))
IOleInPlaceObject_UIDeactivate();
ControlWndProc(Message);
break;
case CM_RECREATEWND:
if ((m_bInPlaceActive) && ((TWinControl*)m_VclCtl == (TWinControl*)m_VclWinCtl))
RecreateWnd();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -