前言:本店绝不含地沟油

顾客:“老板,你这油怎么这么亮呀,跟我平常吃的不一样,不会是地沟油吧?”

回答:“你平常吃的是地沟油!”

继续缅怀逝去的程序员生涯

倒腾WinForm, 是这样的俺想做个方便的类来控制其他程序的窗口,具体就是操作句柄。

这里以改变窗口的输入框(Text)举例,其他自己搞吧,就是调用WinAPI。

实现过程:

过程一:找到当前鼠标位置的句柄

您的使用2个WinAPI(俺喜欢自己封装下来用):

View Code

        [DllImport("user32.dll", EntryPoint = "GetCursorPos")]public static extern bool GetCursorPos(out Point pt);

        [DllImport("user32.dll", EntryPoint = "WindowFromPoint")]public static extern IntPtr WindowFromPoint(Point pt);

//鼠标位置的坐标        public static Point GetCursorPosPoint()        {            Point p = new Point();if (GetCursorPos(out p))            {return p;            }return default(Point);        }

/// <summary>/// 找到句柄/// </summary>/// <param name="p">坐标</param>/// <returns></returns>        public static IntPtr GetHandle(Point p)        {return WindowFromPoint(p);        }

过程二:改变窗口的Text

您的使用1个WinAPI:

View Code

        [DllImport("user32.dll", EntryPoint = "SendMessage")]private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

/// <summary>/// 给窗口发送内容/// </summary>/// <param name="hWnd">句柄</param>/// <param name="lParam">要发送的内容</param>        public static void SetText(IntPtr hWnd, string lParam)        {            SendMessage(hWnd, WM_SETTEXT, IntPtr.Zero, lParam);        }private const int WM_SETTEXT = 0x000C;

通过这个方法就能改变Text的值了。

思考:如果俺把这个窗口的句柄记录下来,下次不用鼠标获取,直接就能改变值不蛮好的嘛。

例如:我有个桌面系统老叫我输入用户名,密码。我记录用户名和密码的窗口句柄,然后改变他们的输入值,这样多省事。(只是举例,不考虑安全性)

问题:你会告诉我,窗口句柄的每次重建会变的呀,咋办。

回答:类名不变呀。

过程三:您的准备一些工具吧,例如:句柄找类名呀,类名找句柄什么的等等,下面会用到一些WinAPI

View Code

        [DllImport("user32.dll", EntryPoint = "FindWindow")]private static extern IntPtr FindWindow(string IpClassName, string IpWindowName);

        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

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

        [DllImport("user32.dll", CharSet = CharSet.Auto)]public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

/// <summary>/// 找到句柄/// </summary>/// <param name="IpClassName">类名</param>/// <returns></returns>        public static IntPtr GetHandle(string IpClassName)        {return FindWindow(IpClassName, null);        }

/// <summary>/// 子窗口句柄/// </summary>/// <param name="hwndParent">父窗口句柄</param>/// <param name="hwndChildAfter">前一个同目录级同名窗口句柄</param>/// <param name="lpszClass">类名</param>/// <returns></returns>        public static IntPtr GetChildHandle(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass)        {return FindWindowEx(hwndParent, hwndChildAfter, lpszClass, null);        }

/// <summary>/// 全部子窗口句柄/// </summary>/// <param name="hwndParent">父窗口句柄</param>/// <param name="className">类名</param>/// <returns></returns>        public static List<IntPtr> GetChildHandles(IntPtr hwndParent, string className)        {            List<IntPtr> resultList = new List<IntPtr>();for (IntPtr hwndClient = GetChildHandle(hwndParent, IntPtr.Zero, className); hwndClient != IntPtr.Zero; hwndClient = GetChildHandle(hwndParent, hwndClient, className))            {                resultList.Add(hwndClient);            }

return resultList;        }

/// <summary>/// 找类名/// </summary>/// <param name="hWnd">句柄</param>/// <returns></returns>        public static string GetClassName(IntPtr hWnd)        {            StringBuilder lpClassName = new StringBuilder(128);if (GetClassName(hWnd, lpClassName, lpClassName.Capacity) == 0)            {throw new Exception("not found IntPtr!");            }return lpClassName.ToString();        }

思考:遍历桌面上所有的窗口,然后找类名,然后改他的Text,扯淡嘛,相同的类名太多了,找毛呀

实现:不仅记录类名,而且记录类名在父窗口出现的位置,然后通过桌面一层层找下来,最后找到这个句柄。(虽然不是太准,但是一般的还是能解决了,如果你有什么好方式一起研究)。

