C#根据句柄改变窗体控件值

原文: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文本框的值。

时间: 2025-01-21 17:43:17

C#根据句柄改变窗体控件值的相关文章

求助:winform子窗体控件值保存的问题

问题描述 一个主窗体,两三个子窗体,通过主窗体打开子窗体编辑里面textbox中的内容,然后保存关闭子窗体.主窗体调用子窗体里面的值进行运算.求教各位大神,程序运行时,该如何实现保存子窗体里面textbox控件的值?程序退出时,该如何保存所有窗体里面的值?新手上路,全靠自己摸索,还望大家不吝赐教,先谢谢了! 解决方案 解决方案二:在主窗体里定义一个全局的变量即可.publicstaticstringtxt=null;在子窗体关闭的时候.MainForm.txt=textbox1.Text;在主窗

使用js判断TextBox控件值改变然后出发事件

 这篇文章主要介绍了使用js判断TextBox控件值改变然后出发事件.需要的朋友可以过来参考下,希望对大家有所帮助 代码如下: <script language="javascript" type="text/javascript">       var firsty;//最开始的加载页面时年和月     var firstm;       var secondy;//当onchange触发后的值     var secondm;     var pan

控件随窗体等比例缩放,怎么改变combo控件下拉按钮的大小?

问题描述 控件随窗体等比例缩放,怎么改变combo控件下拉按钮的大小? 控件随窗体等比例缩放,怎么改变combo控件下拉按钮的大小?为什么它的大小不会自动缩放?

link如何保存并且恢复程序里面所有的窗体控件的值

问题描述 link如何保存并且恢复程序里面所有的窗体控件的值 link如何保存并且恢复程序里面所有的窗体控件的值 最好用LINK来实现的,代码? 解决方案 直接保存到配置文件就可以了.要什么linq呢?

同一个窗体根据用户来改变contextMenuStrip控件的可见性,这个可以实现吗??

问题描述 同一个窗体根据用户来改变contextMenuStrip控件的可见性,这个可以实现吗??比如说,用户A可以通过右击显示contextMenuStrip控件,用户b则不能通过右击显示contextMenuStrip控件 解决方案 解决方案二:可以实现,关键是你先能区分是A还是B解决方案三:这就是权限管理,你为每个人设置权限,根据这个设置去控制界面,关于权限设置的文章很多,你可以去搜搜解决方案四:引用2楼bdmh的回复: 这就是权限管理,你为每个人设置权限,根据这个设置去控制界面,关于权限

Delphi实现窗体控件自由摆布

在做Mis项目过程中,有时需要让用户自己来实现窗体控件的布局,比如酒店管理中就需要对餐厅餐桌位置进行布局.要实现这种功能,必须做好三件事: 1.设置进入控件边缘的光标形状: 2.改变控件的大小及位置: 3.保存窗体控件的位置及状态,窗体下次启动时重新设置它们的这些信息.具体步骤如下: 1.修改控件光标.只需要在进入控件的时候,将screen的cursor属性设置成对应形状即可,控件都有一个OnMouseMove事件,在这个事件中调用它就可以实现.我已经将它封装成函数如下: procedure C

从在 Internet Explorer 中使用 Windows 窗体控件开始谈Smart Client

client|window|控件 首先引用Microsoft Windows 窗体快速入门教程上的文章"在 Internet Explorer 中使用 Windows 窗体控件":(如果引用的一些信息无法正常显示,请直接上面上的链接查看) 本主题描述如何在 Internet Explorer (IE) 内成功地执行 Windows 窗体控件.IE 内的 Windows 窗体控件无需用户提示即可激活,它不要求注册,而且利用公共语言运行库 (CLR) 代码访问安全性. 在 Internet

使用反射将业务对象绑定到 ASP.NET 窗体控件

asp.net|对象|控件 John DyerDallas Theological Seminary 适用于:Microsoft Visual Studio 2005 及早期版本ASP.NET 1.1C# 编程语言Visual Basic 编程语言 摘要:使用反射以单行代码将业务对象绑定到 ASP.NET Web 窗体,从而降低复杂性并减少错误.(本文包含一些指向英文站点的链接.请注意,在示例文件中,程序员的注释使用的是英文,本文中将其译为中文是为了便于读者理解.) 下载 MSDFormBind

Windows窗体控件开发示例:扩展TreeView

摘要:讲述了如何向 TreeView 控件添加数据绑定功能,它是一系列 Microsoft Windows 控件开发示例之一.您可以将本文与相关的概述文章结合起来阅读. 简介 在可能的情况下,您应该先使用些现成的控件:因为提供的 Microsoft Windows 窗体控件中包含大量编码和测试成果,如果您要放弃它们从头开始,无疑是一种巨大的浪费.基于此,在本例中,我将继承一个现有 Windows 窗体控件 TreeView ,然后对其进行自定义.在下载该 TreeView 控件的代码时,您还会得