和ArcGis辅助编号(半自动)功能的插件式实现类似的工具,用于辅助精细化作业。
该工具同样使用了Windows API以摆放提示窗口,不同的是,本工具采用了“贴膜”的方式在ArcMap地图窗口上嵌入了一层透明窗体展示提示信息,并使用hook窗体消息的方法在ArcMap窗体调整时动态对“膜”的大小进行调整。
操作Windows窗口的API类在上面的“编号”博文里有说明,本文最后只附上Hook、处理窗体消息的API类。
一、工具功能
工具启用后,先选择目标图斑,然后开始按“北->东->南->西”的顺序依次点击邻斑,拾取其QLR字段的信息(显示到ArcMap地图窗口右上角),拾取完毕,按空格键(space)将拾取的四至信息写入目标图斑的四至字段(BZ、DZ、NZ、XZ)。
如果中途拾取错误,需重新拾取,按Esc键重新开始;
如果目标图斑不存在邻斑,可以使用数字键0-9键入预设地物信息(如果不是需要的,可以后面自行批量替换):
1=>"空地",
2=>"道路",
3=>"河流",
4=>"小巷",
5 => "林地",
6 => "居民地",
7 => "园地",
8 => "湖泊",
9 => "水库",
0 => "池塘",
后面或许会把预设地物信息改为由外部文件获取。
二、Windows Hook API
使用嵌入窗体的方法在窗口上方展示四至信息,窗体的调整需要hook 窗口消息,hook API类如下:
using System; using System.Runtime.InteropServices; namespace YToolsforArcMap.Utils.WinAPI { public class HookAPI { /// <summary> /// 函数功能:该函数将一个应用程序定义的挂钩处理过程安装到挂钩链中去,您可以通过安装挂钩处理过程来对系统的某些类型事件进行监控,这些事件与某个特定的线程或系统中的所有事件相关。 /// 函数原形:HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCEhMod, DWORD dwThreadId); /// refer:https://blog.csdn.net/greston/article/details/8243115 /// refer:https://walterlv.blog.csdn.net/article/details/106335266 /// </summary> /// <param name="idHook">钩子的类型,即它处理的消息类型</param> /// <param name="lpfn">指向相应的挂钩处理过程,若参数dwThreadId为0或者指示了一个其他进程创建的线程之标识符,则参数lpfn必须指向一个动态链接中的挂钩处理过程,否则,参数lpfn可以指向一个与当前进程相关的代码中定义的挂钩处理过程。</param> /// <param name="hMod">指示了一个动态链接的句柄,该动态连接库包含了参数lpfn 所指向的挂钩处理过程。若参数dwThreadId指示的线程由当前进程创建,并且相应的挂钩处理过程定义于当前进程相关的代码中,则参数hMod必须被设置为NULL(0)。通过GetModuleHandle获得。</param> /// <param name="dwThreadId">指示了一个线程标识符,挂钩处理过程与线程相关。若此参数值为0,则该挂钩处理过程与所有现存的线程相关,通过dwThreadID = GetWindowThreadProcessId(hwnd,NULL)获得</param> /// <returns>当方法执行成功时,返回值是钩子处理函数的句柄,用于在钩子的消息处理中调用 CallNextHookEx 方法;当方法执行失败时,这里返回 0</returns> [DllImport("user32", EntryPoint = "SetWindowsHookEx",SetLastError = true)] public static extern IntPtr SetWindowsHookEx(HookType idHook, HookProc lpfn,IntPtr hMod,uint dwThreadId); /// <summary> /// 卸载钩子,参数是钩子处理函数的句柄,SetWindowsHookEx的返回值。 /// </summary> /// <param name="hookHandle"></param> /// <returns></returns> [DllImport("user32", EntryPoint = "UnhookWindowsHookEx", SetLastError = true)] public static extern bool UnhookWindowsHookEx(IntPtr hookHandle); [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")] public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("kernel32.dll")] public static extern IntPtr GetModuleHandle(string lpModuleName); [DllImport("user32.dll")] public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, LParamStruct lParam); /// <summary> /// CallNextHookEx的钩子消息处理过程 /// </summary> /// <param name="nCode"></param> /// <param name="wParam"></param> /// <param name="lParam"></param> /// <returns></returns> public delegate IntPtr HookProc(int nCode, IntPtr wParam, LParamStruct lParam); /// <summary> /// 钩子的类型 /// </summary> public enum HookType : int { WH_JOURNALRECORD = 0, WH_JOURNALPLAYBACK = 1, WH_KEYBOARD = 2, /// <summary> /// 监视消息队列的消息 /// </summary> WH_GETMESSAGE = 3, /// <summary> /// 监视窗口过程,在接收前 /// </summary> WH_CALLWNDPROC = 4, WH_CBT = 5, WH_SYSMSGFILTER = 6, WH_MOUSE = 7, WH_HARDWARE = 8, WH_DEBUG = 9, WH_SHELL = 10, WH_FOREGROUNDIDLE = 11, WH_CALLWNDPROCRET = 12, WH_KEYBOARD_LL = 13, WH_MOUSE_LL = 14 } /// <summary> /// CallNextHookEx第4个参数lParam的结构 /// </summary> [StructLayout(LayoutKind.Sequential)] public struct LParamStruct { public IntPtr lParam; public WindowMessage wParam; public int message; public IntPtr hwnd; } /// <summary> /// LParamStruct的wParam属性枚举值 /// </summary> public enum WindowMessage : int { WM_NULL = 0x0000, WM_CREATE = 0x0001, WM_DESTROY = 0x0002, WM_MOVE = 0x0003, WM_SIZE = 0x0005, WM_ACTIVATE = 0x0006, WM_SETFOCUS = 0x0007, WM_KILLFOCUS = 0x0008, WM_ENABLE = 0x000A, WM_SETREDRAW = 0x000B, WM_SETTEXT = 0x000C, WM_GETTEXT = 0x000D, WM_GETTEXTLENGTH = 0x000E, WM_PAINT = 0x000F, WM_CLOSE = 0x00010, WM_QUERYENDSESSION = 0x00011, WM_QUERYOPEN = 0x00013, WM_ENDSESSION = 0x00016, WM_QUIT = 0x00012, WM_ERASEBKGND = 0x00014, WM_SYSCOLORCHANGE = 0x00015, WM_SHOWWINDOW = 0x00018, WM_WININICHANGE = 0x0001A, WM_SETTINGCHANGE = 0x0001A, WM_DEVMODECHANGE = 0x0001B, WM_ACTIVATEAPP = 0x0001C, WM_FONTCHANGE = 0x0001D, WM_TIMECHANGE = 0x0001E, WM_CANCELMODE = 0x0001F, WM_SETCURSOR = 0x00020, WM_MOUSEACTIVATE = 0x00021, WM_CHILDACTIVATE = 0x00022, WM_QUEUESYNC = 0x00023, WM_GETMINMAXINFO = 0x00024, WM_PAINTICON = 0x00026, WM_ICONERASEBKGND = 0x00027, WM_NEXTDLGCTL = 0x00028, WM_SPOOLERSTATUS = 0x0002A, WM_DRAWITEM = 0x0002B, WM_MEASUREITEM = 0x0002C, WM_DELETEITEM = 0x0002D, WM_VKEYTOITEM = 0x0002E, WM_CHARTOITEM = 0x0002F, WM_SETFONT = 0x00030, WM_GETFONT = 0x00031, WM_SETHOTKEY = 0x00032, WM_GETHOTKEY = 0x00033, WM_QUERYDRAGICON = 0x00037, WM_COMPAREITEM = 0x00039, WM_GETOBJECT = 0x0003D, WM_COMPACTING = 0x00041, WM_COMMNOTIFY = 0x00044, WM_WINDOWPOSCHANGING = 0x00046, WM_WINDOWPOSCHANGED = 0x00047, WM_POWER = 0x00048, WM_COPYDATA = 0x0004A, WM_CANCELJOURNAL = 0x0004B, WM_NOTIFY = 0x0004E, WM_INPUTLANGCHANGEREQUEST = 0x00050, WM_INPUTLANGCHANGE = 0x00051, WM_TCARD = 0x00052, WM_HELP = 0x00053, WM_USERCHANGED = 0x00054, WM_NOTIFYFORMAT = 0x00055, WM_CONTEXTMENU = 0x0007B, WM_STYLECHANGING = 0x0007C, WM_STYLECHANGED = 0x0007D, WM_DISPLAYCHANGE = 0x0007E, WM_GETICON = 0x0007F, WM_SETICON = 0x00080, WM_NCCREATE = 0x00081, WM_NCDESTROY = 0x00082, WM_NCCALCSIZE = 0x00083, WM_NCHITTEST = 0x00084, WM_NCPAINT = 0x00085, WM_NCACTIVATE = 0x00086, WM_GETDLGCODE = 0x00087, WM_SYNCPAINT = 0x00088, WM_NCMOUSEMOVE = 0x000A0, WM_NCLBUTTONDOWN = 0x000A1, WM_NCLBUTTONUP = 0x000A2, WM_NCLBUTTONDBLCLK = 0x000A3, WM_NCRBUTTONDOWN = 0x000A4, WM_NCRBUTTONUP = 0x000A5, WM_NCRBUTTONDBLCLK = 0x000A6, WM_NCMBUTTONDOWN = 0x000A7, WM_NCMBUTTONUP = 0x000A8, WM_NCMBUTTONDBLCLK = 0x000A9, WM_NCXBUTTONDOWN = 0x000AB, WM_NCXBUTTONUP = 0x000AC, WM_NCXBUTTONDBLCLK = 0x000AD, WM_INPUT = 0x000FF, WM_KEYFIRST = 0x000100, WM_KEYDOWN = 0x000100, WM_KEYUP = 0x000101, WM_CHAR = 0x000102, WM_DEADCHAR = 0x000103, WM_SYSKEYDOWN = 0x000104, WM_SYSKEYUP = 0x000105, WM_SYSCHAR = 0x000106, WM_SYSDEADCHAR = 0x000107, WM_UNICHAR = 0x000109, WM_KEYLAST_NT501 = 0x000109, UNICODE_NOCHAR = 0x000FFFF, WM_KEYLAST_PRE501 = 0x000108, WM_IME_STARTCOMPOSITION = 0x00010D, WM_IME_ENDCOMPOSITION = 0x00010E, WM_IME_COMPOSITION = 0x00010F, WM_IME_KEYLAST = 0x00010F, WM_INITDIALOG = 0x000110, WM_COMMAND = 0x000111, WM_SYSCOMMAND = 0x000112, WM_TIMER = 0x000113, WM_HSCROLL = 0x000114, WM_VSCROLL = 0x000115, WM_INITMENU = 0x000116, WM_INITMENUPOPUP = 0x000117, WM_MENUSELECT = 0x00011F, WM_MENUCHAR = 0x000120, WM_ENTERIDLE = 0x000121, WM_MENURBUTTONUP = 0x000122, WM_MENUDRAG = 0x000123, WM_MENUGETOBJECT = 0x000124, WM_UNINITMENUPOPUP = 0x000125, WM_MENUCOMMAND = 0x000126, WM_CHANGEUISTATE = 0x000127, WM_UPDATEUISTATE = 0x000128, WM_QUERYUISTATE = 0x000129, WM_CTLCOLORMSGBOX = 0x000132, WM_CTLCOLOREDIT = 0x000133, WM_CTLCOLORLISTBOX = 0x000134, WM_CTLCOLORBTN = 0x000135, WM_CTLCOLORDLG = 0x000136, WM_CTLCOLORSCROLLBAR = 0x000137, WM_CTLCOLORSTATIC = 0x000138, WM_MOUSEFIRST = 0x000200, WM_MOUSEMOVE = 0x000200, WM_LBUTTONDOWN = 0x000201, WM_LBUTTONUP = 0x000202, WM_LBUTTONDBLCLK = 0x000203, WM_RBUTTONDOWN = 0x000204, WM_RBUTTONUP = 0x000205, WM_RBUTTONDBLCLK = 0x000206, WM_MBUTTONDOWN = 0x000207, WM_MBUTTONUP = 0x000208, WM_MBUTTONDBLCLK = 0x000209, WM_MOUSEWHEEL = 0x00020A, WM_XBUTTONDOWN = 0x00020B, WM_XBUTTONUP = 0x00020C, WM_XBUTTONDBLCLK = 0x00020D, WM_MOUSELAST_5 = 0x00020D, WM_MOUSELAST_4 = 0x00020A, WM_MOUSELAST_PRE_4 = 0x000209, WM_PARENTNOTIFY = 0x000210, WM_ENTERMENULOOP = 0x000211, WM_EXITMENULOOP = 0x000212, WM_NEXTMENU = 0x000213, WM_SIZING = 0x000214, WM_CAPTURECHANGED = 0x000215, WM_MOVING = 0x000216, WM_POWERBROADCAST = 0x000218, WM_DEVICECHANGE = 0x000219, WM_MDICREATE = 0x000220, WM_MDIDESTROY = 0x000221, WM_MDIACTIVATE = 0x000222, WM_MDIRESTORE = 0x000223, WM_MDINEXT = 0x000224, WM_MDIMAXIMIZE = 0x000225, WM_MDITILE = 0x000226, WM_MDICASCADE = 0x000227, WM_MDIICONARRANGE = 0x000228, WM_MDIGETACTIVE = 0x000229, WM_MDISETMENU = 0x000230, WM_ENTERSIZEMOVE = 0x000231, WM_EXITSIZEMOVE = 0x000232, WM_DROPFILES = 0x000233, WM_MDIREFRESHMENU = 0x000234, WM_IME_SETCONTEXT = 0x000281, WM_IME_NOTIFY = 0x000282, WM_IME_CONTROL = 0x000283, WM_IME_COMPOSITIONFULL = 0x000284, WM_IME_SELECT = 0x000285, WM_IME_CHAR = 0x000286, WM_IME_REQUEST = 0x000288, WM_IME_KEYDOWN = 0x000290, WM_IME_KEYUP = 0x000291, WM_MOUSEHOVER = 0x0002A1, WM_MOUSELEAVE = 0x0002A3, WM_NCMOUSEHOVER = 0x0002A0, WM_NCMOUSELEAVE = 0x0002A2, WM_WTSSESSION_CHANGE = 0x0002B1, WM_TABLET_FIRST = 0x0002C0, WM_TABLET_LAST = 0x0002DF, WM_CUT = 0x000300, WM_COPY = 0x000301, WM_PASTE = 0x000302, WM_CLEAR = 0x000303, WM_UNDO = 0x000304, WM_RENDERFORMAT = 0x000305, WM_RENDERALLFORMATS = 0x000306, WM_DESTROYCLIPBOARD = 0x000307, WM_DRAWCLIPBOARD = 0x000308, WM_PAINTCLIPBOARD = 0x000309, WM_VSCROLLCLIPBOARD = 0x00030A, WM_SIZECLIPBOARD = 0x00030B, WM_ASKCBFORMATNAME = 0x00030C, WM_CHANGECBCHAIN = 0x00030D, WM_HSCROLLCLIPBOARD = 0x00030E, WM_QUERYNEWPALETTE = 0x00030F, WM_PALETTEISCHANGING = 0x000310, WM_PALETTECHANGED = 0x000311, WM_HOTKEY = 0x000312, WM_PRINT = 0x000317, WM_PRINTCLIENT = 0x000318, WM_APPCOMMAND = 0x000319, WM_THEMECHANGED = 0x00031A, WM_HANDHELDFIRST = 0x000358, WM_HANDHELDLAST = 0x00035F, WM_AFXFIRST = 0x000360, WM_AFXLAST = 0x00037F, WM_PENWINFIRST = 0x000380, WM_PENWINLAST = 0x00038F, WM_APP = 0x0008000, WM_USER = 0x000400 } } }