C# API 应用(根据句柄,实现向另一应用程序登录窗体实现登录) 收藏
//一个引用
using System.Runtime.InteropServices;
//一些定义,放在例如public partial class Form1 : Form下
const int WM_GETTEXT = 0x000D;
const int WM_SETTEXT = 0x000C;
const int WM_CLICK = 0x00F5;
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
//下面的例子是针对一个弹出式web登录界面,你要用spy++找出你的登录窗口里的相关控件
void PopLogin()
{
tsslStatus.Text = "准备在弹出窗口登录......";
int retval = 0; //增加一个返回值用来判断操作是否成功
//下面的这些参数都可以用Spy++查到
string lpszParentClass = "#32770"; //整个窗口的类名
string lpszParentWindow = strWndName; //窗口标题
//string lpszClass = "Edit"; //需要查找的子窗口的类名,也就是输入框
string lpszClass_Submit = "Button"; //需要查找的Button的类名
string lpszName_Submit = "确定"; //需要查找的Button的标题
string text = "";
IntPtr ParenthWnd = new IntPtr(0);
IntPtr EdithWnd = new IntPtr(0);
IntPtr ip = new IntPtr(0);
//查到窗体,得到整个窗体
ParenthWnd = FindWindow(lpszParentClass, lpszParentWindow);
//等待5秒
int iSecCnt = 1;
while (ParenthWnd == IntPtr.Zero)
{
if (iSecCnt > 5) return;
tsslStatus.Text = "尝试登录......"+iSecCnt.ToString();
Thread.Sleep(1000);
ParenthWnd = FindWindow(lpszParentClass, lpszParentWindow);
iSecCnt++;
}
//判断这个窗体是否有效
if (!ParenthWnd.Equals(IntPtr.Zero))
{
EdithWnd = FindWindowEx(ParenthWnd, new IntPtr(0), "Edit", "");
//得到User Name这个子窗体,并设置其内容
EdithWnd = FindWindowEx(ParenthWnd, EdithWnd, "SysCredential", "");
if (!EdithWnd.Equals(IntPtr.Zero))
{
//MessageBox.Show("sc");
ip = EdithWnd;
//得到Password这个子窗体,并设置其内容
EdithWnd = FindWindowEx(ip, new IntPtr(0), "Edit", "");
if (!EdithWnd.Equals(IntPtr.Zero))
{
text = strGPwd;
SendMessage(EdithWnd, WM_SETTEXT, (IntPtr)0, text);
retval++;
}
EdithWnd = FindWindowEx(ip, new IntPtr(0), "ComboBoxEx32", "");
if (!EdithWnd.Equals(IntPtr.Zero))
{
//MessageBox.Show("cbe");
ip = EdithWnd;
EdithWnd = FindWindowEx(ip, new IntPtr(0), "ComboBox", "");
if (!EdithWnd.Equals(IntPtr.Zero))
{
//MessageBox.Show("cb");
ip = EdithWnd;
EdithWnd = FindWindowEx(ip, new IntPtr(0), "Edit", "");
if (!EdithWnd.Equals(IntPtr.Zero))
{
text = strGAcnt;
//调用SendMessage方法设置其内容
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, new IntPtr(0), lpszClass_Submit, lpszName_Submit);
if (!EdithWnd.Equals(IntPtr.Zero))
{
SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
retval++;
}
}
tsslStatus.Text = "尝试登录已完成。";
//return retval;
}
原出处:http://hi.baidu.com/xiaoxin08/blog/item/dddd8c01736b54df267fb5c8.html
Windows通过句柄(Handle)识别每个窗体、控件、菜单和菜单项,当程序运行时,它所包含的每个部件都有一个惟一确定的句柄同其他的部件相区别句柄在Windows API中具有举足轻重的作用,现举三例,有兴趣的读者不妨一试。
获取窗体和控件的句柄
步骤如下:
1、为了看到显示于屏幕上所有的窗体和控件的句柄,用SetWindowPos函数设置窗口始终在最上面,其他窗口不能覆盖它,并使其只以标题显示于屏幕左上角。
(1)新建一工程,打开API Viwer:Add-ins→API Viewer→File→Load text file→Win32api.txt。
(2)将SetWindowPos函数的声明粘贴到窗体的声明部分:Private Declare Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long。
(3)程序启动时调用SetWindowPos函数,窗体Load事件代码如下:
Private Sub Form_Load()
SetWindowPos Me.hwnd, -1, 0, 0, 0, 0, conSwpNoActivate Or conSwpShowWindow'使窗体一直置于最顶层
End Sub
卧龙传说提醒:当第二个参数hWndInsertAfter的值为-1时置于顶层;值为-2时不置于顶层。
2、为了找到鼠标指针的X和Y坐标,用上面同样的方法,通过API Viewer工具把获取的鼠标指针位置的API函数GetCursorPos的声明和结构类型声明粘贴到窗体的声明部分:
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Type POINTAPI
x As Long
y As Long
3、用API Viewer把指定点的窗口的句柄的API函数WindowFromPointXY的声明粘贴到窗体的声明部分:
Private Declare Function WindowFromPointXY Lib "user32" Alias
"WindowFromPoint" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
4、在窗体上添加timer控件,并把Interval属性设为500(毫秒),用如下的Timer事件完成操作:
Private Sub Timer1_Timer()
Dim xy As POINTAPI'(声明变量类型)
GetCursorPos xy'(取得XY的座标)
ahwnd = WindowFromPointXY(xy.x, xy.y) '(取得当前鼠标坐标下窗口的句柄)
Me.Caption = ahwnd'(在标题栏显示当前坐标下窗口的句柄)
End Sub
获取激活窗口的句柄
用GetFocus函数可获得激活窗口(拥有输入焦点的窗口)的句柄。
1、用API Viewer工具将函数GetFocus的声明粘贴到窗体的声明部分:
Private Declare Function GetFocus Lib "user32" Alias "GetFocus" () As Long
2、新建一工程,添加两个文本框text1和text2,两个文本框控件的GotFocus事件代码如下:
Sub Text1_GotFocus()
h&& = GetFocus&&()
Debug.Print h&&(在立即窗口显示当前窗口句柄)
End Sub
Private Sub Text2_GotFocus()
h&& = GetFocus&&()
Debug.Print h&
End Sub
原出处:http://hi.baidu.com/gdz0703/blog/item/915dd9fb0b8ba7274e4aea2e.html