需求是这样,有个程序界面我们需要通过自己的程序持续输入数据,界面如图。

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

通过这个工具可以获得窗体的句柄,当然这里获得的句柄只能用于测试,因为.net开发的程序窗体每次打开句柄都会变,都需要重新获得。这个工具的用处在于找一个控件的前一句柄控件和后一句柄控件。

一、引用

  1. //寻找目标进程窗口
  2. [DllImport("USER32.DLL")]
  3. public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
  4. [DllImport("USER32.DLL", EntryPoint = "FindWindowEx", SetLastError = true)]
  5. public static extern IntPtr FindWindowEx(IntPtr hwndParent, uint hwndChildAfter,string lpszClass, string lpszWindow);
  6. //设置进程窗口到最前
  7. [DllImport("USER32.DLL")]
  8. public static extern bool SetForegroundWindow(IntPtr hWnd);
  9. //模拟键盘事件
  10. [DllImport("USER32.DLL")]
  11. public static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo);
  12. public delegate bool CallBack(IntPtr hwnd, int lParam);
  13. [DllImport("USER32.DLL")]
  14. public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);
  15. //给CheckBox发送信息
  16. [DllImport("USER32.DLL", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
  17. public static extern int SendMessage(IntPtr hwnd, UInt32 wMsg, int wParam, int lParam);
  18. //给Text发送信息
  19. [DllImport("USER32.DLL", EntryPoint = "SendMessage")]
  20. private static extern int SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, string lParam);
  21. [DllImport("USER32.DLL")]
  22. public static extern IntPtr GetWindow(IntPtr hWnd, int wCmd);

二、方法

公共方法

  1. /// <summary>
  2. /// 查找窗体上控件句柄
  3. /// </summary>
  4. /// <param name="hwnd">父窗体句柄</param>
  5. /// <param name="lpszWindow">控件标题(Text)</param>
  6. /// <param name="bChild">设定是否在子窗体中查找</param>
  7. /// <returns>控件句柄,没找到返回IntPtr.Zero</returns>
  8. private static IntPtr FindWindowEx(IntPtr hwnd, string lpszWindow, bool bChild)
  9. {
  10. IntPtr iResult = IntPtr.Zero;
  11. // 首先在父窗体上查找控件
  12. iResult = FindWindowEx(hwnd, 0, null, lpszWindow);
  13. // 如果找到直接返回控件句柄
  14. if (iResult != IntPtr.Zero) return iResult;
  15. // 如果设定了不在子窗体中查找
  16. if (!bChild) return iResult;
  17. // 枚举子窗体,查找控件句柄
  18. int i = EnumChildWindows(
  19. hwnd,
  20. (h, l) =>
  21. {
  22. IntPtr f1 = FindWindowEx(h, 0, null, lpszWindow);
  23. if (f1 == IntPtr.Zero)
  24. return true;
  25. else
  26. {
  27. iResult = f1;
  28. return false;
  29. }
  30. },
  31. 0);
  32. // 返回查找结果
  33. return iResult;
  34. }
  35. /// <summary>
  36. /// 输入回车
  37. /// </summary>
  38. private static void PrintEnter()
  39. {
  40. keybd_event(Convert.ToByte(13), 0, 0, 0);
  41. keybd_event(Convert.ToByte(13), 0, 2, 0);
  42. }

获得窗体句柄

  1. IntPtr wcHandle = FindWindow(null, "窗体名称");
  2. if (wcHandle != IntPtr.Zero)
  3. {
  4. //设置游戏窗口到最前
  5. SetForegroundWindow(wcHandle);
  6. }

获得有Title的控件句柄

  1. uint BM_GETCHECK = 0xF0;
  2. uint BST_CHECKED = 0xF1;
  3. IntPtr weightIntPtr = FindWindowEx(wcHandle, "输入重量[&H]", true);
  4. if (weightIntPtr != IntPtr.Zero)
  5. {
  6. //获得Checkbox值
  7. int i = SendMessage(weightIntPtr, BM_GETCHECK, 0, 0);
  8. //更改CheckBox值
  9. SendMessage(weightIntPtr, BST_CHECKED, 1, 0);
  10. }

获得没Title的控件句柄

  1. public enum WindowSearch
  2. {
  3. GW_HWNDFIRST = 0, //同级别第一个
  4. GW_HWNDLAST = 1, //同级别最后一个
  5. GW_HWNDNEXT = 2, //同级别下一个
  6. GW_HWNDPREV = 3, //同级别上一个
  7. GW_OWNER = 4, //属主窗口
  8. GW_CHILD = 5 //子窗口}获取与指定窗口具有指定关系的窗口的句柄
  9. }
  10. IntPtr waybill = GetWindow(waybillIntPtr, (int)WindowSearch.GW_HWNDNEXT);
  11. SendMessage(waybill, WM_SETTEXT, IntPtr.Zero, waybillValue);

这里完成了我们的需求,改变了窗体中选择框和Text文本框的值。

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

  1. WPF通过EventTrigger改变其他控件的值

    场景:点击TextBox后弹出Poppup 原理:使用EventTrigger后触发StoryBoard,通过StoryBoard改变其他控件的值. 参考代码: <Grid> <Gr ...

  2. 将四个按钮放入一个父控件的好处:方便移动,只需要改变父控件的y值,就可移动四个按钮

      将四个按钮放入一个父控件的好处:方便移动,只需要改变父控件的y值, 就可移动四个按钮               https://www.evernote.com/shard/s227/sh/78 ...

  3. (转)sl简单自定义win窗体控件

    sl简单自定义win窗体控件      相信大家接触过不少win窗体控件ChildWin子窗口就的sl自带的一个  而且网上也有很多类似的控件,而今天我和大家分享下自己制作个win窗体控件,希望对初学 ...

  4. C# winform 跨线程更改窗体控件的属性

    当winform程序中新开一个线程,是无法改变主线程中窗体控件的属性的,否则运行时会报错. 若想在其他线程中控制主线程中的窗体控件,则必须利用BeginInvoke方法. 例如:添加一个名为textb ...

  5. winform窗体控件(全)

    回顾跟补充下除了昨天那常用6个其他的winform窗体控件作用 1:Button:按钮 (1)AutoSize:如果是True的情况下,内容将会撑开:False的话会另起一行 (2)Enabled: ...

  6. 如何:对 Windows 窗体控件进行线程安全调用

    http://msdn.microsoft.com/zh-cn/library/ms171728(VS.90).aspx http://msdn.microsoft.com/zh-cn/library ...

  7. C# 静态函数调用窗体控件

    回调函数方法是静态函数,需要调用窗体控件,赋值或取值. 定义 public static Form1 mainFrm;   mainFrm = this; public partial class F ...

  8. 用于列出选项的Windows窗体控件

    可以提供选项列表的控件有ListBox.ComboBox.CheckedListBox,如何正确的使用和选择这些控件,下面对此进行讨论.首先对这三种控件的功能分别进行说明: ListBox ListB ...

  9. 如何在多线程中调用winform窗体控件

    由于 Windows 窗体控件本质上不是线程安全的.因此如果有两个或多个线程适度操作某一控件的状态(set value),则可能会迫使该控件进入一种不一致的状态.还可能出现其他与线程相关的 bug,包 ...

随机推荐

  1. NEsper Nuget包

    Esper是专门进行复杂事件处理(CEP)的流处理平台,Java版本为Esper,.Net版本为NEsper.Esper & NEsper可以方便开发者快速开发部署处理大容量消息和事件的应用系 ...

  2. iOS开发系列--并行开发其实很容易

    --多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的, ...

  3. JSON与XML的区别比较

    1.定义介绍 (1).XML定义扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许 ...

  4. Mac 软件篇

    对于美好事务的追求无论何时都不算晚. ** 文章内容来着我整理的fetool,以下内容可能更新不及时 ** Mac 下的软件那么多,又是免费又是付费,应该怎么选呢?我来分享下我的推荐列表,推荐的优先级 ...

  5. 《Entity Framework 6 Recipes》中文翻译系列 (37) ------ 第六章 继承与建模高级应用之独立关联与外键关联

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 6-13  在基类中应用条件 问题 你想从一个已存在的模型中的实体派生一个新的实体, ...

  6. 启动 Apache2.2 的问题

    启动 Apache2.2 的问题: windows不能在本地计算机启动 Apache2.2.有关更多信息,查阅系统事件日志.如果这是非Microsoft服务,请与服务厂商联系,并参考特定服务错误代码1 ...

  7. 30个你必须记住的CSS选择符

    所以你学会了基础的id,类和后代选择符,然后你就一直用它们了吗?如果是这样,你丢失了(css的)巨大的灵活性.在本文中提到的很多选择器属于CSS3规范的一部分,因此,只有在现代浏览器中才可使用. 1. ...

  8. 2013 duilib入门简明教程 -- 自绘标题栏(5)

        如果大家有做过标题栏的自绘,肯定会感慨各种不容易,并且现有的一些资料虽然完美的实现了功能,但是代码比较乱,需要自行整理.如果用duilib,就是小case啦.     duilib其实并没有区 ...

  9. 监控Linux系统性能的工具--nmon(一)

    今天看到一资料上写着,nmon可以对linux系统进行性能监控,随手在自己的阿里云上敲了一下这个命令,提示'command not find' 一脸懵~,然后探索了一下如何安装这个工具以及如何更好的查 ...

  10. C#设计模式-装饰者模式

    在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).Access ...