Chinaunix首页 | 论坛 | 博客
  • 博客访问: 18682050
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类: C/C++

2008-05-31 11:40:38

我们通过实例来学习在AO中接口的使用方法,我们要学的这个实例是在VC 6.0下用ATL创建的一个COM。
    COM的创建的主要步骤是:
    1.实现esriSystemUI ICommand接口,使用户可以把这个组建模型加入ArcScene或其他工具栏上,在点击这个按钮的时候实现相关操作。
    2.创建一个连接点实现ISceneGraphEvents接口事件,并改写fire事件的相关函数。我在Fire_BeforeDraw和Fire_AfterDraw中加了一些OpenGL的函数以实现雾化的效果。
    3.回过头,我们具体实现ICommand接口。在ICommand的OnCreate函数中用ISceneHookHelper钩住IScene。在OnClick中我们通过ISceneHookHelper进一步获得ISceneViewer用来刷新场景。在刷新场景的前后分别调用Fire_BeforeDraw和Fire_AfterDraw来绘制雾化效果。这样ArcScene中的sink们就可以响应fire事件函数了,中国自学编程网, 。
    主要流程是这样的:用户-->ArcScene-->ICommand接口-->自定义接口-->连接点-->fire事件-->OpenGL-->ArcScene。
    工程名:Walkthrough1Cpp;自定义接口类:CZoomIn;代理接口事件类CProxyISceneGraphEvents
    注意:在用ATL创建接口的时候,要在属性面板Interface中选择Custom而不是Dual,前者继承IUnkown,后者继承IDispatch。还要选择支持连接点。
// stdafx.h : include file for standard system include files,
//      or project specific include files that are used frequently,
//      but are changed infrequently
#if !defined(AFX_STDAFX_H__FF23B542_C904_4F39_8A97_C4DE3C45A0E6__INCLUDED_)
#define AFX_STDAFX_H__FF23B542_C904_4F39_8A97_C4DE3C45A0E6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define STRICT
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#define _ATL_APARTMENT_THREADED
#include 
//You may derive a class from CComModule and use it if you want to override
//something, but do not change the name of _Module
extern CComModule _Module;
#include 
#pragma warning(push)
#pragma warning(disable : 4146)
#pragma warning(disable : 4192)
#import \"e:\\Program Files\\ArcGIS\\com\\esriSystem.olb\" raw_interfaces_only raw_native_types no_namespace 
named_guids exclude(\"OLE_COLOR\", \"OLE_HANDLE\", \"VARTYPE\") [Page]
#import \"e:\\Program Files\\ArcGIS\\com\\esriSystemUI.olb\" raw_interfaces_only raw_native_types no_namespace 
named_guids
#import \"e:\\Program Files\\ArcGIS\\com\\esriGeometry.olb\" raw_interfaces_only raw_native_types no_namespace 
named_guids
#import \"e:\\Program Files\\ArcGIS\\com\\esriDisplay.olb\" raw_interfaces_only raw_native_types no_namespace 
named_guids
#import \"e:\\Program Files\\ArcGIS\\com\\esriGeoDatabase.olb\" raw_interfaces_only raw_native_types 
no_namespace named_guids
#import \"e:\\Program Files\\ArcGIS\\com\\esriCarto.olb\" raw_interfaces_only raw_native_types no_namespace 
named_guids
#import \"e:\\Program Files\\ArcGIS\\com\\esriControlCommands.olb\" raw_interfaces_only raw_native_types 
no_namespace named_guids
#import \"e:\\Program Files\\ArcGIS\\com\\esriFramework.olb\" raw_interfaces_only raw_native_types no_namespace 
named_guids
#import \"e:\\Program Files\\ArcGIS\\com\\esri3DAnalyst.olb\" raw_interfaces_only raw_native_types no_namespace 
named_guids
#pragma warning(pop)  
#include \"gl\\gl.h\"
#include \"gl\\glu.h\"
#include \"gl\\glaux.h\"
#include 
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__FF23B542_C904_4F39_8A97_C4DE3C45A0E6__INCLUDED)
 
 
// ZoomIn.h : Declaration of the CZoomIn
#ifndef __ZOOMIN_H_
#define __ZOOMIN_H_
#include \"resource.h\"       // main symbols
#include \"esri3DAnalystCP.h\"
//#import \"D:\\Program Files\\ArcGIS\\com\\esriSystemUI.olb\" raw_interfaces_only, raw_native_types, 
no_namespace, named_guids 
/////////////////////////////////////////////////////////////////////////////
// CZoomIn
class ATL_NO_VTABLE CZoomIn : 

 public CComObjectRootEx,
 public CComCoClass,
 public IZoomIn,
 public ICommand,
 public CProxyISceneGraphEvents< CZoomIn >,
 public IConnectionPointContainerImpl [Page]
{
public:
  CZoomIn()
  {
    m_hBitmap = ::LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_ZOOMIN));
  }
  ~CZoomIn()
  {
    DeleteObject(m_hBitmap);
  }
  IHookHelperPtr    m_ipHookHelper;
  ISceneHookHelperPtr  m_ipSceneHookHelper;
