zoukankan      html  css  js  c++  java
  • AO的Display对象简介二【转载】

     AO的Display对象简介二

    刷新相对失效
        为了引起一个显示重画,这个失效的程序一定要调用。大多数的客户端决不用IScreenDisplay::Invalidate。这是因为如果一个视图在 你的程序中被调用,这个视图应该为屏幕刷新。这个视图管理显示缓冲器和知道最好的方法去执行失效。仅仅要确定PartialRefresh调用。一但停止 无效,为了允许视图(Map和PageLayout)完全管理显示缓冲区,所有的无效一定要通过视图。调用IActiveView::Refresh总是 绘画毎一个对象。这是非常低效的。这个方法调用PartialRefresh应该在任何可能的时候。它让你指定视图什么部分重画和允许视图和显示缓冲区一 起工作,这个方法绘画是快速和高效的。

    绘制阶段

    地图

    排版

    esriViewBackground

    不用

    page/snap grid

    esriViewGeography

    layers

    不用

    esriViewGeoSelection

    feature selection

    不用

    esriViewGraphics

    labels/graphics

    graphics

    esriViewGraphicSelection

    graphic selection

    element selection

    esriViewForeground

    不用

    snap guides

    下面的表显示一些例子调用空间刷新;

    操作

    方法调用

    Refresh Layer

    pMap.PartialRefresh(esriViewGeography, pLayer, 0)

    Refresh All Layers

    pMap.PartialRefresh(esriViewGeography, 0, 0)

    Refresh Selection

    pMap.PartialRefresh(esriViewGeoSelection, 0, 0)

    Refresh Labels

    pMap.PartialRefresh(esriViewGraphics, 0, 0)

    Refresh Element

    pLayout.PartialRefresh(esriViewGraphics, pElement, 0)

    Refresh All Elements

    pLayout.PartialRefresh(esriViewGraphics, 0, 0)

    Refresh Selection

    pLayout.PartialRefresh(esriViewGraphicSelection, 0, 0)

       注释:任何一个失效将会引起记录缓冲器失效。为了强加从记录缓冲器重画,用下面的方法调用:pScreenDisplay.Invalidate(0, VARIANT_FALSE, esriNoScreenCache);

    显示事件

       这一节就要描述当地图绘画时的调用的事件。下面提供更好洞察绘画事件,绘画顺序和显示缓冲器。

    绘制顺序

       为了更好的理解地图的绘制的事件,下面一节主要讲述了每一种视图对象被绘画的顺序。

    Map(数据视图):下面显示由高到低的顺序,每一条被画上面的高于下面的一条:

    对象

    阶段

    缓冲

    Graphic Selection

    esriViewForeground

    none

    Clip Border

    esriViewForeground

    none

    Feature Selection

    esriViewGeoSelection

    selection

    Auto Labels

    esriViewGraphics

    annotation

    Graphics

    esriViewGraphics

    annotation

    Layer Annotation

    esriViewGraphics

    annotation

    Layers

    esriViewGeography

    layer(s)

    Background

    esriViewBackground

    bottom layer

    PageLayout:

    对象

    阶段

    缓冲

    Snap Guides

    esriViewForeground

    none

    Selection

    esriViewGraphicSelection

    selection

    Elements

    esriViewGraphics

    element

    Snap Grid

    esriViewBackground

    element

    Print Margins

    esriViewBackground

    element



    显示设计模式
       为了帮助你理解怎样和各种显示对象一起工作来解决一般的开发需求,一些应用情节和细节在他们执行被给。用这些模式作为显示对象一起工作的引点。
    应用窗口
       最一般的任务之一是来在支持滚动和备份存储的应用窗口的客户端区域绘制地图。这个显示对象在下面的情况可能被用。
    初始化
       当窗口被创建时,通过创建一个Screen Display开始。你需要创建一个或多个符号用来绘制形状。使应用句柄到pScreenDisplay.Hwnd。从它 IDisplayTransformation接口的Screen Display得到和用pTransformation.Bounds和pDisplayTransform.VisibleBounds来设置全图和可 视范围。可视范围决定当前空间水平。Screen Display关心更新DeviceFrame的转化显示。Screen Display管理窗口的消息和一般的事件的句柄像窗口的大小和滚动。

    Private m_pScreenDisplay As IScreenDisplay
    Private m_pFillSymbol As ISimpleFillSymbol
    Private Sub Form_Load()
      Set m_pScreenDisplay = New ScreenDisplay
      m_pScreenDisplay.hWnd = Picture1.hWnd
      Set m_pFillSymbol = New SimpleFillSymbol
      Dim pEnv As IEnvelope
      Set pEnv = New Envelope
      pEnv.PutCoords 0, 0, 50, 50
      m_pScreenDisplay.DisplayTransformation.bounds = pEnv
      m_pScreenDisplay.DisplayTransformation.VisibleBounds = pEnv
    End Sub

    绘画
       显示对象定义一个基本的IDraw接口,这个接口很容易对任何显示的绘制。只要你用IDraw或IDisplay来执行你的绘制代码,你不用担心你要绘制 的哪一种设备。一个绘制过程用StartDrawing开始和用FinishDrawing完成。例如,创建一个程序在屏幕中心建立一个多边形并且绘制 它。这个形状用默认的符号。

    Private Function GetPolygon() As IPolygon
      Set GetPolygon = New Polygon
      Dim pPointCollection As IPointCollection
      Set pPointCollection = GetPolygon
      Dim pPoint As IPoint
      Set pPoint = New Point
      pPoint.PutCoords 20, 20
      pPointCollection.AddPoint pPoint
      pPoint.PutCoords 30, 20
      pPointCollection.AddPoint pPoint
      pPoint.PutCoords 30, 30
      pPointCollection.AddPoint pPoint
      pPoint.PutCoords 20, 30
      pPointCollection.AddPoint pPoint
      GetPolygon.Close
    End Function

    Private Sub MyDraw(pDisplay As IDisplay, hDC As esriSystem.OLE_HANDLE)
      ' Draw from Scratch
      Dim pDraw As IDraw
      Set pDraw = pDisplay
      pDraw.StartDrawing hDC, esriNoScreenCache
      Dim pPoly As IPolygon
      Set pPoly = GetPolygon()
      pDraw.SetSymbol m_pFillSymbol
      pDraw.Draw pPoly
      pDraw.FinishDrawing
    End Sub

    这段程序可以在任何设备中绘制多边形。不管怎么样,第一地方我们需要绘制到窗口。为了处理这个,在那些应用程序的 Screen Display的指示器和PictureBox的句柄的PictureBox的Paint方法中写一些代码到MyDraw程序中去。注意这个程序接受显示 指示器和窗口设备。
    Private Sub Picture1_Paint()
      MyDraw m_pScreenDisplay, Picture1.hDC
    End Sub

    增加显示缓冲区
    一些绘画过程可能花一段时间才能完成。一个简单的方法来提高 性能就是用运显示缓冲区。这个涉及到Screen Display的能力来记录你的绘画过程到一个位图中,然后当不论何时Paint方法被调用,就用这个位图来刷新图片的窗口。直到你的数据改变和你调用 IScreenDisplay::Invalidate来指定哪个缓冲区是无效的,这个缓冲区就会被用。有两种缓冲区:一个是记录缓冲区,一个是用户联合 缓冲区。用记录在应用程序的Paint方法中来执行显示缓冲区。

    Private Sub Picture1_Paint()
      If (m_pScreenDisplay.IsCacheDirty(esriScreenRecording)) Then
        m_pScreenDisplay.StartRecording
        MyDraw m_pScreenDisplay, Picture1.hDC
        m_pScreenDisplay.StopRecording
      Else
        Dim rect As tagRECT
        m_pScreenDisplay.DrawCache Picture1.hDC, esriScreenRecording, rect, rect
      End If
    End Sub

    当你执行这个代码时,你将会看到在屏幕上什么也没有画。这个由于ScreenRecording缓冲区没有设置。为确定MyDraw函数被调用,当首先绘画消息被接收,你一定要使缓冲区无效。增加下面的一行到Form_load方法的后面。
    m_pScreenDisplay.Invalidate Nothing, True, esriScreenRecording
    一些应用,如ArcMap,可能需要多个显示缓冲区。为利用多个缓冲区,用到下面的步骤:
    1、 用IScreenDisplay::AddCache增加新的缓冲区。返回时保存缓冲区的ID。
    2、 为绘制你的缓冲区,指定缓冲区的ID开始,StartDrawing。
    3、 为使缓冲区无效,指定缓冲区的ID失效,Invalidate。
    4、 为了从缓冲区中绘制,指定缓冲区ID绘制,DrawCache。

    为了改变应用例子支持自己的缓冲区,做下面的改变:
    1)增加新变量来保持新的缓冲区
    Private m_lCacheID As Long
    2)在Form_load方法中创建缓冲区
    m_lCacheID = m_pScreenDisplay.AddCache
    3)用m_ICacheID变量和从Paint方法中移除开始和停止记录来适当的改变调用。

    移动,大小变化和旋转
    显示对象一个强大的特征能力就是在你绘制地图上放大和缩小。它用放大,缩小或平移工具很容易执行。滚动被自动处理。在你的地图上放在缩小,简单设置你的可视范围。例如,增加一个按键到表格上,放入下面的代码,这个通过固定的数来变化屏幕,在Click事件按键中。
    Private Sub Command1_Click()
      Dim pEnv As IEnvelope
      Set pEnv = m_pScreenDisplay.DisplayTransformation.VisibleBounds
      pEnv.Expand 0.75, 0.75, True
      m_pScreenDisplay.DisplayTransformation.VisibleBounds = pEnv
      m_pScreenDisplay.Invalidate Nothing, True, esriAllScreenCaches
    End Sub

    Screen Display执行TrackPan方法,这个调用主要是鼠标按下事件让用户平移视图。你可以通过设置DisplaytransFormation的 Rotation属性值来以屏幕为中心旋转实体。Rotation指定是以度表示。Screen Display执行TrackRotate方法,这个调用是鼠标按下事件让用户相互旋转视图。

    打印
    打印与屏幕绘制非常相似。当绘制到打印机时,你不用担心缓冲区或者滚 动,Simple Display被用。创建Simple Display对象和通过复制Screen Display的变化来初始化它的变化。设置打印机的变化的设备框架的打印页的像素边的值。最后,用Simple Display和打印机的句柄从草图绘制。
    输出元文件
    这个GDIDisplay对象被用来表示一个元 文件。创建元文件和打印之间有少许不同。如果你指定lpbounds变量为0到CreateEnhMetaFile,这个MyDraw程序能够被用。仅仅 用hPrinterDc来代替hMetafileDC。如果你想要指定CreateEnhMetafFile的范围,设置 DisplayTransformation的DeviceFrame相同的矩形的像素版本。
    打印结构
    一些工程可能需要直接输出到输出设备的某些下一级矩形。它通过设置Displaytransformation的设备框架像素范围少于完全设备范围很容易处理这些。
    过滤
    非 常高级的绘制效果,像颜色透明度,用显示过虑能够完成。过虑和显示缓冲区一起工作,允许你的光栅版本(rasterized version)的绘制操作。当一个过虑被指定到显示视图时(用IDisplay::putrefy_displayFilter),这个显示创建一个和 用记录缓冲区提供栅格信息一起的内部过虑缓冲区。输出是直到过虑被清除就发送到过虑缓冲区(putref_displayFilter(0))。在哪一点 上调用IDisplayFilter::Apply.Apply接收当前背景位图(记录缓冲区),绘制缓冲区(包含被指定过虑的哪些所有绘画)和目的地的 句柄。透明过虑在这些位图上执行(alphblending)和得到颜色透明度把他们绘制到目标的句柄。新的过虑能被创建执行其他的一些效果。
    例子

    画点
    [C#]
    public void OnMouseDown(int Button, int Shift, int X, int Y)
    {
      IMxDocument mxDoc = m_App.Document as IMxDocument;
      IActiveView activeView = mxDoc.FocusMap as IActiveView;
      IScreenDisplay screenDisplay = activeView.ScreenDisplay;
      screenDisplay.StartDrawing(screenDisplay.hDC, (short)  esriScreenCache.esriNoScreenCache);
      screenDisplay.SetSymbol(new SimpleMarkerSymbolClass());
      screenDisplay.DrawPoint(mxDoc.CurrentLocation);
      screenDisplay.FinishDrawing();
    }

    画线
    public void OnMouseDown(int Button, int Shift, int X, int Y)
    {
      IMxDocument mxDoc = m_App.Document as IMxDocument;
      IActiveView activeView = mxDoc.FocusMap as IActiveView;
      IScreenDisplay screenDisplay = activeView.ScreenDisplay;
      ISimpleLineSymbol lineSymbol = new SimpleLineSymbolClass();
      IRgbColor rgbColor = new RgbColorClass();
      rgbColor.Red = 255;
      lineSymbol.Color = rgbColor;
      IRubberBand rubberLine = new RubberLineClass();
      IPolyline newPolyline = (IPolyline)rubberLine.TrackNew(screenDisplay, (ISymbol)lineSymbol);
      screenDisplay.StartDrawing(screenDisplay.hDC, (short)esriScreenCache.esriNoScreenCache);
      screenDisplay.SetSymbol((ISymbol)lineSymbol);
      screenDisplay.DrawPolyline(newPolyline);
      screenDisplay.FinishDrawing();
    }

    画面
    public void OnMouseDown(int Button, int Shift, int X, int Y)
    {
      IMxDocument mxDoc = m_App.Document as IMxDocument;
      IActiveView activeView = mxDoc.FocusMap as IActiveView;
      IScreenDisplay screenDisplay = activeView.ScreenDisplay;
      ISimpleFillSymbol fillSymbol = new SimpleFillSymbolClass();
      IRgbColor rgbColor = new RgbColorClass();
      rgbColor.Red = 255;
      fillSymbol.Color = rgbColor;
      IRubberBand rubberPolygon = new RubberPolygonClass();
      IPolygon newPolygon = (IPolygon)rubberPolygon.TrackNew(screenDisplay, (ISymbol)fillSymbol);
      screenDisplay.StartDrawing(screenDisplay.hDC, (short)esriScreenCache.esriNoScreenCache);
      screenDisplay.SetSymbol((ISymbol)fillSymbol);
      screenDisplay.DrawPolygon(newPolygon);
      screenDisplay.FinishDrawing();
    }
    画矩形
    public void OnMouseDown(int Button, int Shift, int X, int Y)
    {
      IMxDocument mxDoc = m_App.Document as IMxDocument;
      IActiveView activeView = mxDoc.FocusMap as IActiveView;
      IScreenDisplay screenDisplay = activeView.ScreenDisplay;
      ISimpleFillSymbol fillSymbol = new SimpleFillSymbolClass();
      IRgbColor rgbColor = new RgbColorClass();
      rgbColor.Red = 255;
      fillSymbol.Color = rgbColor;
      IRubberBand rubberEnv = new RubberEnvelopeClass();
      IEnvelope newEnvelope = (IEnvelope)rubberEnv.TrackNew(screenDisplay, (ISymbol)fillSymbol);
      screenDisplay.StartDrawing(screenDisplay.hDC, (short)esriScreenCache.esriNoScreenCache);
      screenDisplay.SetSymbol((ISymbol)fillSymbol);
      screenDisplay.DrawRectangle(newEnvelope);
      screenDisplay.FinishDrawing();
    }

  • 相关阅读:
    [转] 你不知道的JavaScript和CSS交互的方法
    threejs学习笔记(9)
    把Mongodb配置成windows服务
    mongodb的一些基本操作
    DuiLib事件分析(一)——鼠标事件响应
    DuiLib学习bug整理——某些png不能显示
    DuiLib学习笔记5——标题栏不能正常隐藏问题
    DuiLib学习笔记4——布局
    DuiLib学习笔记3——颜色探究
    DuiLib学习笔记2——写一个简单的程序
  • 原文地址:https://www.cnblogs.com/lauer0246/p/1099265.html
Copyright © 2011-2022 走看看