C#根据句柄改变窗体控件值
需求是这样,有个程序界面我们需要通过自己的程序持续输入数据,界面如图。

可以获得控件的句柄而用钩子写入值。这里需要用到spy++工具。在VS的工具下有个spy++工具,打开如下图

通过这个工具可以获得窗体的句柄,当然这里获得的句柄只能用于测试,因为.net开发的程序窗体每次打开句柄都会变,都需要重新获得。这个工具的用处在于找一个控件的前一句柄控件和后一句柄控件。
一、引用
//寻找目标进程窗口
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("USER32.DLL", EntryPoint = "FindWindowEx", SetLastError = true)]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, uint hwndChildAfter,string lpszClass, string lpszWindow);
//设置进程窗口到最前
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
//模拟键盘事件
[DllImport("USER32.DLL")]
public static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo);
public delegate bool CallBack(IntPtr hwnd, int lParam);
[DllImport("USER32.DLL")]
public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);
//给CheckBox发送信息
[DllImport("USER32.DLL", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int SendMessage(IntPtr hwnd, UInt32 wMsg, int wParam, int lParam);
//给Text发送信息
[DllImport("USER32.DLL", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, string lParam);
[DllImport("USER32.DLL")]
public static extern IntPtr GetWindow(IntPtr hWnd, int wCmd);
二、方法
公共方法
/// <summary>
/// 查找窗体上控件句柄
/// </summary>
/// <param name="hwnd">父窗体句柄</param>
/// <param name="lpszWindow">控件标题(Text)</param>
/// <param name="bChild">设定是否在子窗体中查找</param>
/// <returns>控件句柄,没找到返回IntPtr.Zero</returns>
private static IntPtr FindWindowEx(IntPtr hwnd, string lpszWindow, bool bChild)
{
    IntPtr iResult = IntPtr.Zero;
    // 首先在父窗体上查找控件
    iResult = FindWindowEx(hwnd, 0, null, lpszWindow);
    // 如果找到直接返回控件句柄
    if (iResult != IntPtr.Zero) return iResult;
    // 如果设定了不在子窗体中查找
    if (!bChild) return iResult;
    // 枚举子窗体,查找控件句柄
    int i = EnumChildWindows(
    hwnd,
    (h, l) =>
    {
        IntPtr f1 = FindWindowEx(h, 0, null, lpszWindow);
        if (f1 == IntPtr.Zero)
            return true;
        else
        {
            iResult = f1;
            return false;
        }
    },
    0);
    // 返回查找结果
    return iResult;
}
/// <summary>
/// 输入回车
/// </summary>
private static void PrintEnter()
{
    keybd_event(Convert.ToByte(13), 0, 0, 0);
    keybd_event(Convert.ToByte(13), 0, 2, 0);
}
获得窗体句柄
IntPtr wcHandle = FindWindow(null, "窗体名称");
if (wcHandle != IntPtr.Zero)
{
    //设置游戏窗口到最前
    SetForegroundWindow(wcHandle);
}
获得有Title的控件句柄
uint BM_GETCHECK = 0xF0;
uint BST_CHECKED = 0xF1;
IntPtr weightIntPtr = FindWindowEx(wcHandle, "输入重量[&H]", true);
if (weightIntPtr != IntPtr.Zero)
{
    //获得Checkbox值
    int i = SendMessage(weightIntPtr, BM_GETCHECK, 0, 0);
    //更改CheckBox值
    SendMessage(weightIntPtr, BST_CHECKED, 1, 0);
}
获得没Title的控件句柄
public enum WindowSearch
{
    GW_HWNDFIRST = 0, //同级别第一个
    GW_HWNDLAST = 1, //同级别最后一个
    GW_HWNDNEXT = 2, //同级别下一个
    GW_HWNDPREV = 3, //同级别上一个
    GW_OWNER = 4, //属主窗口
    GW_CHILD = 5 //子窗口}获取与指定窗口具有指定关系的窗口的句柄
}
IntPtr waybill = GetWindow(waybillIntPtr, (int)WindowSearch.GW_HWNDNEXT);
SendMessage(waybill, WM_SETTEXT, IntPtr.Zero, waybillValue);
这里完成了我们的需求,改变了窗体中选择框和Text文本框的值。
C#根据句柄改变窗体控件值的更多相关文章
- WPF通过EventTrigger改变其他控件的值
		场景:点击TextBox后弹出Poppup 原理:使用EventTrigger后触发StoryBoard,通过StoryBoard改变其他控件的值. 参考代码: <Grid> <Gr ... 
- 将四个按钮放入一个父控件的好处:方便移动,只需要改变父控件的y值,就可移动四个按钮
		将四个按钮放入一个父控件的好处:方便移动,只需要改变父控件的y值, 就可移动四个按钮 https://www.evernote.com/shard/s227/sh/78 ... 
- (转)sl简单自定义win窗体控件
		sl简单自定义win窗体控件 相信大家接触过不少win窗体控件ChildWin子窗口就的sl自带的一个 而且网上也有很多类似的控件,而今天我和大家分享下自己制作个win窗体控件,希望对初学 ... 
- C# winform 跨线程更改窗体控件的属性
		当winform程序中新开一个线程,是无法改变主线程中窗体控件的属性的,否则运行时会报错. 若想在其他线程中控制主线程中的窗体控件,则必须利用BeginInvoke方法. 例如:添加一个名为textb ... 
- winform窗体控件(全)
		回顾跟补充下除了昨天那常用6个其他的winform窗体控件作用 1:Button:按钮 (1)AutoSize:如果是True的情况下,内容将会撑开:False的话会另起一行 (2)Enabled: ... 
- 如何:对 Windows 窗体控件进行线程安全调用
		http://msdn.microsoft.com/zh-cn/library/ms171728(VS.90).aspx http://msdn.microsoft.com/zh-cn/library ... 
- C# 静态函数调用窗体控件
		回调函数方法是静态函数,需要调用窗体控件,赋值或取值. 定义 public static Form1 mainFrm; mainFrm = this; public partial class F ... 
- 用于列出选项的Windows窗体控件
		可以提供选项列表的控件有ListBox.ComboBox.CheckedListBox,如何正确的使用和选择这些控件,下面对此进行讨论.首先对这三种控件的功能分别进行说明: ListBox ListB ... 
- 如何在多线程中调用winform窗体控件
		由于 Windows 窗体控件本质上不是线程安全的.因此如果有两个或多个线程适度操作某一控件的状态(set value),则可能会迫使该控件进入一种不一致的状态.还可能出现其他与线程相关的 bug,包 ... 
随机推荐
- 企业IT管理员IE11升级指南【6】—— Internet Explorer 11面向IT专业人员的常见问题
			企业IT管理员IE11升级指南 系列: [1]—— Internet Explorer 11增强保护模式 (EPM) 介绍 [2]—— Internet Explorer 11 对Adobe Flas ... 
- CentOS6编译安装PHP7+Nginx
			本文属于动手搭建PHP开发环境的一部分,更多点击链接查看. 本文以centos6为例. 安装PHP 下载 http://cn2.php.net/distributions/php-5.6.22.tar ... 
- Atitti  onvif 设备发现与原理
			Atitti onvif 设备发现与原理 1.1. ,有以下几个步骤:1 1.2. 设备搜索原理及编程技巧:2 1.3. Ws disconvert 的组播地址和端口就是37022 1)发现ipca ... 
- Oracle 多行转多列,列值转为列名
			前段时间做调查问卷,客户创建自定义问卷内容,包括题目和选项内容; 之后需要导出问卷明细,,,,麻烦来咯 于是到网上到处搜索,没有直接结果;于是又找各种相似的,,终于功夫不负有心人 然后最终自己写出来了 ... 
- Distributed4:SQL Server 分布式数据库性能测试
			我使用三台SQL Server 2012 搭建分布式数据库,将一年的1.4亿条数据大致均匀存储在这三台Server中,每台Server 存储4个月的数据,Physical Server的配置基本相同, ... 
- jQuery源码分析系列(39) : 动画队列
			data函数在jQuery中只有短短的300行代码,非常不起点 ,剖析源码的时候你会发现jQuery只要在有需要保存数据的地方无时无刻不依赖这个基础设施 动画会调用队列,队列会调用data数据接口还保 ... 
- Spark中决策树源码分析
			1.Example 使用Spark MLlib中决策树分类器API,训练出一个决策树模型,使用Python开发. """ Decision Tree Classifica ... 
- MVC5 网站开发实践 2.2、管理员身份验证
			上次完成了管理员的登录,这次要解决对管理员登录后的验证,采用AuthorizeAttribute属性的方式.之前还要解决几个问题,然后才重写验证类,最后稍微改一下界面. 目录 MVC5 网站开发实践 ... 
- 【结果很简单,过程很艰辛】记阿里云Ons消息队列服务.NET接口填坑过程
			Maybe 这个问题很简单,因为解决方法是非常简单,但填坑过程会把人逼疯,在阿里云ONS工作人员.同事和朋友的协助下,经过一天的调试和瞎捣鼓,终于解决了这个坑,把问题记下来,也许更多人在碰到类似问题的 ... 
- AngularJS之指令中controller与link(十二)
			前言 在指令中存在controller和link属性,对这二者心生有点疑问,于是找了资料学习下. 话题 首先我们来看看代码再来分析分析. 第一次尝试 页面: <custom-directive& ... 