过程四:实现一个WinHWND的类,可以把他的规则,他的父窗口类名,以及在父窗口中同类名出现的顺序记录下来,然后通过这些记录的信息还原句柄。

View Code

    public class WinHWND    {public IntPtr HWND { get; set; }public string ClassName { get; set; }public WinHWND Parent { get; set; }public int InParentSequence { get; set; }

private WinHWND() { }

public WinHWND(IntPtr hWnd)        {this.HWND = hWnd;this.ClassName = GetClassName();this.Parent = GetParent();this.InParentSequence = GetInParentSequence();        }

private string GetClassName()        {return WinAPI.GetClassName(this.HWND);        }private WinHWND GetParent()        {if (WinAPI.GetParent(this.HWND) == null)            {throw new Exception("not found IntPtr!");            }

if (WinAPI.GetParent(this.HWND) == IntPtr.Zero)            {return null;            }

return new WinHWND(WinAPI.GetParent(this.HWND));        }private int GetInParentSequence()        {            IntPtr IntprtParent = this.Parent == null ? IntPtr.Zero : this.Parent.HWND;return WinAPI.GetChildHandles(IntprtParent, this.ClassName).IndexOf(this.HWND);        }

public override string ToString()        {            StringBuilder result = new StringBuilder();for (WinHWND winHandle = this; winHandle != null; winHandle = winHandle.Parent)            {                result.Append(string.Format("{0}:{1};", Escape(winHandle.ClassName), winHandle.InParentSequence.ToString()));if (winHandle.InParentSequence == -1) break;            }return result.ToString().TrimEnd(';');        }

private static string GetBaseMark(string sMark)        {string[] sMarks = sMark.Split(';');return sMarks[sMarks.Length - 1].Split(':')[0];        }

private static string[] GetChildMarks(string sMark)        {string[] sMarks = sMark.Split(';');string[] sChildMarks = new string[sMarks.Length - 1];for (int i = 0; i < sChildMarks.Length; i ++ )            {                sChildMarks[i] = sMarks[i ];            }return sChildMarks;        }

//我一直觉得这段写很丑陋,谁能帮帮我改改        public static WinHWND GetWinHWND(string sMark)        {            List<IntPtr> baseHwnds = WinAPI.GetChildHandles(IntPtr.Zero, GetBaseMark(sMark));string[] sChildMarks = GetChildMarks(sMark);//由于主窗口在桌面出现所以很可能同名,所以要看看他的儿子和孙子...是不是都匹配            foreach (IntPtr baseHwnd in baseHwnds)            {                IntPtr handle = baseHwnd;for (int i = sChildMarks.Length - 1; i >= 0; i--)                {string[] sChildMark = sChildMarks[i].Split(':');try                    {                        handle = WinAPI.GetChildHandles(handle, UnEscape(sChildMark[0]))[int.Parse(sChildMark[1])];                    }catch                    {break;                    }

if (i == 0) return new WinHWND(handle);                }continue;            }

return null;        }

#region 转义private static string Escape(string arg)        {return arg.Replace(":", "\\:").Replace(";","\\;");        }

private static string UnEscape(string arg)        {return arg.Replace("\\:", ":").Replace("\\;", ";");        }#endregion

public static WinHWND GetWinHWND()        {return new WinHWND(WinAPI.GetHandle(WinAPI.GetCursorPosPoint()));        }    }

上全部代码,里面加了窗口的部分属性,扩展其他的属性,自己发挥吧,就是搞WinAPI

View Code

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Runtime.InteropServices;using System.Drawing;using System.Collections;

namespace InformationCollectionDataFill{public class WinAPI    {#region WinodwsAPI        [DllImport("user32.dll", EntryPoint = "FindWindow")]private static extern IntPtr FindWindow(string IpClassName, string IpWindowName);

        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        [DllImport("user32.dll", EntryPoint = "SendMessage")]private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);

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

        [DllImport("user32.dll", EntryPoint = "GetCursorPos")]public static extern bool GetCursorPos(out Point pt);

        [DllImport("user32.dll", EntryPoint = "WindowFromPoint", CharSet = CharSet.Auto, ExactSpelling = true)]public static extern IntPtr WindowFromPoint(Point pt);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]public static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]public static extern int GetWindowRect(IntPtr hwnd, ref Rectangle rc);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]public static extern int GetClientRect(IntPtr hwnd, ref Rectangle rc);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]public static extern int MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, bool bRepaint);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]public static extern int ScreenToClient(IntPtr hWnd, ref Rectangle rect);#endregion

