⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atlvcl.h

📁 OPC客户端程序
💻 H
📖 第 1 页 / 共 3 页
字号:
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 + -