什么是句柄(编译原理句柄是什么意思)?
边肖工作的单位性质偏向于服务制造业。众所周知,我国高端设备基本依赖进口,自有CAM软件一般是全封闭的,没有开放的API接口。但在工业互联网时代,设备网络化、生产数据云端化是大势所趋。那么,在国外技术封锁的情况下,如何实现第三方软件的数据采集呢?
在Windows系统下,有个东西叫handle,是Windows编程的基础。只要Windows上运行的软件绕不过去。本文将带你学习如何使用底层句柄实现第三方软件的交互。
句柄及其作用官方对handle的解释在这里没有过多提及,一般刚接触这个概念的人是无法理解的。要掌握这个把柄,你只需要明白这几点:
1.句柄并不是什么神秘的东西,它只是一个4字节的值(64位系统8字节,后续所有文章都会用32位展开)。然而,它是独一无二的。当系统启动时,它将建立一个句柄表。程序在Windows上运行时,会被系统自动分配给每一个对象,比如表单句柄、表单控件句柄(输入框、按钮)、文件句柄等。
2.句柄单独存在于一个固定的区域,因为内存中对象的地址可能会实时变化,但系统会将变化后的地址绑定一个唯一不变的句柄,使其保持不变。
3.你可以把它理解为一个指针,通过它你可以找到程序中的每一个对象。
4.虽然句柄类似于指针,可以通过句柄找到对应的对象,但是不能像指针一样使用句柄。必须通过系统打包的API来使用。
下图是通过spy++实现GifCam(第三方gif制作软件)各个控件的句柄。手柄:图中000A07F0是Rec按钮的手柄。一旦得到它的句柄,就可以通过系统API控制按钮的功能,比如点击开始录音。
sp y+++查看GifCam
类比理解如果你还是不能理解上面的说法,请看类比:
你们都看过古装剧吗?在古代,每个奴隶都被打上奴隶标记,每个标记都有不同的编号。奴隶主管理奴隶的时候,都是通过烙印来管理的。但是每个奴隶都有自己的名字。类比手柄,可以这样理解:奴隶的实物就是对象,他的名字就是他在电脑里的地址(名字可以随意改,奴隶想改名重新开始生活,但是奴隶主会愿意吗?),奴隶标记就是把柄(不管你怎么改名字,只要这个奴隶标记在,你就跑不掉)。
图形理解:
手柄图
句柄实际应用关于手柄的理解,我讲了很多。这里我开始回到实际的项目,探讨句柄在实际项目中是如何发挥作用的。
要求:如下图所示,需要实时获取图中的幅值和相位值。
获取数据的表单
编程思路:
编程思想
要用CSharp实现以上功能,需要介绍使用
系统;运行时;互 *** 作服务;和使用系统。诊断;
系统。诊断:负责进程关联。
系统。runtime . interop services:DLLimport功能,负责调用系统API。
代码实现:
class Program { //系统API //通过窗体标题寻找窗体句柄 [DllImport(quot;user32.dllquot;, EntryPoint = quot;FindWindowquot;)] public static extern IntPtr FindWindow( string lpClassName, string lpWindowName ); //遍历主窗体下的所有句柄(各控件对象) [DllImport(quot;user32.dllquot;, EntryPoint = quot;FindWindowExquot;)] public static extern IntPtr FindWindowEx( IntPtr hWnd1, IntPtr hWnd2, string lpsz1, string lpsz2 ); //通过对象句柄获取控件文字内容 [DllImport(quot;user32.dllquot;, SetLastError = true, CharSet = CharSet.Auto)] public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); //通过对象句柄获取控件类名 [DllImport(quot;user32.dllquot;, SetLastError = true, CharSet = CharSet.Auto)] public static extern int GetClassName(IntPtr hWnd, StringBuilder lpString, int nMaxCount); //通过对象句柄给对象发系统消息(系统定义的消息标识:如单击、输入文字等) [DllImport(quot;User32.dllquot;, EntryPoint = quot;SendMessagequot;)] public static extern int SendMessages(IntPtr hWnd, // 信息发往的窗口的句柄 int Msg, // 消息ID int wParam, // 参数1 int lParam //参数2 ); //--------------------------- static void Main(string[] args) { bool find = false; IntPtr hwnd = IntPtr.Zero; while (!find) { string title = null; Process[] process = Process.GetProcesses(); foreach (Process p in process) { title = p.MainWindowTitle.ToString(); if (title.Contains(quot;iBalancequot;)) { hwnd = p.Handle; find = true; break; } } // Console.WriteLine(title); if (find) hwnd = FindWindow(null, title); else { ProcessStartInfo info = new ProcessStartInfo(@quot;C:\Program Files\ANCA\RN31.1-1\TG7\BIN\Vibe_Monitor.exequot;); Process.Start(info); Thread.Sleep(1000); Console.WriteLine(quot;open itquot;); } } find = false; if (hwnd != IntPtr.Zero) { StringBuilder sb_text = new StringBuilder(1024); StringBuilder sb_class= new StringBuilder(1024); IntPtr child = IntPtr.Zero ; do { child = FindWindowEx(hwnd, child, null, null); GetWindowText(child,sb_text,sb_text.Capacity); // Console.Write(sb_text.ToString()+quot;::CLASS::quot;); GetClassName(child, sb_class, sb_class.Capacity); //Console.WriteLine(sb_class.ToString()); if (sb_text.ToString().Contains(quot;.quot;) amp;amp; sb_class.ToString() == quot;Staticquot;) { find = true; break; } sb_text.Remove(0,sb_text.Length); sb_class.Remove(0, sb_class.Length); } while (child != IntPtr.Zero); StringBuilder msg = new StringBuilder(); if (find) { int i = 0; string msg_combine = string.Empty; try { while (true) { Thread.Sleep(10); sb_text.Remove(0, sb_text.Length); GetWindowText(child, sb_text, sb_text.Capacity); int index = sb_text.ToString().IndexOf(quot;\nquot;); msg_combine = DateTime.Now.ToString() + quot;:quot; + quot;震幅:quot; + sb_text.ToString().Substring(0, index) + quot;相位:quot; + sb_text.ToString().Substring(index + 1, sb_text.ToString().Length - index - 1); i++; Console.WriteLine(msg_combine + quot;::quot;+i); msg.AppendLine(msg_combine); if (i == 1024) { i = 0; StreamWriter sw = new StreamWriter(quot;msg.txtquot;, true, Encoding.UTF8); sw.WriteLine(msg.ToString()); msg = new StringBuilder(); sw.Flush(); sw.Close(); } } } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(quot;程序被关闭quot;); } } } Console.Read(); } }欢迎分享,转载请注明来源:内存溢出
评论列表(0条)