#region 封装API方法/// <summary>/// 找到句柄/// </summary>/// <param name="IpClassName">类名</param>/// <returns></returns>        public static IntPtr GetHandle(string IpClassName)        {return FindWindow(IpClassName, null);        }

/// <summary>/// 找到句柄/// </summary>/// <param name="p">坐标</param>/// <returns></returns>        public static IntPtr GetHandle(Point p)        {return WindowFromPoint(p);        }

//鼠标位置的坐标        public static Point GetCursorPosPoint()        {            Point p = new Point();if (GetCursorPos(out p))            {return p;            }return default(Point);        }

/// <summary>/// 子窗口句柄/// </summary>/// <param name="hwndParent">父窗口句柄</param>/// <param name="hwndChildAfter">前一个同目录级同名窗口句柄</param>/// <param name="lpszClass">类名</param>/// <returns></returns>        public static IntPtr GetChildHandle(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass)        {return FindWindowEx(hwndParent, hwndChildAfter, lpszClass, null);        }

/// <summary>/// 全部子窗口句柄/// </summary>/// <param name="hwndParent">父窗口句柄</param>/// <param name="className">类名</param>/// <returns></returns>        public static List<IntPtr> GetChildHandles(IntPtr hwndParent, string className)        {            List<IntPtr> resultList = new List<IntPtr>();for (IntPtr hwndClient = GetChildHandle(hwndParent, IntPtr.Zero, className); hwndClient != IntPtr.Zero; hwndClient = GetChildHandle(hwndParent, hwndClient, className))            {                resultList.Add(hwndClient);            }

return resultList;        }

/// <summary>/// 给窗口发送内容/// </summary>/// <param name="hWnd">句柄</param>/// <param name="lParam">要发送的内容</param>        public static void SetText(IntPtr hWnd, string lParam)        {            SendMessage(hWnd, WM_SETTEXT, IntPtr.Zero, lParam);        }private const int WM_SETTEXT = 0x000C;

/// <summary>/// 获得窗口内容或标题/// </summary>/// <param name="hWnd">句柄</param>/// <returns></returns>        public static string GetText(IntPtr hWnd)        {            StringBuilder result = new StringBuilder(128);            GetWindowText(hWnd, result, result.Capacity);return result.ToString();        }

/// <summary>/// 找类名/// </summary>/// <param name="hWnd">句柄</param>/// <returns></returns>        public static string GetClassName(IntPtr hWnd)        {            StringBuilder lpClassName = new StringBuilder(128);if (GetClassName(hWnd, lpClassName, lpClassName.Capacity) == 0)            {throw new Exception("not found IntPtr!");            }return lpClassName.ToString();        }

/// <summary>/// 窗口在屏幕位置/// </summary>/// <param name="hWnd">句柄</param>/// <returns></returns>        public static Rectangle GetWindowRect(IntPtr hWnd)        {            Rectangle result = default(Rectangle);            GetWindowRect(hWnd, ref result);return result;        }

/// <summary>/// 窗口相对屏幕位置转换成父窗口位置/// </summary>/// <param name="hWnd"></param>/// <param name="rect"></param>/// <returns></returns>        public static Rectangle ScreenToClient(IntPtr hWnd, Rectangle rect)        {            Rectangle result = rect;            ScreenToClient(hWnd, ref result);return result;        }

/// <summary>/// 窗口大小/// </summary>/// <param name="hWnd"></param>/// <returns></returns>        public static Rectangle GetClientRect(IntPtr hWnd)        {            Rectangle result = default(Rectangle);            GetClientRect(hWnd, ref result);return result;        }#endregion    }

