技术员博客      html  css  js  c++  java
  • QQ登陆功能的实现2 rolends1986 博客园

    QQ登陆功能的实现2 - rolends1986 - 博客园

    QQ登陆功能的实现2

    由于看到园子里有朋友说需要讲解和剖析实现的步骤,前面的QQ登陆实现只有代码,所以这篇补上

    1. 分析

    1). 当运行QQ.exe后会出现qq登陆界面的窗体
    image

    2). 我们用spy++分析窗体可以看到窗体有2个子控件,一个是账号输入框,一个密码框
    image

    3). 再用spy++做事件分析,让spy++挂载hook后点解登陆按钮可以发现,按钮点击的坐标
    image

    2. 上面我们详细分析了登陆过程的操作步骤需要的信息,现在来实现

    1). 首先运行QQ,使用 Process pro = Process.Start(qqPath);这个方法来运行QQ

    2). 然后我们需要找到登陆窗体的句柄,需要EnumDesktopWindows这个API来实现
    函数原型BOOL WINAPI EnumDesktopWindows(

    __in_opt HDESK hDesktop,

    __in WNDENUMPROC lpfn,

    __in LPARAM lParam

    );
    大家都知道.net调用API比较烦,那么我们需要一个工具来简化我们的操作,在这里推荐2个工具,pinvoke.net(http://www.pinvoke.net/)和P/Invoke Interop Assistant(http://clrinterop.codeplex.com/)后者是一个开源项目,个人来说喜欢前者一些,工具很简单一看就会,就不讲解了,接上

    我们需要EnumDesktopWindows来找到登陆窗体,这个api 的声明如下
    public delegate bool EnumDesktopWindowsDelegate(IntPtr hWnd, uint lParam);
    [DllImport("user32.dll", EntryPoint = "EnumDesktopWindows", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]

    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDesktopWindowsDelegate lpEnumCallbackFunction, IntPtr lParam);
    使用这个API,然后根据pid就可以找到登陆窗口了

    3). 找到登陆窗口之后我们需要找到登陆窗口里面的控件,这过程我们需要使用另一个API就是EnumChildWindows,函数原型:
    BOOL EnumChildWindows(
    HWND hWndParent,
    WNDENUMPROC lpEnumFunc,
    LPARAM lParam);
    .net API声明
    [DllImport("user32.Dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool EnumChildWindows(IntPtr parentHandle, EnumChildWindowsDelegate callback, IntPtr lParam);
    public delegate bool EnumChildWindowsDelegate(IntPtr hwnd, IntPtr lParam);
    找控件方法如下

     public static List<IntPtr> FindControl(IntPtr hwnd, string className, string title = null)
     {
                List<IntPtr> controls = new List<IntPtr>();
                IntPtr handle = IntPtr.Zero;
                while (true)
                {
                    IntPtr tmp = handle;
                    handle = WinAPIHelper.FindWindowEx(hwnd, tmp, className, title);
                    if (handle != IntPtr.Zero)
                    {
                        controls.Add(handle);
                    }
                    else
                        break;
                }
                return controls;
      }

    4). 经过上面我们找到2个子控件,现在需要为2个子控件设置值,对于一般的文本框我们可以用SETText消息来实现,对于特殊的输入框,我们只能模拟按键实现

    首先设置QQ号码WinAPIHelper.SendMessage(cons[0], WinAPIHelper.WM_SETTEXT, IntPtr.Zero, new StringBuilder(mainQQ)),其中cons[0]为输入框的句柄,这样就输入了QQ号码,输入密码需要以下步骤

    A)窗体置顶,b)窗体获取焦点,c)输入控件获取焦点,d)发送按键
    WinAPIHelper.BringWindowToTop(hLogonWnd)
    ,使用BringWindowToTop这个API来实现置顶,WinAPIHelper.SetForegroundWindow(hLogonWnd)使用SetForegroundWindow这个API来实现获取焦点,WinAPIHelper.SendMessage(cons[0], WinAPIHelper.WM_SETFOCUS, 0x001a0494, 0)使用SETFocus来设置控件焦点,SendKeys.SendWait(mainQQPwd)这个类来实现密码输入模拟

    5). 经过上面步骤我们实现信息的输入,现在我们需要点解按钮
    通过spy我们的到了按钮的坐标信息,关于点击的实现参照http://www.cnblogs.com/Rolends/archive/2012/04/18/2454964.html

    6). 登陆操作过程完成,接下来就等待登陆结果,我们需要使用EnumDesktopWindows不断的来获取窗体进行辨别

    word里写还是不行,发出来乱完了

    QQ 讨论组广告群发工具(已开发完成)索引

  • 相关阅读:
    WIN7,server2008 IIS 伪静态 不能显示特殊图片 加号 减号 “+”,""号的图片需要转义才可以显示 狼人:
    Java内存结构学习总结
    Java theory and practice: Dealing with InterruptedException 规格严格
    谈移动互联网开发的数据分析和决策思路
    mysql/sqlserver where in 传参数的问题
    StringSearch 规格严格
    C++中的XML配置文件编程经验
    RichTextBox
    王建军_百度百科
    Packaging a Qt application
  • 原文地址:https://www.cnblogs.com/lexus/p/2458629.html
Copyright © 2011-2022 技术员博客