using System;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;
using static WinAPI.Struct;
using System.Windows.Forms;
#pragma warning disable IDE1006 // 命名样式
namespace WinAPI
{
    /// <summary>
    /// 
    /// </summary>
    public partial class User32
    {
        #region UnmanagedMethods
        /// <summary>
        /// 模拟鼠标点击
        /// </summary>
        /// <param name="dwFlags"></param>
        /// <param name="dx"></param>
        /// <param name="dy"></param>
        /// <param name="dwData"></param>
        /// <param name="dwExtraInfo"></param>
        /// <returns></returns>
        [DllImport("user32")]
        public static extern int mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
        /// <summary>
        /// 模拟按键
        /// </summary>
        /// <param name="bVk"></param>
        /// <param name="bScan"></param>
        /// <param name="dwFlags"></param>
        /// <param name="dwExtraInfo"></param>
        [DllImport("user32.dll", EntryPoint = "keybd_event", SetLastError = true)]
        public static extern void keybd_event(Keys bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
        /// <summary>
        /// 返回hWnd参数所指定的窗口的设备环境。
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetWindowDC(IntPtr hWnd);
        /// <summary>
        /// 移动窗口
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="repaint"></param>
        /// <returns></returns>
        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int width, int height, bool repaint);
        /// <summary>
        /// 将消息信息传送给指定的窗口过程的函数。使用函数CallWindowsProc可进行窗口子分类。
        /// 通常来说，同一类的所有窗口共享一个窗口过程。子类是一个窗口或者相同类的一套窗口，
        /// 在其消息被传送到该类的窗口过程之前，这些消息是由另一个窗口过程进行解释和处理的。
        /// </summary>
        /// <param name="lpPrevWndFunc"></param>
        /// <param name="hwnd"></param>
        /// <param name="msg"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        [DllImport("User32.dll")]
        public extern static IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
        /// <summary>
        /// 用来改变指定窗口的属性．函数也将指定的一个32位值设置在窗口的额外存储空间的指定偏移位置。
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="nIndex"></param>
        /// <param name="dwNewLong"></param>
        /// <returns></returns>
        [DllImport("User32.dll")]
        public static extern IntPtr SetWindowLong(IntPtr hwnd, int nIndex, IntPtr dwNewLong);
        /// <summary>
        /// 用来改变指定窗口的属性．函数也将指定的一个32位值设置在窗口的额外存储空间的指定偏移位置。
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="nIndex"></param>
        /// <param name="dwNewLong"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern uint SetWindowLong(
            IntPtr hWnd,
            int nIndex,
            int dwNewLong);
        /// <summary>
        /// 设置弹出式窗口，层叠窗口或子窗口的父窗口
        /// </summary>
        /// <param name="hwndChild"></param>
        /// <param name="hwndParent"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern IntPtr SetParent(IntPtr hwndChild, IntPtr hwndParent);

