现需要捕获天翼通无线上网客户端
通过System.Diagnostics.Process.Start()启动并取得窗体句柄
但是不知道如何去模仿鼠标点击里面的自动连接按钮注:FindWindowEx无效,找不到自动连接按钮的句柄。SPY++分析亦找不到对应的BUTTON
请各位给点意见,有源码更好,谢谢。

解决方案 »

  1.   

    SetForegroundWindow将客户端设为前台窗体,确定自动连接按钮的位置后用mouse_eventhttp://www.cnblogs.com/leafyoung/archive/2007/06/29/799837.html
      

  2.   

    [DllImport ( "user32.dll", EntryPoint = "FindWindow", SetLastError = true )]
    private static extern IntPtr FindWindow( string lpClassName, string lpWindowName );
    [DllImport ( "user32.dll", EntryPoint = "FindWindowEx", SetLastError = true )]
    private static extern IntPtr FindWindowEx( IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow );
    [DllImport ( "user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto )]
    private static extern int SendMessage( IntPtr hwnd, uint wMsg, int wParam, int lParam );
    [DllImport ( "user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true )]
    private static extern void SetForegroundWindow( IntPtr hwnd )
    const uint BM_CLICK = 0xF5;  
      IntPtr hwndC= FindWindow ( null, "" );  
      if ( hwndC!= IntPtr.Zero )
      {
      IntPtr hwnd = FindWindowEx ( hwndC, 0, null, "1" );  
      SetForegroundWindow ( hwndC );   
      SendMessage (hwnd , BM_CLICK, 0, 0 );
      }
      

  3.   

    谢谢1楼和2楼及时的回答1楼是完全模仿鼠标机械点击,不是通过内部消息机制点击,跟我设计不吻合。
    2楼的方法我试过,就是FindWindowEx根本早不到对应的BUTTON,用SPY++也找不到
      

  4.   

    intptr ip = MyApi.FindWindow(null, "目标窗口");  //取得窗口句柄
                int x=25,y=193;//btn坐标
                int xy = (y << 16) + x;
                MyApi.SendMessage(ip, MOUSEEVENTF_LEFTDOWN, 0, xy);
                MyApi.SendMessage(ip, MOUSEEVENTF_LEFTUP, 0, xy);
      

  5.   

    用API是完全可以搞定的,只不过2楼的调用方法中,参数写的不正确。正确使用就可以了。
      

  6.   


    谢谢你的回复。不过,SENDMESSAGE无效啊
      

  7.   

    SPY++分析亦找不到对应的BUTTON,按钮可能是别人画出来的
    用SPY++的日志消息监视你点击按钮时出现了哪些消息,最后直接模拟消息
      

  8.   

    如果spy++真找不到句柄。
    那么就是那个按钮。不是一个控件,
    需要用别的方法了。比如钩子。
      

  9.   

     ///API函数类
      public class WinAPI
        {
            [DllImport("user32.dll")]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
            [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
            public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
            [DllImport("User32.dll", EntryPoint = "SendMessage")]
            public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
           [DllImport("user32.dll")]
            public static extern IntPtr SetActiveWindow(IntPtr hWnd);
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool SetForegroundWindow(IntPtr hWnd);
         }
    ///调用
     假定被启动的窗体(窗体text内容):flash
        窗体按纽(按纽text内容):begin
    首先启动那个窗体程序,然后执行下面程序:
       const int WM_CLICK = 0x00F5; 
       IntPtr window;
       while (true)  //循环抓取,抓到为止
         {
           window = WinAPI.FindWindow(null, "flash");
           if (window.ToInt32() != 0)
           {
             break;
           }
         }
        WinAPI.SetActiveWindow(window);  //激活抓到的窗体
        WinAPI.SetForegroundWindow(window);  //设置该窗体为顶层窗体
    //抓按纽,并发送点击命令
         IntPtr EdithWnd = new IntPtr(0);
        EdithWnd = WinAPI.FindWindowEx(window, EdithWnd, "Button", "begin");
       if (!EdithWnd.Equals(IntPtr.Zero))
        {
           WinAPI.SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
        }
    这里按纽text内容"begin",如果第一个字母b下有下滑线,你可以写成"&begin"。              
      

  10.   

    谢谢楼上的
    窗体句柄可以找到,但找不到按钮句柄FindWindowEx无效。
      

  11.   


    /*
    某些控件是直接绘制出来的,不是一个单独控件
    找不到句柄的话,说明这个控件根本就没有句柄
    这里你可以找到按钮所在位置 
    然后去发送WM_LBUTTONDOWN WM_LBUTTONUP(即使你的目标程序不在最顶端也可以发送有效的)
    */
    PostMessage(hwnd,WM_LBUTTONDOWN,MK_LBUTTON,MAKELPARAM(x,y));
    PostMessage(hwnd,WM_LBUTTONUP,0,MAKELPARAM(x,y)));
      

  12.   

    我上面的代码里的hwnd句柄 是你的按钮父窗体的句柄
      

  13.   

     [DllImport("KERNEL32.DLL ")]
            public static extern IntPtr CreateToolhelp32Snapshot(uint flags, uint processid);
            [DllImport("KERNEL32.DLL ")]
            public static extern int CloseHandle(IntPtr handle);
            [DllImport("KERNEL32.DLL ")]
            public static extern int Process32First(IntPtr handle, ref   ProcessEntry32 pe);
            [DllImport("KERNEL32.DLL ")]
            public static extern int Process32Next(IntPtr handle, ref   ProcessEntry32 pe);
            [DllImport("KERNEL32.DLL ")]
            public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
            [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
            private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
            [DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
            private static extern IntPtr FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow);
            [DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
            private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);
            [DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
            private static extern void SetForegroundWindow(IntPtr hwnd);        public delegate bool CallBack(IntPtr hwnd, int lParam);
            [DllImport("user32.dll")]
            public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);        [DllImport("user32.dll", EntryPoint = "GetWindowText")]
            public static extern int GetWindowText(IntPtr hwnd,StringBuilder lpString,int cch);
            [DllImport("user32.dll ", EntryPoint = "GetDlgItem")]
            public static extern IntPtr GetDlgItem(IntPtr hParent, int nIDParentItem);
            [DllImport("user32.dll")]
            public static extern uint GetWindowThreadProcessId(IntPtr hWnd,out uint dwProcessId);
            [DllImport("kernel32.dll")]
            public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,uint dwSize, uint flAllocationType, uint flProtect);        [DllImport("kernel32.dll")]
            public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress,uint dwSize, uint dwFreeType);        [DllImport("kernel32.dll")]
            public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);
    以上API全部试过,均无效果
      

  14.   

    这个也许有用吧:
    http://msdn.microsoft.com/zh-cn/library/aa686045.aspx
      

  15.   


    System.Diagnostics.Process wc = System.Diagnostics.Process.Start(@"D:\Chinatelecom C+W\C+WClient.exe");
    System.Threading.Thread.Sleep(5000);
    IntPtr hwndCalc = wc.MainWindowHandle; // 等同于FindWindow窗体句柄已经活得,无奈里面的BUTTON句柄无法获取
    SPY++也找不到相关按钮
    如果用模仿鼠标点击的话,位置必须得固定。(多系统多显示器下很难控制这点)所以此举不可取
      

  16.   


    不好意思,文章只是介绍 P/Invoke 编程,系统API调用。
      

  17.   

    这个有什么不可取?
    你找到form的坐标 然后 加上你的按钮的相对位置就是它的坐标了
      

  18.   

    找窗口容易,枚举所有窗口,找到对应进程名,然后再根据classname或WindowText筛选,就可以确定是哪个窗口.然后根据窗体左上角坐标偏移,就可以找到单击或双击位置,然后模拟鼠标单击。这个方法我做过很多遍,绝对可行。鼠标单击就用API:mouseevent,绝对有效,2000\XP\WIN7都没问题。