用C#操作API实现填写桌面窗体内的textbox,并点击窗体内按钮

2024-12-22 17:55:45
推荐回答(4个)
回答1:

首先通俗地讲:wparam和lparam是sendmessage的两个参数。也就是说,它会随着wMsg所代表的消息的不同而不同,所以理解起来有一定的难度。

我想你的疑问来自于API定义里面的WPARAM wParam,LPARAM IParam吧

WPARAM 和LPARAM 这两个结构体在C#中没有定义(这也是C#操作API不方便的诸多地方之一,很多结构都需要转换成C#相应类型,这大大提高了C#操作API的入门难度)。下表的内容对你用C#掉API有帮助:

C++          输入输出    C# 

================================== 

char chr[255]  O    StringBuilder 

KCA_DIR        I    int 

LPCSTR          I    string 

int            I    int 

LPSTR          O    StringBuilder 

int*            O    out int 

DWORD          I    int 

DWORD*          O    out int 

BOOL            I    bool 

Rc_DBMgr        I    IntPtr 

long*          O    out long 

继续说明这两个参数使用场合,一下举例:

1、向某窗口发送一个WM_SETTEXT消息,获得该窗口的文本    

string  tempstr = "要设置的值"; 

SendMessage(hWnd,WM_SETTEXT,IntPtr.Zero,tempstr); 

说明:WM_SETTEXT是设置文本消息,相应地, 此时的lParam为要设置的值,wParam参数不需要我们给IntPtr.Zero。

2、向某控件发送一个BM_CLICK消息   

SendMessage(hWnd,BM_CLICK,IntPtr.Zero,IntPtr.Zero)   

说明:BM_CLICK此时的wParam和lParam均没有作用,所以为IntPtr.Zero

如果你抽时间多了解一下API的话会发现这两个结构体使用频率很高。不用多想,就当做两个普通结构来对待就可以。上表的结构在转C#类型的时候不需要开发人员去处理,这种转换在C#进行调用的时候是自动进行的。

上面几位已经把获得窗口句柄讲的很详细了,我就不再费口舌了。

如果仍有疑问可以联系我。 

------------------------------------------------------------

恩,果然遇到我最担心的问题了,看来躲是躲不掉,呵呵。

引用前辈们的解决方法吧:

1.打开要操作的程序 

2.把这个程序窗口置顶!也就算是激活了(主窗口的句柄你可以得到!) 

3.获得这个窗口在屏幕上的位置信息(程序窗口左上角的坐标值) 

设为(x,y) 

4.获得你要操作的按钮在窗口上的坐标信息(a,b),那么这个按钮在整个屏幕里的坐标值就是(x+a,y+b) 

5.移动鼠标到(x+a,y+b)这个位置! 

6.模拟单击 

补充:第4步中的a和b的值你可能不能得到,因为你得不到按钮的句柄,但是你可以打开那个程序,然后用qq截图功能从窗口的左上角开始拖拉鼠标,直到移动到按钮的中间位置,这时候,左上角有截图大小信息,也就是坐标信息了! 这样我们就可以估算一个坐标值,把它付给a和b!  呵呵!就达到我们的目的了!

回答2:

user32.dll下

使用findwindows(string winclass,string wintitle)来返回句柄
然后使用sendMessage();函数发消息驱动键盘输入或者点击button来发送。

回答3:

你说的窗口都是其它程序的吧?
填写textbox,首先用API FindWindow 查找窗口,然后用API FindWindowEx 查找textbox的句柄,你可以用Spy++查看一下窗口的结构,类名之类的信息用来查找。然后用API SendMessage发送一个SendMessage 发送一个 WM_SETTEXT,声明这个API的时候把最后一个参数类型声明成StringBuilder吧(没试验过)或者用API SetWindowText设置内容。
点击按钮那个,用同样的方法找到按钮的句柄,然后SendMessage发送一个WM_LBUTTONUP 消息。

回答4:

你参考
下面是整个程序的部分,查找窗体并对它进行操作
private int SearchWindow()
{
int retval = 0; //增加一个返回值用来判断操作是否成功

//下面的这些参数都可以用Spy++查到
string lpszParentClass = "#32770"; //整个窗口的类名
string lpszParentWindow = "本地连接"; //窗口标题
string lpszClass = "Edit"; //需要查找的子窗口的类名,也就是输入框
string lpszClass_Submit = "Button"; //需要查找的Button的类名
string lpszName_Submit = "确定"; //需要查找的Button的标题
string text = "";

IntPtr ParenthWnd = new IntPtr(0);
IntPtr EdithWnd = new IntPtr(0);

//查到窗体,得到整个窗体
ParenthWnd = FindWindow(lpszParentClass,lpszParentWindow);

//判断这个窗体是否有效
if (!ParenthWnd.Equals(IntPtr.Zero))
{
//得到User Name这个子窗体,并设置其内容
EdithWnd = FindWindowEx(ParenthWnd,EdithWnd,lpszClass,"");
if (!EdithWnd.Equals(IntPtr.Zero))
{
text = this.tbUserName.Text.Trim();
//调用SendMessage方法设置其内容
SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, text);
retval ++;
}

//得到Password这个子窗体,并设置其内容
EdithWnd = FindWindowEx(ParenthWnd,EdithWnd,lpszClass,"");
if (!EdithWnd.Equals(IntPtr.Zero))
{
text = this.tbPassword.Text.Trim();
SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, text);
retval ++;
}

//得到Domain这个子窗体,并设置其内容
EdithWnd = FindWindowEx(ParenthWnd,EdithWnd,lpszClass,"");
if (!EdithWnd.Equals(IntPtr.Zero))
{
text = this.tbDomain.Text.Trim();
SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, text);
retval ++;
}

//得到Button这个子窗体,并触发它的Click事件
EdithWnd = FindWindowEx(ParenthWnd,
EdithWnd,lpszClass_Submit,lpszName_Submit);
if (!EdithWnd.Equals(IntPtr.Zero))
{
SendMessage(EdithWnd,WM_CLICK,(IntPtr)0,"0");
retval ++;
}
}

return retval;
}
里面有调用API给窗口textbox赋值的方法,很详细,有问题再咨询我