        /// <summary>
        /// 获得一个指定子窗口的父窗口句柄
        /// </summary>
        /// <param name="hwnd">Handle to the window whose parent window handle is to be retrieved.</param>
        /// <returns>If the window is a child window, the return value is a handle to the parent window. If the window is a top-level window, the return value is a handle to the owner window. If the window is a top-level unowned window or if the function fails, the return value is NULL.</returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern IntPtr GetParent(IntPtr hwnd);
        /// <summary>
        /// 获取系统菜单的句柄
        /// </summary>
        /// <param name="hwnd">拥有窗口菜单拷贝的窗口的句柄</param>
        /// <param name="bRevert">标志位，指定将执行的操作</param>
        /// <returns></returns>
        [DllImport("USER32.DLL")]
        public static extern int GetSystemMenu(IntPtr hwnd, int bRevert);
        /// <summary>
        /// 获取系统菜单的句柄
        /// </summary>
        /// <param name="hwnd">拥有窗口菜单拷贝的窗口的句柄</param>
        /// <param name="bRevert">标志位，指定将执行的操作。
        /// 如果此参数为FALSE，GetSystemMenu返回当前使用窗口菜单的拷贝的句柄。该拷贝初始时与窗口菜单相同，但可以被修改。
        /// 如果此参数为TRUE，GetSystemMenu重置窗口菜单到缺省状态。如果存在先前的窗口菜单，将被销毁。
        /// </param>
        /// <returns>如果参数bRevert为FALSE，返回值是窗口菜单的拷贝的句柄：如果参数bRevert为TRUE，返回值是NULL。</returns>
        [DllImport("USER32.DLL")]
        public static extern int GetSystemMenu(IntPtr hwnd, bool bRevert);
        /// <summary>
        /// 从指定菜单删除一个菜单项或分离一个子菜单。
        /// 备注：只要一个菜单被修改，无论它是否在显示窗口里，应用程序都必须调用函数DrawMenuBar。
        /// </summary>
        /// <param name="hMenu">将被修改的菜单的句柄。</param>
        /// <param name="nPosition">指定将被删除的菜单项，其含义由参数wFlags决定。</param>
        /// <param name="wFlags"></param>
        /// <returns>如果函数调用成功，返回非零值；如果函数调用失败，返回值是零。若想获得更多的错误信息，请调用GetLastError函数。</returns>
        [DllImport("USER32.DLL")]
        public static extern int RemoveMenu(int hMenu, int nPosition, int wFlags);
        /// <summary>
        /// 设置前台窗口
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);
        /// <summary>
        /// 获取当前前台窗口句柄
        /// </summary>
        /// <returns></returns>
        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetForegroundWindow();
        /// <summary>
        /// 获得当前活动窗体
        /// </summary>
        /// <returns>活动窗口的句柄。如没有窗口处于活动状态或处于活动状态的窗口非当前线程创建，则返回零。</returns>
        [DllImport("user32.dll")]
        public static extern IntPtr GetActiveWindow();//获得当前活动窗体
        /// <summary>
        /// 设置活动窗体
        /// </summary>
        /// <param name="hwnd"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern IntPtr SetActiveWindow(IntPtr hwnd);//设置活动窗体
        /// <summary>
        /// 获取类名
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="lpClassName"></param>
        /// <param name="nMaxCount"></param>
        /// <returns></returns>
        [DllImport("user32", EntryPoint = "GetClassName", SetLastError = false,
            CharSet = CharSet.Auto, ExactSpelling = false,
            CallingConvention = CallingConvention.StdCall)]
        public static extern int GetClassName(int hWnd, StringBuilder lpClassName, int nMaxCount);
        /// <summary>
        /// 获取当前线程对应的进程ID
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="ID"></param>
        /// <returns></returns>
        [DllImport("User32.dll", CharSet = CharSet.Auto)]
        public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID);
        /// <summary>
        /// 判断指定句柄是否是一个窗口
        /// </summary>
        /// <param name="hWnd"></param>
        /// <returns></returns>
        [DllImport("user32.dll", EntryPoint = "IsWindow")]
        public static extern bool IsWindow(IntPtr hWnd);
        /// <summary>
        /// 获取窗口标题
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="lpString"></param>
        /// <param name="nMaxCount"></param>
        /// <returns></returns>
        [DllImport("user32", SetLastError = true)]
        public static extern int GetWindowText(
            int hWnd,//窗口句柄
            StringBuilder lpString,//标题
            int nMaxCount //最大值
            );
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="wMsg"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern int SendMessage(
            IntPtr hwnd,
            int wMsg,
            int wParam,
            int lParam);
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="wMsg"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern int SendMessage(
            IntPtr hwnd,
            int wMsg,
            IntPtr wParam,
            IntPtr lParam);
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="Msg"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        [DllImport("user32.dll", SetLastError = true)]
        public static extern bool SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="msg"></param>
        /// <param name="wParam"></param>
        /// <param name="IParam"></param>
        /// <returns></returns>
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        public static extern int SendMessage(IntPtr hwnd, int msg, int wParam, ref COPYDATASTRUCT IParam);
        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="msg"></param>
        /// <param name="wParam"></param>
        /// <param name="IParam"></param>
        [DllImport("user32.dll")]
        public static extern void PostMessage(IntPtr hWnd, int msg, int wParam, ref COPYDATASTRUCT IParam);
        /// <summary>
        /// 从文件中载入指针
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern IntPtr LoadCursorFromFile(string filename);
        /// <summary>
        /// 判断窗口是否可见
        /// </summary>
        /// <param name="hwnd"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern bool IsWindowVisible(IntPtr hwnd);
        /// <summary>
        /// 查找窗口
        /// </summary>
        /// <param name="lpClassName"></param>
        /// <param name="lpWindowName"></param>
        /// <returns></returns>
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        /// <summary>
        /// The FindWindowEx function retrieves a handle to a window whose class name and window name match the specified strings. The function searches child windows, beginning with the one following the specified child window.
        /// </summary>
        /// <param name="hwndParent">Handle to the parent window whose child windows are to be searched.</param>
        /// <param name="hwndChildAfter">Handle to a child window.</param>
        /// <param name="lpszClass">Specifies class name.</param>
        /// <param name="lpszWindow">Pointer to a null-terminated string that specifies the window name (the window's title).</param>
        /// <returns>If the function succeeds, the return value is a handle to the window that has the specified class and window names.If the function fails, the return value is NULL.</returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindowEx(
            IntPtr hwndParent,
            IntPtr hwndChildAfter,
            [MarshalAs(UnmanagedType.LPTStr)]
			string lpszClass,
            [MarshalAs(UnmanagedType.LPTStr)]
			string lpszWindow);

        /// <summary>
        /// The InvalidateRect function adds a rectangle to the specified window's update region.
        /// </summary>
        /// <param name="hwnd">Handle to window.</param>
        /// <param name="rect">Rectangle coordinates.</param>
        /// <param name="bErase">Erase state.</param>
        /// <returns>If the function succeeds, the return value is true.If the function fails, the return value is false.</returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern bool InvalidateRect(
            IntPtr hwnd,
            ref Rectangle rect,
            bool bErase);

        /// <summary>
        /// The ValidateRect function validates the client area within a rectangle by removing the rectangle from the update region of the specified window.
        /// </summary>
        /// <param name="hwnd">Handle to window.</param>
        /// <param name="rect">Validation rectangle coordinates.</param>
        /// <returns>If the function succeeds, the return value is true.If the function fails, the return value is false.</returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern bool ValidateRect(
            IntPtr hwnd,
            ref Rectangle rect);
        /// <summary>
        /// 获取指定窗口的有关信息，也可用于获取窗口内存中指定偏移的32位度整型值。
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="dwStyle"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern int GetWindowLong(
            IntPtr hWnd,
            int dwStyle);
        /// <summary>
        /// 检索一指定窗口的客户区域或整个屏幕的显示设备上下文环境的句柄，以后可以在GDI函数中使用该句柄来在设备上下文环境中绘图。
        /// </summary>
        /// <param name="hwnd"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern IntPtr GetDC(
            IntPtr hwnd);
        /// <summary>
        /// 释放设备上下文环境（DC）供其他应用程序使用。函数的效果与设备上下文环境类型有关。它只释放公用的和设备上下文环境，对于类或私有的则无效。
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="hdc"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern int ReleaseDC(
            IntPtr hwnd,
            IntPtr hdc);
        /// <summary>
        /// 获取桌面句柄
        /// </summary>
        /// <returns></returns>
        [DllImport("user32", SetLastError = false)]
        public static extern IntPtr GetDesktopWindow();
        //[DllImport("user32", CharSet = CharSet.Auto)]
        //internal static extern int GetScrollPos(
        //    IntPtr hwnd,
        //    int nBar);
        /// <summary>
        /// 获取窗口客户区的大小。注意一下：窗口的客户区为窗口中除标题栏、菜单栏之外的地方。
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="rect"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern int GetClientRect(
            IntPtr hwnd,
            out Rectangle rect);
        /// <summary>
        /// 返回指定窗口的边框矩形的尺寸。该尺寸以相对于屏幕坐标左上角的屏幕坐标给出。
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="rect"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern bool GetWindowRect(
            IntPtr hWnd,
            out Rectangle rect);
        /// <summary>
        /// 更新一个分层窗口的位置，大小，形状，内容和半透明度
        /// </summary>
        /// <param name="hwnd"></param>
        /// <param name="hdcDst"></param>
        /// <param name="pptDst"></param>
        /// <param name="psize"></param>
        /// <param name="hdcSrc"></param>
        /// <param name="pprSrc"></param>
        /// <param name="crKey"></param>
        /// <param name="pblend"></param>
        /// <param name="dwFlags"></param>
        /// <returns></returns>
        [DllImport("user32", ExactSpelling = true, SetLastError = true)]
        public static extern bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);

        /// <summary>
        /// 改变一个子窗口，弹出式窗口或顶层窗口的尺寸，位置和Z序。
        /// 子窗口，弹出式窗口，及顶层窗口根据它们在屏幕上出现的顺序排序、顶层窗口设置的级别最高，并且被设置为Z序的第一个窗口。
        /// </summary>
        /// <param name="hWnd">A handle to the window.</param>
        /// <param name="hWndAfter">A handle to the window to precede the positioned window in the Z order. This parameter must be a window handle or one of the following values.</param>       
        /// <param name="X">Specifies the new position of the left side of the window, in client coordinates.</param>
        /// <param name="Y">Specifies the new position of the top of the window, in client coordinates.</param>
        /// <param name="Width">Specifies the new width of the window, in pixels.</param>
        /// <param name="Height">Specifies the new height of the window, in pixels.</param>
        /// <param name="flags">Specifies the window sizing and positioning flags. This parameter can be a combination of the following values.</param>
        /// <returns>If the function succeeds, the return value is nonzero, if the function fails, the return value is zero.</returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern int SetWindowPos(
            IntPtr hWnd,
            IntPtr hWndAfter,
            int X,
            int Y,
            int Width,
            int Height,
            FlagsSetWindowPos flags);
        /// <summary>
        /// 改变一个子窗口，弹出式窗口或顶层窗口的尺寸，位置和Z序。
        /// 子窗口，弹出式窗口，及顶层窗口根据它们在屏幕上出现的顺序排序、顶层窗口设置的级别最高，并且被设置为Z序的第一个窗口。
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="hWndInsertAfter"></param>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="cx"></param>
        /// <param name="cy"></param>
        /// <param name="uFlags"></param>
        /// <returns></returns>
        [DllImport("user32", CharSet = CharSet.Auto)]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X,
           int Y, int cx, int cy, uint uFlags);
        /// <summary>
        /// 设置指针位置
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern bool SetCursorPos(int x, int y);
        #endregion
    }
}