Engine地図移動動作を何とかしたい


一回白抜きになったりと良く分からない制御が入るArcGIS EngineやArcMapの地図移動の挙動
フル制御する場合の検討コード
FillRectでチラつくかなぁ…うーむ

using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.ADF.BaseClasses;
using ESRI.ArcGIS.ADF.CATIDs;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Display;
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using geom = ESRI.ArcGIS.Geometry;

本体

enum TernaryRasterOperations : uint
{
  /// <summary>dest = source</summary>
  SRCCOPY = 0x00CC0020,
  /// <summary>dest = source OR dest</summary>
  SRCPAINT = 0x00EE0086,
  /// <summary>dest = source AND dest</summary>
  SRCAND = 0x008800C6,
  /// <summary>dest = source XOR dest</summary>
  SRCINVERT = 0x00660046,
  /// <summary>dest = source AND (NOT dest)</summary>
  SRCERASE = 0x00440328,
  /// <summary>dest = (NOT source)</summary>
  NOTSRCCOPY = 0x00330008,
  /// <summary>dest = (NOT src) AND (NOT dest)</summary>
  NOTSRCERASE = 0x001100A6,
  /// <summary>dest = (source AND pattern)</summary>
  MERGECOPY = 0x00C000CA,
  /// <summary>dest = (NOT source) OR dest</summary>
  MERGEPAINT = 0x00BB0226,
  /// <summary>dest = pattern</summary>
  PATCOPY = 0x00F00021,
  /// <summary>dest = DPSnoo</summary>
  PATPAINT = 0x00FB0A09,
  /// <summary>dest = pattern XOR dest</summary>
  PATINVERT = 0x005A0049,
  /// <summary>dest = (NOT dest)</summary>
  DSTINVERT = 0x00550009,
  /// <summary>dest = BLACK</summary>
  BLACKNESS = 0x00000042,
  /// <summary>dest = WHITE</summary>
  WHITENESS = 0x00FF0062,
  /// <summary>
  /// Capture window as seen on screen.  This includes layered windows 
  /// such as WPF windows with AllowsTransparency="true"
  /// </summary>
  CAPTUREBLT = 0x40000000
}

[DllImport("gdi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

private Bitmap m_Img = null;
private Point m_MouseDownPt = new Point();

public override void OnMouseDown(int button, int shift, int x, int y)
{
  if (this.m_hookHelper == null)
    return;

  this.m_MouseDownPt.X = x;
  this.m_MouseDownPt.Y = y;

  IScreenDisplay scDisplay = this.m_hookHelper.ActiveView.ScreenDisplay;
  var rect = scDisplay.DisplayTransformation.get_DeviceFrame();

  Bitmap bmp = new Bitmap(rect.right, rect.bottom);

  scDisplay.StartDrawing(scDisplay.hDC, (short)esriScreenCache.esriNoScreenCache);
  try
  {
    using (Graphics imgGraphics = Graphics.FromImage(bmp))
    {
      IntPtr screenGraphics = new IntPtr(scDisplay.hDC);
      IntPtr imgGr = imgGraphics.GetHdc();

      BitBlt(imgGr, 0, 0, bmp.Width, bmp.Height, screenGraphics, 0, 0, TernaryRasterOperations.SRCCOPY);

      imgGraphics.ReleaseHdc(imgGr);
    }

  }
  finally
  {
    scDisplay.FinishDrawing();
  }
  this.m_Img = bmp;

  //確認用
  //bmp.Save(@"c:\test.png", ImageFormat.Png);
}

public override void OnMouseMove(int button, int shift, int x, int y)
{
  if (this.m_Img == null || this.m_hookHelper == null)
    return;
  IScreenDisplay scDisplay = this.m_hookHelper.ActiveView.ScreenDisplay;
  var rect = scDisplay.DisplayTransformation.get_DeviceFrame();

  Bitmap bmp = new Bitmap(rect.right, rect.bottom);

  scDisplay.StartDrawing(scDisplay.hDC, (short)esriScreenCache.esriNoScreenCache);
  IntPtr screenGraphics = new IntPtr(scDisplay.hDC);

  using (Graphics screen = Graphics.FromHdc(screenGraphics))
  using (SolidBrush solid = new SolidBrush(Color.White))
  {
    screen.FillRectangle(solid, new Rectangle(rect.left, rect.top, rect.right, rect.bottom));
    Point imgPt = new Point();
    imgPt.X = x - this.m_MouseDownPt.X;
    imgPt.Y = y - this.m_MouseDownPt.Y;

    screen.DrawImageUnscaled(this.m_Img, imgPt);
  }
  scDisplay.FinishDrawing();
}

public override void OnMouseUp(int button, int shift, int x, int y)
{
  if (this.m_Img == null || this.m_hookHelper == null)
    return;

  IActiveView actView = this.m_hookHelper.ActiveView;
  IScreenDisplay scDisplay = actView.ScreenDisplay;
  var displayTransformation = scDisplay.DisplayTransformation;
  var rect = scDisplay.DisplayTransformation.get_DeviceFrame();

  //Point imgPt = new Point();
  //imgPt.X = this.m_MouseDownPt.X - y;
  //imgPt.Y = this.m_MouseDownPt.Y - x;

  using (ComReleaser com = new ComReleaser())
  {
    geom.IPoint downPt = displayTransformation.ToMapPoint(this.m_MouseDownPt.X, this.m_MouseDownPt.Y);
    com.ManageLifetime(downPt);

    geom.IPoint upPt = displayTransformation.ToMapPoint(x, y);
    com.ManageLifetime(upPt);

    geom.ILine line = new geom.LineClass();
    com.ManageLifetime(line);
    line.PutCoords(upPt, downPt);

    var env = actView.Extent;
    ((geom.ITransform2D)env).MoveVector(line);
    actView.Extent = env;

    using (Bitmap img = new Bitmap(this.m_Img.Width, this.m_Img.Height))
    {
      scDisplay.StartDrawing(scDisplay.hDC, (short)esriScreenCache.esriNoScreenCache);

      using (Graphics g = Graphics.FromImage(img))
      {
        IntPtr ptr = g.GetHdc();
        actView.Output(ptr.ToInt32(), 96, ref rect, env, null);

        g.ReleaseHdc(ptr);
      }

      IntPtr screenGraphics = new IntPtr(scDisplay.hDC);

      using (Graphics screen = Graphics.FromHdc(screenGraphics))
      using (SolidBrush solid = new SolidBrush(Color.White))
      {
        screen.FillRectangle(solid, new Rectangle(rect.left, rect.top, rect.right, rect.bottom));
        screen.DrawImageUnscaled(img, new Point(0, 0));
      }
    }//end img
    scDisplay.FinishDrawing();

  }

  this.m_Img.Dispose();
  this.m_Img = null;
}
カテゴリー: 開発 タグ: パーマリンク