• C# 获取句柄中的文本框内容


    C# 如何用获取文本框的句柄,并且获取文本框里面的值?

    C# 如何用获取某个应用程序里面的文本框的句柄,并且获取文本框里面的值?
    我是要拿到那个程序里面文本框的句柄.

    IntPtr ab = new IntPtr();
    StringBuilder className = new StringBuilder(256);
    IntPtr ip = User32API.FindWindow("Notepad", "Raybelly.txt - 记事本");
    IntPtr b = User32API.FindWindowEx(ip, ab, "Edit", null);
    User32API.GetWindowText(b, className, className.Capacity);
    MessageBox.Show(className.ToString());

    我现在已经拿到文本框的句柄了,但是GetWindowText方法拿不出里面的值?

    const int HWND_TOPMOST = -1;
    const int SWP_SHOWWINDOW = 40;
    const int WM_GETTEXT = 0x000D;
    private void Form1_Load(object sender, System.EventArgs e)
    {
    IntPtr ab = new IntPtr();
    StringBuilder className = new StringBuilder(256);
    IntPtr ip = User32API.FindWindow("Notepad", "Raybelly.txt - 记事本");
    IntPtr b = User32API.FindWindowEx(ip, ab, "Edit", null);
    //User32API.GetWindowText(b, className, className.Capacity);
    //MessageBox.Show(className.ToString());

    string w = "";
    IntPtr ptr = Marshal.StringToHGlobalAnsi(w);
    if (User32API.SendMessage(b, WM_GETTEXT, 100000, ptr))
    MessageBox.Show(Marshal.PtrToStringAnsi(ptr));

    }

    解决办法:

    const int HWND_TOPMOST = -1;
    const int SWP_SHOWWINDOW = 40;
    const int WM_GETTEXT = 0x000D;
    private void Form1_Load(object sender, System.EventArgs e)
    {
    IntPtr ab = new IntPtr();
    StringBuilder className = new StringBuilder(256);
    IntPtr ip = User32API.FindWindow("Notepad", "Raybelly.txt - 记事本");
    IntPtr b = User32API.FindWindowEx(ip, ab, "Edit", null);
    //User32API.GetWindowText(b, className, className.Capacity);
    //MessageBox.Show(className.ToString());

    string w = "";
    IntPtr ptr = Marshal.StringToHGlobalAnsi(w);
    if (User32API.SendMessage(b, WM_GETTEXT, 100000, ptr))
    MessageBox.Show(Marshal.PtrToStringAnsi(ptr));

    }

    参照以上资材(网上下载的)编写了我自己的程序,运行过程中发现功能没有问题,但是经常死机,卡死。

    应该反复寻找,找到了额问题点的所在

    string w="" ; 申请的是空字符串,而 if (User32API.SendMessage(b, WM_GETTEXT, 100000, ptr))  使用了100000个字符串。

    运行一次两次没有问题,如果经常使用 会出现 卡死,死机的问题发生

    解决办法 string w="" ; 变更为 string  w=new string(new char[100000]);

    这样就解决问题了

    句柄太消耗CPU资源了

     

    以下是我优化后直接使用StringBuilder 来接收数据

    using System.Runtime.InteropServices;

     [DllImport("user32.dll", EntryPoint = "SendMessage")]
     private static extern void SendMessage(IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam);

    // rfptr为主菜单的句柄

    rfptr = FindWindow(null, "要寻找的标题名称");

    //child_2为文本框的 句柄

    child_2 = FindWindowEx(rfptr, child_two, "要寻找的类名称");

    StringBuilder strbu = new StringBuilder(102);
    SendMessage(child_2, 0x0d, 100, strbu);

    //label1.text输出找到的文档

    label1.text=strbu.tostring();

    面是转载自:http://www.cnblogs.com/me-sa/articles/669402.html

    SendMessage是一个在user32.dll中声明的API函数,在C#中导入如下:

    using System.Runtime.InteropServices;[DllImport("user32.dll", EntryPoint="SendMessageA")]public static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

    本文描述其参数 lParam 的用法,主要是数据类型之间的转化

    一种最简单的处理方式是声明多个SendMessage函数(overload),用所需的数据类型直接替换IntPtr。例如:

    //声明:[DllImport("user32.dll", EntryPoint="SendMessageA")]private static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, string lParam);[DllImport("user32.dll", EntryPoint="SendMessageA")]private static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, ref Rectangle lParam);//调用:string s = "hello, floodzhu";SendMessage(this.textBox1.Handle, WM_SETTEXT, IntPtr.Zero, s);Rectangle rect = new Rectangle();SendMessage(this.richTextBox1.Handle, EM_GETRECT, (IntPtr)0, ref rect);

    对要求返回字符串的类型(out string)可以用 StringBuilder 代替,此时不需要 out/ref。例如:

    [DllImport("user32.dll", EntryPoint="SendMessageA")]private static extern int SendMessage (IntPtr hwnd, int wMsg, int wParam, StringBuilder lParam);private void button1_Click(object sender, System.EventArgs e){ const int buffer_size = 1024; StringBuilder buffer = new StringBuilder(buffer_size); SendMessage(this.textBox1.Handle, WM_GETTEXT, buffer_size, buffer); //MessageBox.Show(buffer.ToString());}

    如果想用 InPtr 类型统一处理的话,可以借助于 Marshal 或者 GCHandle 的相关方法。例如:

    [DllImport("user32.dll", EntryPoint="SendMessageA")]private static extern int SendMessage (IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);private void button2_Click(object sender, System.EventArgs e){ Rectangle rect = new Rectangle(); IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Rectangle))); Marshal.StructureToPtr(rect, buffer ,true); SendMessage(this.richTextBox1.Handle, EM_GETRECT, (IntPtr)0, buffer); rect = (Rectangle)Marshal.PtrToStructure(buffer, typeof(Rectangle)); Marshal.FreeHGlobal(buffer);}

    或者

    private void button2_Click(object sender, System.EventArgs e){ Rectangle rect = new Rectangle(); GCHandle gch = GCHandle.Alloc(rect); SendMessage(this.richTextBox1.Handle, EM_GETRECT, (IntPtr)0, (IntPtr)gch); rect = (Rectangle)Marshal.PtrToStructure((IntPtr)gch, typeof(Rectangle)); gch.Free();}

  • 相关阅读:
    java四种数组排序
    hadoop安装及配置
    Talend初试,实现定时同步
    JAVA语言概述和基本语法知识点
    Maven项目资源文件打包错误
    Ajax同步和异步
    Nginx + Tomcat 负载均衡
    PLSQL安装配置
    WebStorm 设置光标位置不随意停靠
    Hello Node.js
  • 原文地址:https://www.cnblogs.com/2SBC/p/12851751.html
Copyright © 2020-2023  润新知