using PTMedicalInsurance.Variables;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace PTMedicalInsurance.Common
{
    class WinApi
    {
        private bool IsWindowExist(IntPtr handle)
        {
            return (!(GetWindow(new HandleRef(this, handle), 4) != IntPtr.Zero) && IsWindowVisible(new HandleRef(this, handle)));
        }

        [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetWindow(HandleRef hWnd, int uCmd);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern bool IsWindowVisible(HandleRef hWnd);
        /// <summary>
        /// 获取应用程序窗口句柄
        /// </summary>
        /// <param name="processId"></param>
        /// <returns></returns>
        private  IntPtr GetWindowHandle(int processId)
        {
            var windowHandle = IntPtr.Zero;
            EnumThreadWindowsCallback windowsCallback = new EnumThreadWindowsCallback(FindMainWindow);
            EnumWindows(windowsCallback, IntPtr.Zero);
            //保持循环
            GC.KeepAlive(windowsCallback);

            bool FindMainWindow(IntPtr handle, IntPtr extraParameter)
            {
                int num;
                GetWindowThreadProcessId(new HandleRef(this, handle), out num);
                if (num == processId && IsWindowExist(handle))
                {
                    windowHandle = handle;
                    return true;
                }
                return false;
            }

            return windowHandle;
        }
        public delegate bool EnumThreadWindowsCallback(IntPtr hWnd, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool EnumWindows(EnumThreadWindowsCallback callback, IntPtr extraData);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int GetWindowThreadProcessId(HandleRef handle, out int processId);


        public static IntPtr GetWindowsHandle(string WindowName)
        {
            IntPtr hwnd = IntPtr.Zero;
            Process[] procs = Process.GetProcessesByName(WindowName);
            if (procs.Length != 0)
            {
                hwnd = procs[0].MainWindowHandle;
                //MessageBox.Show("??" + procs[0].Id.ToString() + "??" + procs[0].MainWindowHandle.ToString());
                //Global.writeLog("GetWindowsHandle=>ProcessID:" + procs[0].Id + ",ManagedThreadId:" + Thread.CurrentThread.ManagedThreadId.ToString());
                //Global.writeLog("GetWindowsHandle=>CurrentProcessID:" + Process.GetCurrentProcess().Id);
            }
            

            //Process ps = procs[0];
            //Global.writeLog("Start");
            //for (int i = 0; i < ps.Threads.Count; i++)
            //{
            //    var thread = ps.Threads[i];
            //    string str = string.Empty;
            //    str = str + "标识符(" + i.ToString() + "):"+ thread.Id.ToString() + System.Environment.NewLine;
            //    //str = str + "标识符：" + thread. + System.Environment.NewLine;
            //    str = str +"基本优先级：" + thread.BasePriority.ToString() + System.Environment.NewLine;
            //    str = str +"当前优先级：" + thread.CurrentPriority.ToString() + System.Environment.NewLine;
            //    str = str +"内存地址：" + thread.StartAddress.ToInt32() + System.Environment.NewLine;
            //    str = str +"启动时间：" + thread.StartTime.ToString() + System.Environment.NewLine;
            //    str = str +"使用时间：" + thread.UserProcessorTime.ToString() + System.Environment.NewLine;
            //    str = str + "当前状态：";
            //    switch (thread.ThreadState)
            //    {
            //        case System.Diagnostics.ThreadState.Initialized:
            //            str = str +"线程已经初始化但尚未启动";
            //            break;
            //        case System.Diagnostics.ThreadState.Ready:
            //            str = str +"线程准备在下一个可用的处理器上运行";
            //            break;
            //        case System.Diagnostics.ThreadState.Running:
            //            str = str +"当前正在使用处理器";
            //            break;
            //        case System.Diagnostics.ThreadState.Standby:
            //            str = str +"线程将要使用处理器";
            //            break;
            //        case System.Diagnostics.ThreadState.Terminated:
            //            str = str +"线程已完成执行并退出";
            //            break;
            //        case System.Diagnostics.ThreadState.Transition:
            //            str = str +"线程在可以执行钱等待处理器之外的资源";
            //            break;
            //        case System.Diagnostics.ThreadState.Unknown:
            //            str = str +"状态未知";
            //            break;
            //        case System.Diagnostics.ThreadState.Wait:
            //            str = str +"正在等待外围操作完成或者资源释放";
            //            break;
            //        default:
            //            break;
            //    }
            //    if (thread.ThreadState == System.Diagnostics.ThreadState.Wait)
            //    {

            //        str = str + System.Environment.NewLine +"等待原因：";
            //        switch (thread.WaitReason)
            //        {
            //            case ThreadWaitReason.EventPairHigh:
            //                str = str +"线程正在等待事件对高";
            //                break;
            //            case ThreadWaitReason.EventPairLow:
            //                str = str +"线程正在等待事件对低";
            //                break;
            //            case ThreadWaitReason.ExecutionDelay:
            //                str = str +"线程执行延迟";
            //                break;
            //            case ThreadWaitReason.Executive:
            //                str = str +"线程正在等待计划程序";
            //                break;
            //            case ThreadWaitReason.FreePage:
            //                str = str +"线程正在等待可用的虚拟内存页";
            //                break;
            //            case ThreadWaitReason.LpcReceive:
            //                str = str +"线程正在等待本地过程调用到达";
            //                break;
            //            case ThreadWaitReason.LpcReply:
            //                str = str +"线程正在等待对本地过程调用的回复到达";
            //                break;
            //            case ThreadWaitReason.PageIn:
            //                str = str +"线程正在等待虚拟内存页到达内存";
            //                break;
            //            case ThreadWaitReason.PageOut:
            //                str = str +"线程正在等待虚拟内存页写入磁盘";
            //                break;
            //            case ThreadWaitReason.Suspended:
            //                str = str +"线程执行暂停";
            //                break;
            //            case ThreadWaitReason.SystemAllocation:
            //                str = str +"线程正在等待系统分配";
            //                break;
            //            case ThreadWaitReason.Unknown:
            //                str = str +"线程因位置原因而等待";
            //                break;
            //            case ThreadWaitReason.UserRequest:
            //                str = str +"线程正在等待用户请求";
            //                break;
            //            case ThreadWaitReason.VirtualMemory:
            //                str = str +"线程正在等待系统分配虚拟内存";
            //                break;
            //            default:
            //                break;
            //        }
            //    }
            //    Global.writeLog("ThreadsInfo:" + procs[0].Id.ToString() + "_" + procs[0].ProcessName, "Count:" + ps.Threads.Count.ToString(), str);
            //}
            //Global.writeLog("End");
            
                //foreach (Process process in procs)
                //{
                //    if (process.ProcessName.Contains(WindowName))
                //    {
                //        MessageBox.Show($"Process_Name = ({process.ProcessName}), Id = {process.Id}");
                //    }
                //}


                //return GetCurrentWindowHandle((uint)procs[0].Id);

                //Process[] processes = Process.GetProcesses();
                //foreach (Process process in processes)
                //{
                //    if (process.ProcessName.Contains(WindowName))
                //    {
                //        MessageBox.Show($"ProcessName = ({process.ProcessName}), Id = {process.Id}");
                //    }
                //}

                return hwnd;

        }

        private static Hashtable processWnd = null;

        public delegate bool WNDENUMPROC(IntPtr hwnd, uint lParam);

        //static User32API()
        //{
        //    if (processWnd == null)
        //    {
        //        processWnd = new Hashtable();
        //    }
        //}

        [DllImport("user32.dll", EntryPoint = "EnumWindows", SetLastError = true)]
        public static extern bool EnumWindows(WNDENUMPROC lpEnumFunc, uint lParam);

        [DllImport("user32.dll", EntryPoint = "GetParent", SetLastError = true)]
        public static extern IntPtr GetParent(IntPtr hWnd);

        [DllImport("user32.dll", EntryPoint = "GetWindowThreadProcessId")]
        public static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref uint lpdwProcessId);

        [DllImport("user32.dll", EntryPoint = "IsWindow")]
        public static extern bool IsWindow(IntPtr hWnd);

        [DllImport("kernel32.dll", EntryPoint = "SetLastError")]
        public static extern void SetLastError(uint dwErrCode);

        public static IntPtr GetCurrentWindowHandle()
        {
            IntPtr ptrWnd = IntPtr.Zero;
            uint uiPid = (uint)Process.GetCurrentProcess().Id;  // 当前进程 ID
            object objWnd = processWnd[uiPid];

            if (objWnd != null)
            {
                ptrWnd = (IntPtr)objWnd;
                if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd))  // 从缓存中获取句柄
                {
                    return ptrWnd;
                }
                else
                {
                    ptrWnd = IntPtr.Zero;
                }
            }

            bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid);
            // 枚举窗口返回 false 并且没有错误号时表明获取成功
            if (!bResult && Marshal.GetLastWin32Error() == 0)
            {
                objWnd = processWnd[uiPid];
                if (objWnd != null)
                {
                    ptrWnd = (IntPtr)objWnd;
                }
            }

            return ptrWnd;
        }

        private static bool EnumWindowsProc(IntPtr hwnd, uint lParam)
        {
            uint uiPid = 0;

            if (GetParent(hwnd) == IntPtr.Zero)
            {
                GetWindowThreadProcessId(hwnd, ref uiPid);
                if (uiPid == lParam)    // 找到进程对应的主窗口句柄
                {
                    processWnd[uiPid] = hwnd;   // 把句柄缓存起来
                    SetLastError(0);    // 设置无错误
                    return false;   // 返回 false 以终止枚举窗口
                }
            }

            return true;
        }

        public static IntPtr GetCurrentWindowHandle(uint proid)
        {
            IntPtr ptrWnd = IntPtr.Zero;
            uint uiPid = proid;
            object objWnd = processWnd[uiPid];
            if (objWnd != null)
            {
                ptrWnd = (IntPtr)objWnd;
                if (ptrWnd != IntPtr.Zero && IsWindow(ptrWnd))  // 从缓存中获取句柄
                {
                    return ptrWnd;
                }
                else
                {
                    ptrWnd = IntPtr.Zero;
                }
            }
            bool bResult = EnumWindows(new WNDENUMPROC(EnumWindowsProc), uiPid);
            // 枚举窗口返回 false 并且没有错误号时表明获取成功
            if (!bResult && Marshal.GetLastWin32Error() == 0)
            {
                objWnd = processWnd[uiPid];
                if (objWnd != null)
                {
                    ptrWnd = (IntPtr)objWnd;
                }
            }
            return ptrWnd;
        }


    }
}
