我想做一个QQ自动登陆,使用的QQ是2009.现在先模拟打开QQ,然后通过api调用回调函数。回调函数为一个委托方法,但是在方法中整个参数乱码,请问如何解决?
具体流程为,启动QQ,获取当前启动QQ的句柄,通过EnumChildWindows方法回调方法,但是在EnumWindowsProc中,account和pwd乱码。请问如何解决?
public
delegate
bool
CallBack(IntPtr hwnd,
int
lParam,
string
account,
string
pwd );
[DllImport(
"user32.dll"
, CharSet = CharSet.Auto, SetLastError =
true
)]
static
extern
IntPtr EnumChildWindows(IntPtr hWndParent, CallBack lpEnumFunc,
int
lParam);
/// <summary>
/// QQ登录
/// </summary>
public
static
void
LoginIn(
string
account =
"123456"
,
string
pwd =
"123456"
)
{
//启动QQ程序
StartCmd();
IntPtr h;
string
strName =
"QQ2009"
;
h = FindWindow(
null
, strName);
if
(h.ToInt32() != 0)
{
MoveWindow(h, 0, 0, 350, 300,
true
);
CallBack myCallBack =
new
CallBack(EnumWindowsProc);
EnumChildWindows(h, myCallBack, 0);
}
}
/// <summary>
///将鼠标移动到登陆按钮
/// </summary>
/// <param name="h"></param>
/// <param name="lParam"></param>
/// <returns></returns>
private
static
bool
EnumWindowsProc(IntPtr h,
int
lParam,
string
account,
string
pwd)
{
//改变账号
SetCursorPos(900, 530);
SetForegroundWindow(h);
SendMessage(h, 0x000C, IntPtr.Zero, account.ToString());
//移动鼠标到登陆按钮
SetCursorPos(1090, 645);
SetForegroundWindow(h);
mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
return
false
;
}
Callback只有两个参数
/// Return Type: BOOL->int ///param0: HWND->HWND__* ///param1: LPARAM->LONG_PTR->int [System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute(System.Runtime.InteropServices.CallingConvention.StdCall)] public delegate int WNDENUMPROC(System.IntPtr param0, System.IntPtr param1); [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] public struct HWND__ { /// int public int unused; } public partial class NativeMethods { /// Return Type: BOOL->int ///hWndParent: HWND->HWND__* ///lpEnumFunc: WNDENUMPROC ///lParam: LPARAM->LONG_PTR->int [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint="EnumChildWindows")] [return: System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] public static extern bool EnumChildWindows([System.Runtime.InteropServices.InAttribute()] System.IntPtr hWndParent, WNDENUMPROC lpEnumFunc, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.SysInt)] int lParam) ; }
能麻烦你一下嘛,把我的方法改造一下,你的意思还是不太明白。api我是第一次接触。谢谢!
现在我同时要传入账号和密码两个参数。麻烦了,谢谢!
@瀞默:
首先,修改如下,注意将lParam是IntPtr类型
public delegate bool EnumWinProc(IntPtr hwnd, IntPtr lParam); [DllImport("user32.Dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool EnumChildWindows(IntPtr parentHandle, EnumWinProc callback, IntPtr lParam);
然后,定义结构体UserData
public struct UserData { public string Accout; public string Password; }
然后,修改调用,将结构数据Marshal成IntPtr,通过lParam传递到回调中
/// <summary> /// QQ登录 /// </summary> public static void LoginIn(string account = "123456", string pwd = "123456") { //启动QQ程序 StartCmd(); IntPtr h; string strName = "QQ2009"; h = FindWindow(null, strName); if (h.ToInt32() != 0) { MoveWindow(h, 0, 0, 350, 300, true); CallBack myCallBack = new CallBack(EnumWindowsProc); UserData userData; userData.Account = account; userData.Password = pwd; IntPtr pUserData = Marshal.AllocHGlobal(Marshal.Sizeof(typeof(UserData))); Marshal.StructureToPtr(userData,pUserData,false); EnumChildWindows(h, myCallBack, pUserData); Marshal.FreeHGlobal(pUserData); } }
再然后,修改回调,通过lParam获取到Marshal过来的结构数据,如下所示:
/// <summary> ///将鼠标移动到登陆按钮 /// </summary> /// <param name="h"></param> /// <param name="lParam"></param> /// <returns></returns> private static bool EnumWindowsProc(IntPtr h, IntPtr lParam) { //此处获取传递的数据 UserData userData=(UserData)Marshal.PtrToStructure(lParam,typeof(UserData)); //改变账号 SetCursorPos(900, 530); SetForegroundWindow(h); SendMessage(h, 0x000C, IntPtr.Zero, userData.Account.ToString()); //移动鼠标到登陆按钮 SetCursorPos(1090, 645); SetForegroundWindow(h); mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); return false; }
注意以上代码不是在IDE中编写的,所以可能会有手误,请多包涵!
@jello chen: 谢谢了,十分感谢!