在windows平台句柄是共享资源,也就是一个进程可以拿到另外一个进程的句柄,当然包括那个进程创建的窗体句柄,甚至是控件的句柄(除非拿不到该句柄)
方法是:
1.FindWindow 拿到目标窗体的句柄,当然也可其他方式拿到窗体句柄
2.FindwindowEx拿到1上面的控件(应当先知道该控件的名字,俺用spy++探测)
3.SendMessage发送消息给2返回的句柄
下面用windows自带的计算器(calc)进行简单的操作,将两个uint进行运算
//////////////////////////Feng's//////////////////////////////////
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
using System.Diagnostics;
public class GETControlTEXT {
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string ClassName, string windowName);
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndPareent,
IntPtr hwndChildAfter,
string ClassName,
string windowName);
[DllImport("user32.dll", SetLastError = true)]
static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
//WM_GETTEXT 消息用于获取其他应用程序的标题获取控件的标题
//0x000D
//用SendMessage获取
static int WM_GETTEXT = 0x000D;
public static void GetText() {
IntPtr jsq = FindWindow(null, "计算器");
IntPtr ctext = FindWindowEx(jsq, IntPtr.Zero, "Edit", null);
IntPtr wp = Marshal.AllocHGlobal(4);
Marshal.WriteInt32(wp, 260);
IntPtr lp = Marshal.AllocHGlobal(wp);
SendMessage(ctext, WM_GETTEXT, wp, lp);
string s = Marshal.PtrToStringAnsi(lp);
Console.WriteLine(s);
if(wp != IntPtr.Zero)
Marshal.FreeHGlobal(wp);
if(lp != IntPtr.Zero)
Marshal.FreeHGlobal(lp);
}
static int BM_CLICK = 0x00F5;
static string button="Button";
/// <summary>
/// 用这个函数可以用来编程实现对计算器的操作,仅可用来做十进制计算
/// </summary>
/// <param name="firstOperand">第一个操作数</param>
/// <param name="Operate">操作符号,例如"+","-","*","-","x^y"等等,在CALC上的操作符</param>
/// <param name="secondOperand"></param>
public static void Count(uint firstOperand,string Operate,uint secondOperand ) {
//十进制计算
//1+1=2
// BM_CLICK Button被点击
//WM_SETTEXT 设置文本
IntPtr jsq = FindWindow(null, "计算器");
if(jsq == IntPtr.Zero)
Process.Start("calc");
jsq = FindWindow(null, "计算器");
//CE被点击
IntPtr buttonHandle = FindWindowEx(jsq, IntPtr.Zero, button, "CE");//无法解释为什么点击C只有一声响,却没有任何作用
int rv= SendMessage(buttonHandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero);//清空原有的数据
string[] fsary = setUinttoStringAry( firstOperand);
string[] ssary = setUinttoStringAry( secondOperand);
foreach(string t in fsary)
Operator(jsq, t);
Operator(jsq, Operate);
foreach(string t in ssary)
Operator(jsq, t);
//结果
Operator(jsq, "=");
}
static string[] setUinttoStringAry(uint value) {
List<string> temp = new List<string>();
uint c = _Count(value);
for(uint i = 0; i < c; i++)
temp.Add( getValuefromLeftDigit(value, i).ToString());
return temp.ToArray();
}
static void Operator(IntPtr jsq, string oprand) {
IntPtr buttonHandle = FindWindowEx(jsq, IntPtr.Zero, button, oprand);
SendMessage(buttonHandle, BM_CLICK, IntPtr.Zero, IntPtr.Zero);
}
internal static uint getValuefromLeftDigit(uint specValue, uint LeftDigit) {
uint count = 1;
uint t = specValue;
while((t /= 10) > 0)
count++;
if(count < LeftDigit)
throw new ArgumentOutOfRangeException
("参数LeftDigit指定的位数范围大于specValue参数的位数");
LeftDigit++;
uint tempValue = specValue / (uint)Math.Pow(10, count - LeftDigit);
return tempValue % 10;
}
public static uint _Count(uint specValue) {
uint count = 1;
uint t = specValue;
while((t /= 10) > 0)
count++;
return count;
}
};