DECLARE_REGISTRY_RESOURCEID(IDR_ZOOMIN)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CZoomIn)
 COM_INTERFACE_ENTRY(IZoomIn)
 COM_INTERFACE_ENTRY(ICommand)
 COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
// IZoomIn private:
    HBITMAP    m_hBitmap;
public:
// ICommand
 STDMETHOD(get_Enabled)(VARIANT_BOOL * Enabled);
 STDMETHOD(get_Checked)(VARIANT_BOOL * Checked);
 STDMETHOD(get_Name)(BSTR * Name);
 STDMETHOD(get_Caption)(BSTR * Caption);
 STDMETHOD(get_Tooltip)(BSTR * Tooltip);
 STDMETHOD(get_Message)(BSTR * Message);
 STDMETHOD(get_HelpFile)(BSTR * HelpFile);
 STDMETHOD(get_HelpContextID)(LONG * helpID);
 STDMETHOD(get_Bitmap)(OLE_HANDLE * Bitmap);
 STDMETHOD(get_Category)(BSTR * categoryName);
 STDMETHOD(OnCreate)(IDispatch * hook);
 STDMETHOD(OnClick)();
public :
BEGIN_CONNECTION_POINT_MAP(CZoomIn)
 CONNECTION_POINT_ENTRY(IID_ISceneGraphEvents)