public class WinHWND    {public IntPtr HWND { get; set; }public string ClassName { get; set; }public WinHWND Parent { get; set; }public int InParentSequence { get; set; }

private Rectangle _currentRect;private string _Text;private int _Left;private int _Top;private int _Width;private int _Height;

public string Text        {get            {return _Text == default(string) ? WinAPI.GetText(this.HWND) : _Text;            }set            {                _Text = value;                WinAPI.SetText(this.HWND, value);            }        }public int Left        {get            {return _Left == default(int) ? _currentRect.Left : _Left;            }set            {                _Left = value;                WinAPI.MoveWindow(this.HWND, value, this.Top, this.Width, this.Height, true);            }        }public int Top        {get            {return _Top == default(int) ? _currentRect.Top : _Top;            }set            {                _Top = value;                WinAPI.MoveWindow(this.HWND, this.Left, value, this.Width, this.Height, true);            }        }public int Width        {get            {return _Width == default(int) ? _currentRect.Width : _Width;            }set            {                _Width = value;                WinAPI.MoveWindow(this.HWND, this.Left, this.Top, value, this.Height, true);            }        }public int Height        {get            {return _Height == default(int) ? _currentRect.Height : _Height;            }set            {                _Height = value;                WinAPI.MoveWindow(this.HWND, this.Left, this.Top, this.Width, value, true);            }        }

private WinHWND() { }public WinHWND(IntPtr hWnd)        {this.HWND = hWnd;this.ClassName = GetClassName();this.Parent = GetParent();this.InParentSequence = GetInParentSequence();this._currentRect = GetRect();        }

private string GetClassName()        {return WinAPI.GetClassName(this.HWND);        }private WinHWND GetParent()        {if (WinAPI.GetParent(this.HWND) == null)            {throw new Exception("not found IntPtr!");            }

if (WinAPI.GetParent(this.HWND) == IntPtr.Zero)            {return null;            }

return new WinHWND(WinAPI.GetParent(this.HWND));        }private int GetInParentSequence()        {            IntPtr IntprtParent = this.Parent == null ? IntPtr.Zero : this.Parent.HWND;return WinAPI.GetChildHandles(IntprtParent, this.ClassName).IndexOf(this.HWND);        }private Rectangle GetRect()        {if (this.Parent == null) return default(Rectangle);            Rectangle clientSize = WinAPI.GetClientRect(this.HWND);            Rectangle clientPoint = WinAPI.ScreenToClient(this.Parent.HWND, WinAPI.GetWindowRect(this.HWND));return new Rectangle(clientPoint.X, clientPoint.Y, clientSize.Width, clientSize.Height);        }

public static WinHWND GetWinHWND()        {return new WinHWND(WinAPI.GetHandle(WinAPI.GetCursorPosPoint()));        }

public override string ToString()        {            StringBuilder result = new StringBuilder();for (WinHWND winHandle = this; winHandle != null; winHandle = winHandle.Parent)            {                result.Append(string.Format("{0}:{1};", Escape(winHandle.ClassName), winHandle.InParentSequence.ToString()));if (winHandle.InParentSequence == -1) break;            }return result.ToString().TrimEnd(';');        }

private static string GetBaseMark(string sMark)        {string[] sMarks = sMark.Split(';');return sMarks[sMarks.Length - 1].Split(':')[0];        }

private static string[] GetChildMarks(string sMark)        {string[] sMarks = sMark.Split(';');string[] sChildMarks = new string[sMarks.Length - 1];for (int i = 0; i < sChildMarks.Length; i ++ )            {                sChildMarks[i] = sMarks[i];            }return sChildMarks;        }

//我一直觉得这段写很丑陋,谁能帮帮我改改        public static WinHWND GetWinHWND(string sMark)        {            List<IntPtr> baseHwnds = WinAPI.GetChildHandles(IntPtr.Zero, GetBaseMark(sMark));string[] sChildMarks = GetChildMarks(sMark);//由于主窗口在桌面出现所以很可能同名,所以要看看他的儿子和孙子...是不是都匹配            foreach (IntPtr baseHwnd in baseHwnds)            {                IntPtr handle = baseHwnd;for (int i = sChildMarks.Length - 1; i >= 0; i--)                {string[] sChildMark = sChildMarks[i].Split(':');try                    {                        handle = WinAPI.GetChildHandles(handle, UnEscape(sChildMark[0]))[int.Parse(sChildMark[1])];                    }catch                    {break;                    }

if (i == 0) return new WinHWND(handle);                }continue;            }

return null;        }

#region 转义private static string Escape(string arg)        {return arg.Replace(":", "\\:").Replace(";","\\;");        }

private static string UnEscape(string arg)        {return arg.Replace("\\:", ":").Replace("\\;", ";");        }#endregion    }}

Demo.rar效果:

ps:水果忍者新纪录:788 嘎嘎

转载于:https://www.cnblogs.com/newzhq/archive/2011/07/29/2121371.html

