ArcGIS宗地四至辅助录入功能的插件式实现与Windows Hook API的声明

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
        }
    }
}
原文地址:https://www.cnblogs.com/yzhyingcool/p/14619602.html