1. 程式人生 > >獲取ArcMap視窗控制代碼,通過WinAPI獲取工作空間中點選要素的系統桌面座標

獲取ArcMap視窗控制代碼,通過WinAPI獲取工作空間中點選要素的系統桌面座標

這裡用了個“桌面座標”,是希望區分一下ArcGis的“螢幕座標”(與之對應的還有一個“地理座標”)。

什麼是“螢幕座標”呢?使用ITool介面的OnMouseDown方法獲取的“x,y”值即是,其原點值在“工作空間”窗體左上角。

什麼是我所稱謂的“工作空間”呢?它是資料編輯區域,用Spy++檢視一下其窗體的classname是“AfxFrameOrView90u”,這樣看稱作“工作框”或者“工作檢視”什麼的似乎更準確~

前面已經提到可以通過OnMouseDown方法獲取滑鼠在AfxFrameOrView90u視窗相對於其左上角的座標值(滑鼠點選位置的“螢幕座標”),而通過IActiveView.ScreenDisplay.DisplayTransformation.FromMapPoint()可以將地理座標轉為螢幕座標,那麼獲取AfxFrameOrView90u視窗左上角的系統桌面座標加上“螢幕座標值”就可以獲取滑鼠點選位置或者工作框中要素的桌面座標。

知道桌面座標就可以做一些窗體跟隨,桌面繪圖等額效果了。

使用GetClassName通過控制代碼獲取當前ArcMap視窗的ClassName,然後查詢子視窗獲得AfxFrameOrView90u就可以下一步操作了,主要程式碼如下:
API部分:

 class WinAPI
    {
        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); [DllImport("user32.dll", EntryPoint = "FindWindow")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("user32.dll", EntryPoint = "FindWindowEx")] public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetWindowRect(IntPtr Hwnd, ref RECT lpRect);//獲取window的矩形座標 } [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; }


獲取窗體:

 StringBuilder clsName = new StringBuilder(100); ;
 RECT rect = new RECT();
 WinAPI.GetClassName((IntPtr)m_application.hWnd, clsName, clsName.Capacity);
 IntPtr hwndArcMap = WinAPI.FindWindow(clsName.ToString(), null);
 IntPtr hwndFrame = WinAPI.FindWindowEx(hwndArcMap,IntPtr.Zero,"AfxFrameOrView90u", null);