C#获取当前活动窗口句柄

1.项目结构

图片说明

1).创建视窗项目

2).创建捕获窗口 控制台项目

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Drawing;

namespace AutoSetTextBoxContent
{
    class Program
    {
        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        //窗口的类型或者窗口的标题,只需要传一个
        private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);//查找窗口内控件句柄

        [DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern int SendMessage(IntPtr hwnd, uint wMsg, IntPtr wParam, string lParam);//发送消息
        [DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
        private static extern void SetForegroundWindow(IntPtr hwnd);// 设置窗口为激活状态
        [DllImport("user32.dll", EntryPoint = "WindowFromPoint")]//指定坐标处窗体句柄
        public static extern IntPtr WindowFromPoint(Point point);
        [DllImport("user32.dll", EntryPoint = "ChildWindowFromPointEx")]//指定坐标处窗体句柄
        private static extern IntPtr ChildWindowFromPointEx(IntPtr hwnd, Point pt, uint flags);

        //SendMessage参数
        private const int WM_KEYDOWN = 0X100;
        private const int WM_KEYUP = 0X101;
        private const int WM_SYSCHAR = 0X106;
        private const int WM_SYSKEYUP = 0X105;
        private const int WM_SYSKEYDOWN = 0X104;
        private const int WM_CHAR = 0X102;

        const uint WM_SETTEXT = 0x000C;//设置文本框内容的消息
        static void Main(string[] args)
        {
            //IntPtr myPtr = GetForegroundWindow();
            IntPtr ParenthWnd = new IntPtr(0);

            ParenthWnd = FindWindow(null, "Form1");
            //判断这个窗体是否有效 
            if (ParenthWnd != IntPtr.Zero)
            {
                //var t = findallchild(ParenthWnd);
                //MessageBox.Show("找到窗口");

                //获取输入框的控件句柄,Spy++进行查询。比如C语言编写的程序中,文本框的句柄类型一般为“EDIT”,C#写的程序则不是。
                //IntPtr hwndQ = FindWindowEx(ParenthWnd, IntPtr.Zero, null, null);
                //IntPtr hwndP = FindWindowEx(ParenthWnd, hwndQ, null, null);  //获取密码输入框的控件句柄
                //1.因为winform窗体上有很多控件,无法唯一标识,用spy++查看contol id发现不是唯一的,每次重启都会变化。所以就无法区分哪个edit控件对应哪个字段,
                //2.现在发现用EnumChildsWindow来遍历控件发现取得的控件不是按Tab的顺序来的,所以这种方式也无法区分每个edit。
                // 解决思路:根据控件的位置获取控件的句柄
                Point pointQ = new Point { X = 292, Y = 134 };
                Point pointP = new Point { X = 292, Y = 217 };
                IntPtr hwndQ = ChildWindowFromPointEx(ParenthWnd, pointQ, 0x0000);
                IntPtr hwndP = ChildWindowFromPointEx(ParenthWnd, pointP, 0x0000);
                //将窗口设置为激活
                SetForegroundWindow(ParenthWnd);
                //System.Threading.Thread.Sleep(1000);   //暂停1秒让你看到效果
                SendMessage(hwndQ, WM_SETTEXT, IntPtr.Zero, "123");//发送文本框1里面的内容
                //System.Threading.Thread.Sleep(1000);   //暂停1秒让你看到效果
                SendMessage(hwndP, WM_SETTEXT, IntPtr.Zero, "456");//发送文本框2里面的内容
            }
            else
            { 
                Console.WriteLine("没有找到窗口");
            }
            Console.ReadKey(); 
        }

        //查找一级子控件句柄
        public static List<IntPtr> findchild(IntPtr parent)
        {
            List<IntPtr> allchild = new List<IntPtr>();
            IntPtr hwnd = FindWindowEx(parent, IntPtr.Zero, null, null);
            while (hwnd != IntPtr.Zero)
            {
                allchild.Add(hwnd);
                hwnd = FindWindowEx(parent, hwnd, null, null);
            }
            return allchild;
        }

        //查找所有子控件-广度遍历
        public static List<IntPtr> findallchild(IntPtr parent)
        {
            List<IntPtr> allchild = new List<IntPtr>();
            allchild.Add(parent);   //第一个添加父句柄,最后再删除
            for (int i = 0; i < allchild.Count; i++)
            {
                IntPtr patenttemp = allchild[i];
                IntPtr hwnd = FindWindowEx(patenttemp, IntPtr.Zero, null, null);
                while (hwnd != IntPtr.Zero)
                {
                    allchild.Add(hwnd);
                    hwnd = FindWindowEx(patenttemp, hwnd, null, null);
                }
            }
            allchild.RemoveAt(0);
            return allchild;
        }
    }
}

2.运行结果

1)运行视窗项目

