免费视频|新人指南|投诉删帖|广告合作|地信网APP下载

查看: 1866|回复: 3
收起左侧

[二次开发] 获取ArcMap窗口句柄,通过WinAPI获取工作空间中点击要素的系统桌面坐标

[复制链接]

7

主题

3733

铜板

4

好友

VIP会员

Rank: 23Rank: 23Rank: 23Rank: 23Rank: 23Rank: 23Rank: 23

积分
260
发表于 2018-11-2 22:10 | 显示全部楼层 |阅读模式
本帖最后由 975601416 于 2018-11-2 22:12 编辑

这里用了个“桌面坐标”,是希望区分一下ArcGis的“屏幕坐标”(与之对应的还有一个“地理坐标”)。

什么是“屏幕坐标”呢?使用ITool接口的OnMouseDown方法获取的“x,y”值即是,其原点值在“工作空间”窗体左上角。

什么是我所称谓的“工作空间”呢?它是数据编辑区域,用Spy++查看一下其窗体的classname是“AfxFrameOrView90u”,这样看称作“工作框”或者“工作视图”什么的似乎更准确~
20181020194418907.png
前面已经提到可以通过OnMouseDown方法获取鼠标在AfxFrameOrView90u窗口相对于其左上角的坐标值(鼠标点击位置的“屏幕坐标”),而通过IActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint()可以将地理坐标转为屏幕坐标,那么获取AfxFrameOrView90u窗口左上角的系统桌面坐标加上“屏幕坐标值”就可以获取鼠标点击位置或者工作框中要素的桌面坐标。

知道桌面坐标就可以做一些窗体跟随,桌面绘图等的效果了。
一个样例demo:
ArcGis辅助自增编号功能的插件式实现

使用GetClassName通过句柄获取当前ArcMap窗口的ClassName,然后查找子窗口获得AfxFrameOrView90u就可以下一步操作了,主要代码如下:
API部分:
  1. class WinAPI
  2.     {
  3.         [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  4.         public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
  5.         [DllImport("user32.dll", EntryPoint = "FindWindow")]
  6.         public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
  7.         [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
  8.         public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
  9.         [DllImport("user32.dll")]
  10.         [return: MarshalAs(UnmanagedType.Bool)]
  11.         public static extern bool GetWindowRect(IntPtr Hwnd, ref RECT lpRect);//获取window的矩形坐标
  12.     }
  13.     [StructLayout(LayoutKind.Sequential)]
  14.     public struct RECT
  15.     {
  16.         public int Left;
  17.         public int Top;
  18.         public int Right;
  19.         public int Bottom;
  20.     }
复制代码
获得窗体:

  1. StringBuilder clsName = new StringBuilder(100); ;
  2. RECT rect = new RECT();
  3. WinAPI.GetClassName((IntPtr)m_application.hWnd, clsName, clsName.Capacity);
  4. IntPtr hwndArcMap = WinAPI.FindWindow(clsName.ToString(), null);
  5. IntPtr hwndFrame = WinAPI.FindWindowEx(hwndArcMap,IntPtr.Zero,"AfxFrameOrView90u", null);
复制代码



0

主题

1684

铜板

1

好友

高级工程师

Rank: 9Rank: 9Rank: 9

积分
643
发表于 2022-2-16 11:04 | 显示全部楼层
感谢分享
回复

使用道具 举报

37

主题

2万

铜板

111

好友

钻石会员

Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26Rank: 26

积分
5776
发表于 2022-2-22 16:19 | 显示全部楼层
谢谢分享,难度比较大
回复 支持 反对

使用道具 举报

1

主题

1万

铜板

2

好友

黄金会员

Rank: 23Rank: 23Rank: 23Rank: 23Rank: 23Rank: 23Rank: 23

积分
4853
发表于 2022-12-8 15:36 | 显示全部楼层
谢谢楼主分享
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

在线客服
快速回复 返回顶部 返回列表