END_CONNECTION_POINT_MAP()
};
#endif //__ZOOMIN_H_
 
 
// ZoomIn.cpp : Implementation of CZoomIn
#include \"stdafx.h\"
#include \"Walkthrough1Cpp.h\"
#include \"ZoomIn.h\"
/////////////////////////////////////////////////////////////////////////////
// CZoomIn
STDMETHODIMP CZoomIn::get_Enabled(VARIANT_BOOL * Enabled)
{
 if (Enabled == NULL)
      return E_POINTER;
      
    *Enabled = VARIANT_TRUE;   // Enable the tool always
    return S_OK;
}
STDMETHODIMP CZoomIn::get_Checked(VARIANT_BOOL * Checked)
{
 if (Checked == NULL)
  return E_POINTER;
  
 return E_NOTIMPL;
}
STDMETHODIMP CZoomIn::get_Name(BSTR * Name)
{
if (Name == NULL) [Page]
      return E_POINTER;
    *Name = ::SysAllocString(L\"ZoomIn x 0.5 Cpp\");
    return S_OK;
}
STDMETHODIMP CZoomIn::get_Caption(BSTR * Caption)
{
 if (Caption == NULL)
      return E_POINTER;
    *Caption = ::SysAllocString(L\"ZoomIn x 0.5 Cpp\");
    return S_OK;
}
STDMETHODIMP CZoomIn::get_Tooltip(BSTR * Tooltip)
{
 if (Tooltip == NULL)
  return E_POINTER;
  
 return E_NOTIMPL;
}
STDMETHODIMP CZoomIn::get_Message(BSTR * Message)
{
 if (Message == NULL)
  return E_POINTER;
  
 return E_NOTIMPL;
}
STDMETHODIMP CZoomIn::get_HelpFile(BSTR * HelpFile)
{
 if (HelpFile == NULL)
  return E_POINTER;
  
 return E_NOTIMPL;
}
STDMETHODIMP CZoomIn::get_HelpContextID(LONG * helpID)
{
 if (helpID == NULL)
  return E_POINTER;
  
 return E_NOTIMPL;
}
STDMETHODIMP CZoomIn::get_Bitmap(OLE_HANDLE * Bitmap)
{
   if (Bitmap == NULL)
      return E_POINTER;
    *Bitmap = (OLE_HANDLE) m_hBitmap;
    return S_OK;
}
STDMETHODIMP CZoomIn::get_Category(BSTR * categoryName)
{
  if (categoryName == NULL)
      return E_POINTER;

  *categoryName = ::SysAllocString(L\"Developer Samples\");
    return S_OK;
}
STDMETHODIMP CZoomIn::OnCreate(IDispatch * hook)
{
 m_ipSceneHookHelper.CreateInstance(CLSID_SceneHookHelper);
 HRESULT hr = m_ipSceneHookHelper->putref_Hook(hook);
    return hr;
}
STDMETHODIMP CZoomIn::OnClick()
{
  // HRESULT checking omitted for clarity
 IScenePtr ipScene;
 m_ipSceneHookHelper->get_Scene(&ipScene);
 ISceneGraphPtr ipSceneGraph;
 ipScene->get_SceneGraph(&ipSceneGraph);
 
 ISceneViewer * pViewer;
 ipSceneGraph->get_ActiveViewer(&pViewer); [Page]
 Fire_BeforeDraw(pViewer, NULL);
 ipSceneGraph->RefreshViewers();
 Fire_AfterDraw(pViewer);
        return S_OK;
} // Walkthrough1Cpp.idl : IDL source for Walkthrough1Cpp.dll
//
// This file will be processed by the MIDL tool to
// produce the type library (Walkthrough1Cpp.tlb) and marshalling code.
import \"oaidl.idl\";
import \"ocidl.idl\";
 [
  object,
  uuid(5CA669DE-0DFE-4C49-8546-B8AE24A629D5),
 
  helpstring(\"IZoomIn Interface\"),
  pointer_default(unique)
 ]
 interface IZoomIn : IUnknown
 {
 };
[
 uuid(5C0841D7-80E7-4CDB-AFCD-5D77B23B879E),
 version(1.0),
 helpstring(\"Walkthrough1Cpp 1.0 Type Library\")
]
library WALKTHROUGH1CPPLib
{
 importlib(\"stdole32.tlb\");
 importlib(\"stdole2.tlb\");
 importlib(\"e:\\Program Files\\ArcGIS\\com\\esriSystemUI.olb\");
 [
  uuid(C9265E95-7317-4CB2-9ACC-E3EA5C9CA550),
  helpstring(\"ZoomIn Class\")
 ]
 coclass ZoomIn
 {
  [default] interface IUnknown;
  interface IZoomIn;
  interface ICommand;
//  [default] interface IZoomIn;
 };
};
 
 
//esri3DAnalystCP.h
#ifndef _ESRI3DANALYSTCP_H_
#define _ESRI3DANALYSTCP_H_
#import \"E:\\Program Files\\ArcGIS\\com\\esri3DAnalyst.olb\" raw_interfaces_only, raw_native_types, 
no_namespace, named_guids //\"Import typelib\"
template 
class CProxyISceneGraphEvents : public IConnectionPointImplCComDynamicUnkArray>
{
 //Warning this class may be recreated by the wizard.
public:
 HRESULT Fire_ActiveViewerChanged(ISceneViewer * pViewer)
 {
  HRESULT ret;
  T* pT = static_cast(this);
  int nConnectionIndex;
  int nConnections = m_vec.GetSize();
  
  for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
  {
   pT->Lock();
   CComPtr sp = m_vec.GetAt(nConnectionIndex); [Page]
   pT->Unlock();
   ISceneGraphEvents* pISceneGraphEvents = reinterpret_cast
(sp.p);
   if (pISceneGraphEvents != NULL)
    ret = pISceneGraphEvents->ActiveViewerChanged(pViewer);
  } return ret;
 
 }
 HRESULT Fire_ViewerAdded(ISceneViewer * pViewer)
 {
  HRESULT ret;
  T* pT = static_cast(this);
  int nConnectionIndex;
  int nConnections = m_vec.GetSize();
  
  for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
  {
   pT->Lock();
   CComPtr sp = m_vec.GetAt(nConnectionIndex);
   pT->Unlock();
   ISceneGraphEvents* pISceneGraphEvents = reinterpret_cast
(sp.p);
   if (pISceneGraphEvents != NULL)
    ret = pISceneGraphEvents->ViewerAdded(pViewer);
  } return ret;

 } HRESULT Fire_ViewerRemoved(ISceneViewer * pViewer)
 {
  HRESULT ret;
  T* pT = static_cast(this);
  int nConnectionIndex;
  int nConnections = m_vec.GetSize();
  
  for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
  {
   pT->Lock();
   CComPtr sp = m_vec.GetAt(nConnectionIndex);
   pT->Unlock();
   ISceneGraphEvents* pISceneGraphEvents = reinterpret_cast
(sp.p);
   if (pISceneGraphEvents != NULL)
    ret = pISceneGraphEvents->ViewerRemoved(pViewer);
  } return ret;
 
 }
 HRESULT Fire_InteractionStopped()
 {
  HRESULT ret;
  T* pT = static_cast(this);
  int nConnectionIndex;
  int nConnections = m_vec.GetSize();
  
  for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++) [Page]
  {
   pT->Lock();
   CComPtr sp = m_vec.GetAt(nConnectionIndex);
   pT->Unlock();
   ISceneGraphEvents* pISceneGraphEvents = reinterpret_cast
(sp.p);
   if (pISceneGraphEvents != NULL)
    ret = pISceneGraphEvents->InteractionStopped();
  } return ret;
 
 }
 HRESULT Fire_RecordingStarted(BSTR Name)
 {
  HRESULT ret;
  T* pT = static_cast(this);
  int nConnectionIndex;
  int nConnections = m_vec.GetSize();
  
  for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
  {
   pT->Lock();
   CComPtr sp = m_vec.GetAt(nConnectionIndex);
   pT->Unlock();
   ISceneGraphEvents* pISceneGraphEvents = reinterpret_cast
(sp.p);
   if (pISceneGraphEvents != NULL)
    ret = pISceneGraphEvents->RecordingStarted(Name);
  } return ret;
 
 }
 HRESULT Fire_RecordingStopped()
 {
  HRESULT ret;
  T* pT = static_cast(this);
  int nConnectionIndex;
  int nConnections = m_vec.GetSize();
  
  for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
  {
   pT->Lock();
   CComPtr sp = m_vec.GetAt(nConnectionIndex);
   pT->Unlock();
   ISceneGraphEvents* pISceneGraphEvents = reinterpret_cast
(sp.p);
   if (pISceneGraphEvents != NULL)
    ret = pISceneGraphEvents->RecordingStopped();
  } return ret;
 
 }
 HRESULT Fire_BeforeDraw(ISceneViewer * pViewer, VARIANT_BOOL * pbHandled)
 {
  ISceneGraphPtr ipSceneGraph;
  pViewer->get_SceneGraph(&ipSceneGraph);  [Page]
  IEnvelopePtr pExtent;
  ipSceneGraph->get_Extent(&pExtent);
     
  ICameraPtr pCamera;
  pViewer->get_Camera(&pCamera);
  double Near;
  double Far;
  double Angle;
  double m_aspect;
  pCamera->QueryViewingPlatformMBB(pExtent, &Near, &Far, &Angle, &m_aspect);
  glEnable(GL_FOG);
  glFogf(GL_FOG_MODE, GL_LINEAR);
  glFogf(GL_FOG_START, Near);
  glFogf(GL_FOG_END, Far);
  float red = 0.8;
  float green = 0.4;
  float blue = 0.4;
  
  GLfloat FogColor[4] = {red, green, blue, 1};

 glFogfv(GL_FOG_COLOR, FogColor);
 

  HRESULT ret;
  T* pT = static_cast(this);
  int nConnectionIndex;
  int nConnections = m_vec.GetSize();
  
  for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
  {
   pT->Lock();
   CComPtr sp = m_vec.GetAt(nConnectionIndex);
   pT->Unlock();
   ISceneGraphEvents* pISceneGraphEvents = reinterpret_cast
(sp.p);
   if (pISceneGraphEvents != NULL)
    ret = pISceneGraphEvents->BeforeDraw(pViewer, pbHandled);
  } return ret;
 
 }
 HRESULT Fire_AfterDraw(ISceneViewer * pViewer)
 {
  
  glDisable(GL_FOG);
  HRESULT ret;
  T* pT = static_cast(this);
  int nConnectionIndex;
  int nConnections = m_vec.GetSize();
  
  for (nConnectionIndex = 0; nConnectionIndex < nConnections; nConnectionIndex++)
  {
   pT->Lock();
   CComPtr sp = m_vec.GetAt(nConnectionIndex);
   pT->Unlock();
   ISceneGraphEvents* pISceneGraphEvents = reinterpret_cast [Page]
(sp.p);
   if (pISceneGraphEvents != NULL)
    ret = pISceneGraphEvents->AfterDraw(pViewer);
  } return ret;
 
 }
};
#endif
处理前

阅读(421) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~