图片说明

2)运行获取窗口控制台程序

捕获窗口并填充textbox
图片说明

项目github地址

全部评论

相关推荐

程序员小白条:一般不用左右的模块,自我评价没啥用,这个简历纯前端,然后全是CRUD,说实话我这个后端全能做
点赞 评论 收藏
分享
xdm&nbsp;早上喝奶茶差点喷出来。事情是这样的,我们班有个哥们儿,简称&nbsp;L,去年秋招拿了字节sp,专业方向是后端。我们当时都震惊:这哥们儿平时课上从来不发言,期末小组作业基本是划水的那种,刷题平台&nbsp;commit记录我点进去看过,绿格子稀稀拉拉。但他面试一路绿灯。一面二面三面&nbsp;hr&nbsp;面,全过,给的还是sp。当时班级群里恭喜他的、问他经验的、约饭的,热闹了一周。他说自己"运气好,准备充分"。我们都信了,直到三月初他入职。入职第二周开始,班里另一个进字节的同学W(在隔壁组的)开始跟我他的不对劲。一开始是写代码慢,后来写不出来,再后来是组里&nbsp;mentor&nbsp;让他fix&nbsp;一个简单&nbsp;bug&nbsp;都搞了一下午没动静。最离谱的是上周。W&nbsp;说他们大部门搞了个新人分享会,让新人讲一下自己负责模块的设计思路。L&nbsp;上去讲了&nbsp;20分钟,全程念稿子,问答环节别人随便问一个"那你这里为什么用&nbsp;Redis&nbsp;不用&nbsp;Memcached",他直接卡&nbsp;30秒说"这个我回去再确认一下"。会后他&nbsp;mentor&nbsp;直接找&nbsp;leader&nbsp;谈,leader&nbsp;找&nbsp;hr&nbsp;谈,hr调出了他面试录像,全程对比口型和回答节奏,发现他二三面有大量时长在偷偷看屏幕外(推测开了双机位&nbsp;AI&nbsp;答题)。(这段是&nbsp;W后来转述给我的,他自己也是听他组里同事八卦来的)昨天下班前,W&nbsp;告诉我L&nbsp;被辞退了,让他自己走,不走就走仲裁但会发函到学校。L&nbsp;现在已经回学校了,朋友圈仅三天可见。我说真的,我不是个心眼小的人,但是我看到这个消息的时候真的有种"嗯,挺好"的感觉。去年秋招我投字节后端,简历挂。我准备了八个月,背&nbsp;八股&nbsp;+&nbsp;刷&nbsp;500&nbsp;题&nbsp;+项目改了三版,连面试机会都没拿到。班里这哥们儿凭着一个外挂上岸,最后还是被甩出来了。不是说作弊就一定会被发现,但是当面试拿到的&nbsp;offer远远超出真实能力的时候,迟早会有这一天。试用期三个月不是给你过家家的,是真的要写代码、要在会议上回答问题、要扛需求的。我现在反而有点同情他。同情他相信"上岸就是终点"。发出来不是为了嘲笑谁,就是想说给那些正在被身边作弊上岸的同学搞得很&nbsp;emo&nbsp;的&nbsp;uu&nbsp;们听——别急,回旋镖很长,但它一定会回来。你继续刷你的题,写你的项目,背你的八股。该是你的迟早是你的,不是你的早晚还得还回去。xdm&nbsp;共勉。
牛客12588360...:我不想评论面试方式,作弊是绝对不对的,但是你八股加刷题也不过是个做题小子,他穿帮纯粹是他菜,你也没有高明到哪里去
点赞 评论 收藏
分享
评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务