写个类操作窗口(句柄操作)相关推荐

  1. 8.1 matlab图形窗口与坐标轴(图形对象的句柄和属性、坐标轴的操作、图形窗口的操作)

    1.图形对象的句柄 (1)句柄的概念 在MATLAB中,用句柄来标识对象,通过句柄来访问相应对象的属性:在MATLAB系统中建立-个对象,系统就会建立-个映射该对象的句柄,用于存诸相应对象的属性. 例 ...

  2. C++模拟键盘操作窗口入门

    C++模拟键盘操作窗口入门之文件监控操作句柄操作 #include <iostream> #include <windows.h> #include <tchar.h&g ...

  3. C#之操作窗口模拟键鼠事件文件监控等知识使用

    C#之操作窗口模拟键鼠事件文件监控等知识使用 实现的效果图片,这里我在输入框输入一个号码,在C盘下创建一个文件txt文件, 被filewatch监控到,里面往指定窗口送sn被输入一些键盘鼠标的动作等操 ...

  4. python selenium元素定位、alert操作、iframe切换、多窗口切换、键盘操作、鼠标操作、js操作、操作本地文件、css高级操作

    用了那么久的selenium,整理一篇自己经常用到的标签和方法 本文档持续更新优化,喜欢的小伙伴可以点赞收藏一下 文章目录 1. 通用元素定位方法,需要引入By. 2. 通用多个元素查找By 3. c ...

  5. 【OpenCV 4开发详解】窗口交互操作

    本文首发于"小白学视觉"微信公众号,欢迎关注公众号 本文作者为小白,版权归人民邮电出版社发行所有,禁止转载,侵权必究! 经过几个月的努力,小白终于完成了市面上第一本OpenCV 4 ...

  6. 利用OpenCV的VideoCapture类实现视频读操作

    图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 博主注:后来,博主又写了一篇更为详细介绍Vide ...

  7. OpenCV —数据持久化: FileStorage类的数据存取操作与示例

    OpenCV -FileStorage类的数据读写操作与示例 OpenCV的许多应用都需要使用数据的存储于读取,例如经过3D校准后的相机,需要存储校准结果矩阵,以方便下次调用该数据:基于机器学习的应用 ...

  8. OpenCV FileStorage类的数据读写操作

    OpenCV FileStorage类的数据读写操作 OpenCV的许多应用都需要使用数据的存储于读取,例如经过3D校准后的相机,需要存储校准结果矩阵,以方便下次调用该数据:基于机器学习的应用,同样需 ...

  9. C#和C常用的API操作窗口的代码积累

    C#和C常用的API操作窗口的代码积累 IntPtr awin = MouseHookHelper.FindWindow("WeChatMainWndForPC", "微 ...

  10. 写出记录型信号量中的wait操作代码_操作系统进程的同步与互斥及经典同步与互斥问题...

    概览 临界区临界区的引入 在系统当中,有些资源允许多个进程共享(磁盘),有些资源只允许进程单独使用(打印机,共享变量).为了让进程单独使用资源而不受其他进程干扰引入了临界区的概念. 临界区的概念 在一 ...

最新文章

  1. ld-linux-x86-64.so.2+,RedHat6安装Oracle数据库遇到错误 C [ld-linux-x86-64.so.2+0x14d70]
  2. zookeeper集群部署 精简版本
  3. RVC使用指南(三)-对象管理
  4. conda里的r语言,使用“ conda”从github安装R软件包。
  5. mysql如何查看表的大小_mysql 如何查看表的大小
  6. ORA-00257: 归档程序错误。在释放之前仅限于内部连接
  7. 车机没有carlife可以自己下载吗_安卓车机CarPlay模块初体验
  8. 中文文案排版 - 中文排版教程
  9. 你选择了你的记忆,和生活。
  10. 均值不等式链的几何证明
  11. 微信开发之小程序实现倒计时
  12. TypeScript 类型声明书写踩坑全解析
  13. Windows 10的TPM模块到底是不是美国全球监控体系的奠基石?
  14. python : 超参数优化工具笔记 Tune with PyTorch Quick Start+基础概念
  15. PHP+Mysql—苹果购物商城管理系统网站(前端+后端、整套源码)
  16. 点餐订餐系统应用android源码
  17. oracle ba log market,京东爬虫、数据分析、报表 (2)
  18. 简单实现将商品加入购物车(初级)
  19. 转一个solaris虚拟内存管理的wiki
  20. 英语四六级写作预测及参考范文安排上了!

热门文章

  1. C语言函数多个返回值
  2. Varnish——CDN加速实现(单个后端服务器、缓存命中率情况)
  3. python判断成绩情况
  4. 怎么查看电脑有没有python_使用python获取电脑的磁盘信息方法
  5. moco常用配置参数及实战
  6. Non-ASCII character \xe6 in file
  7. 数据:DeFi总锁仓量突破230亿美元
  8. 比特币挖矿初创公司Layer1 CEO换任
  9. SAP License:谁能透露你的信息
  10. SAP License:ERP失败案例集