C# Find the handle of the child window of the specified window

API functions need to be called

Need to introduce namespace
using System.Runtime.InteropServices at the beginning;

Get the current window handle: GetForegroundWindow()

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern IntPtr GetForegroundWindow();

The return value type is IntPtr, which is the handle of the currently focused window

Usage: IntPtr myPtr=GetForegroundWindow();

After getting the window handle, you can operate on the window. For example, close the window or make it display after the window is hidden

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int ShowWindow(IntPtr hwnd, int nCmdShow);

其中ShowWindow(IntPtr hwnd, int nCmdShow);

Meaning of nCmdShow

0 close the window

1 Normal size display window

2 Minimize the window

3 Maximize the window

Example of use: ShowWindow(myPtr, 0);

Get the window size and position: you need to call the method GetWindowRect(IntPtr hWnd, ref RECT lpRect)

        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int Left; //the leftmost coordinate
            public int Top; //the uppermost coordinate
            public int Right; //the rightmost coordinate
            public int Bottom; //the lowermost coordinate
        }

Example:

                    InPtr awin = GetForegroundWindow(); //Get the current window handle
                    RECT rect = new RECT();
                    GetWindowRect(awin, ref rect);
                   int width = rc.Right - rc.Left; //Window width
                   int height = rc. Bottom - rc.Top; //height of the window
                    int x = rc.Left;                                             
                    int y = rc.Top;

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

FindWindow in C#
  [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint="FindWindow")]
  public static extern int FindWindow (
            string lpClassName,
            string lpWindowName
           ); Knowing the
window title "abc", how to get the window handle? 

IntPtr hWnd = FindWindow(null, "abc");

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

C# uses the FindWindow() function:

            [DllImport("coredll.dll", EntryPoint = "FindWindow")]
            private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
        This function has two parameters, the first is the class of the window to be found, the second is the title of the window to be found. You don't necessarily know both when searching, but at least one of them should be known. The title of some windows is easy to get, such as "Calculator", so you should use the title to search. However, the title of some software is not fixed, such as "Notepad", if the opened file is different, the window title is also different, then it is more convenient to use the window type search. If a window that satisfies the condition is found, this function returns the handle of the window, otherwise it returns 0. see example

           IntPtr ParenthWnd = new IntPtr(0);

            ParenthWnd = FindWindow(null,"Word Mobile");
            //Determine whether this form is valid 
            if (ParenthWnd != IntPtr.Zero)
            {
                MessageBox.Show("Find the window");
            }

            else

                MessageBox.Show("No window found");

        As can be seen from the above discussion, if the window title of the external program to be searched is easier to obtain, the problem is relatively simple. But if the title of the window is not fixed or has no title at all, how to get the class of the window? If you have Visual C++ installed, you can use Spy in it, in Spy++ there is a FindWindow tool that allows you to select a window with the mouse, then Spy++ will show the class of that window.
    There is also a FindWindowEx in the Win32 API which is great for finding child windows.

 

FindWindowEx usage 
 function Function: This function obtains the handle of a window whose class name and window name match the given string. This function finds child windows, starting with the next child window in the row after the given child window. It is not case sensitive when looking for it.

    函数原型:HWND FindWindowEx(HWND hwndParent,HWND hwndChildAfter,LPCTSTR lpszClass,LPCTSTR lpszWindow);

    parameter:

    hwndParent: The parent window handle to find the child window.

    If hwnjParent is NULL, the function takes the desktop window as the parent window and finds all child windows of the desktop window.

    Windows NT5.0 and later: If hwndParent is HWND_MESSAGE, the function just finds all message windows.

    hwndChildAfter : Child window handle. The search starts from the next subwindow in the Z order. The child window must be a direct child window of the hwndPareRt window and not a descendant window. If HwndChildAfter is NULL, the search starts from the first child window of hwndParent. If both hwndParent and hwndChildAfter are NULL, the function finds all top-level windows and message windows.

    lpszClass: Pointer to a null-terminated string specifying a class name, or a pointer to a member identifying the class name string. If the parameter is a member, it must be the global member produced by the previous call to theGlobaIAddAtom function. This member is 16 bits and must be located in the low 16 bits of lpClassName, and the high bit must be 0.

    lpszWindow: Points to a null-terminated string specifying the window name (window title). If this parameter is NULL, all windows are matched. Return value: If the function succeeds, the return value is the window handle with the specified class name and window name. If the function fails, the return value is NULL.

To use this function in C#, first import the namespace:

 
01.using System.Runtime.InteropServices;  
 

Then write the code of the API reference part and put it inside the class

 

 
01.[DllImport("user32.dll", EntryPoint = "FindWindow")]  
02.private static extern IntPtr FindWindowEx( IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow )
 

E.g:

 

 
01.const int BM_CLICK = 0xF5;  
02.IntPtr maindHwnd = FindWindow(null, "QQ user login"); //Get the handle of the QQ login box  
03.if (maindHwnd != IntPtr.Zero)  
04.{  
05. IntPtr childHwnd = FindWindowEx(maindHwnd, IntPtr.Zero, null, "Login"); //Get the handle of the button 
06. if (childHwnd != IntPtr.Zero)  
07. {  
08. SendMessage(childHwnd, BM_CLICK, 0, 0); / /Send a button clicked message  
09. }  
10. else  
11. {  
12. MessageBox.Show("Not found child window");  
13. }  
14.}  
15.else  
16.{  
17. MessageBox.Show("Not found window");  
18.}   
 


 Learn from the network  http://item.congci.com/item/findwindowfindwindowex

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

DllImport("user32", SetLastError = true)] 
public static extern int GetWindowText( 
    IntPtr hWnd,//Window handle 
    StringBuilder lpString,//Title 
    int nMaxCount //Maximum value 
    );

//Get the name of the class 
[DllImport("user32.dll")] 
private static extern int GetClassName( 
    IntPtr hWnd,//Handle 
    StringBuilder lpString, //Class name 
    int nMaxCount //Maximum value 
    );

//Get the window handle according to the coordinates 
[DllImport("user32")] 
private static extern IntPtr WindowFromPoint( 
Point Point //coordinates 
);

 

private void timer1_Tick(object sender, EventArgs e) 

    int x = Cursor.Position.X; 
    int y = Cursor.Position.Y; 
    Point p = new Point(x, y); 
    IntPtr formHandle = WindowFromPoint(p);// Get the window handle 
    StringBuilder title = new StringBuilder(256); 
    GetWindowText(formHandle, title, title.Capacity);//Get the title of the window 
    StringBuilder className = new StringBuilder(256); 
    GetClassName(formHandle, className, className.Capacity);/ / get the handle of the window 
    this.textBox1.Text = title.ToString(); 
    this.textBox2.Text = formHandle.ToString(); 
    this.textBox3.Text = className.ToString(); 
}


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

 

The article is good, the collection is spare.

设计初衷:
  公司为了安全性考虑,不让密码被太多人知道,所以想实现一个自动登录的模块。

设计思想: 
  主要是通过调用Windows API中的一些方法,找到目标窗口和进程之后把保存在数据库中的用户名密码自动填入输入框中,并登录。

设计步骤:
一、调用Windows API。
 C#下调用Windows API方法如下:
 1、引入命名空间:using System.Runtime.InteropServices;
 2、引用需要使用的方法,格式:[DllImport("DLL文件")]方法的声明;
 [DllImport("user32.dll")]private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
 [DllImport("user32.dll")]private static extern bool SetForegroundWindow(IntPtr hWnd);
 [DllImport("user32.dll")]private static extern IntPtr FindWindow(string lpClassName,string lpWindowName);
 [DllImport("user32.dll")]private static extern int SendMessage(IntPtr hWnd,int Msg,int wParam,int lParam);
 [DllImport("user32.dll")]private static extern bool SetCursorPos(int X, int Y);
 [DllImport("user32.dll")]private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
 [DllImport("user32.dll")]private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
  [DllImport("user32.dll")]private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndlnsertAfter, int X, int Y, int cx, int cy, uint Flags); 
 //ShowWindow参数
 private const int SW_SHOWNORMAL = 1;
 private const int SW_RESTORE = 9;
 private const int SW_SHOWNOACTIVATE = 4;
 //SendMessage参数
 private const int WM_KEYDOWN = 0X100;
 private const int WM_KEYUP = 0X101;
 private const int WM_SYSCHAR = 0X106;
 private const int WM_SYSKEYUP = 0X105;
 private const int WM_SYSKEYDOWN = 0X104;
 private const int WM_CHAR = 0X102;

二、找到目标窗口
1)、根据窗口的标题得到句柄
 IntPtr myIntPtr = FindWindow(null,"窗口名"); //null为类名,可以用Spy++得到,也可以为空
 ShowWindow(myIntPtr, SW_RESTORE); //将窗口还原
 SetForegroundWindow(myIntPtr); //如果没有ShowWindow,此方法不能设置最小化的窗口
2)、遍历所有窗口得到句柄
1 定义委托方法CallBack,枚举窗口API(EnumWindows),得到窗口名API(GetWindowTextW)和得到窗口类名API(GetClassNameW)
 public delegate bool CallBack(int hwnd, int lParam);
 [DllImport("user32")]public static extern int EnumWindows(CallBack x, int y);
  [DllImport("user32.dll")]private static extern int GetWindowTextW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
 [DllImport("user32.dll")]private static extern int GetClassNameW(IntPtr hWnd, [MarshalAs(UnmanagedType.LPWStr)]StringBuilder lpString, int nMaxCount);
2 调用EnumWindows遍历窗口
 CallBack myCallBack = new CallBack(Recall);
 EnumWindows(myCallBack, 0);
3 回调方法Recall
 public bool Recall(int hwnd, int lParam)
 {
  StringBuilder sb = new StringBuilder(256);
  IntPtr PW = new IntPtr(hwnd);

  GetWindowTextW(PW,sb,sb.Capacity); //得到窗口名并保存在strName中
  string strName = sb.ToString();

  GetClassNameW(PW,sb,sb.Capacity); //得到窗口类名并保存在strClass中
  string strClass = sb.ToString();

  if (strName.IndexOf("窗口名关键字") >= 0 && strClass.IndexOf("类名关键字") >= 0)
  {
   return false; //返回false中止EnumWindows遍历
  }
  else
  {
   return true; //返回true继续EnumWindows遍历
  }
 }
3)、打开窗口得到句柄
1 定义设置活动窗口API(SetActiveWindow),设置前台窗口API(SetForegroundWindow)
 [DllImport("user32.dll")]static extern IntPtr SetActiveWindow(IntPtr hWnd);
 [DllImport("user32.dll")][return: MarshalAs(UnmanagedType.Bool)]static extern bool SetForegroundWindow(IntPtr hWnd);
2 打开窗口
 Process proc = Process.Start(@"目标程序路径");
 SetActiveWindow(proc.MainWindowHandle);
 SetForegroundWindow(proc.MainWindowHandle);

三、向指定的窗口输入数据
1 利用发送消息API(SendMessage)向窗口发送数据
 InputStr(myIntPtr, _GameID); //输入游戏ID
 SendMessage(myIntPtr, WM_SYSKEYDOWN, 0X09, 0); //输入TAB(0x09)
 SendMessage(myIntPtr, WM_SYSKEYUP, 0X09, 0);
 InputStr(myIntPtr, _GamePass); //输入游戏密码
 SendMessage(myIntPtr, WM_SYSKEYDOWN, 0X0D, 0); //输入ENTER(0x0d)
 SendMessage(myIntPtr, WM_SYSKEYUP, 0X0D, 0);

 /// <summary>
 /// 发送一个字符串
 /// </summary>
 /// <param name="myIntPtr">窗口句柄</param>
 /// <param name="Input">字符串</param>
 public void InputStr(IntPtr myIntPtr, string Input)
 {
  byte[] ch = (ASCIIEncoding.ASCII.GetBytes(Input));
  for (int i = 0; i < ch.Length; i++)
  { 
   SendMessage(PW, WM_CHAR, ch, 0);
  }
 }
2 利用鼠标和键盘模拟向窗口发送数据
 SetWindowPos(PW, (IntPtr)(-1), 0, 0, 0, 0, 0x0040 | 0x0001); //设置窗口位置
 SetCursorPos(476, 177); //设置鼠标位置
 mouse_event(0x0002, 0, 0, 0, 0); //模拟鼠标按下操作
 mouse_event(0x0004, 0, 0, 0, 0); //模拟鼠标放开操作
 SendKeys.Send(_GameID);   //模拟键盘输入游戏ID
 SendKeys.Send("{TAB}"); //模拟键盘输入TAB
 SendKeys.Send(_GamePass); //模拟键盘输入游戏密码
 SendKeys.Send("{ENTER}"); //模拟键盘输入ENTER

另:上面还提到了keybd_event方法,用法和mouse_event方法类似,作用和SendKeys.Send一样。

C# 别人软件里边做好的文本框,我如何给他赋值并且提交,最好有源码可供参考,如有合适的,将高额追加分
可以用WINDOWS api函数实现。
下面的WINDIWS API引用部分的代码,放入 class 内部

[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 );// 设置窗口为激活状态

哈哈,现在可以开工了。我就用QQ的自动登录为列子
下面是你winfrom窗口的按钮事件:
private void button1_Click( object sender, EventArgs e )
{
const uint WM_SETTEXT = 0x000C;//设置文本框内容的消息
const uint BM_CLICK = 0xF5; //鼠标点击的消息,对于各种消息的数值,你还是得去查查API手册
IntPtr hwndCalc = FindWindow ( null, "QQ2011" ); //查找QQ2011的窗口句柄
if ( hwndCalc != IntPtr.Zero )//找到啦
{
IntPtr hwndLogin= FindWindowEx ( hwndCalc, 0, null, "安全登录" ); //获取登陆按钮的句柄
IntPtr hwndQ = FindWindowEx ( hwndCalc, 0, “ComboBox”, "" );  //获取QQ号码输入框的控件句柄
IntPtr hwndP = FindWindowEx ( hwndCalc, 0,"Edit", “” );  //获取密码输入框的控件句柄 SetForegroundWindow ( hwndCalc );    //将QQ窗口设置为激活
System.Threading.Thread.Sleep ( 1000 );   //暂停1秒让你看到效果
SendMessage ( hwndQ, WM_SETTEXT, TextBox1.Text, 0 );//发送文本框1里面的内容(QQ号啦)
System.Threading.Thread.Sleep ( 1000 );   //暂停1秒让你看到效果
SendMessage( hwndP, WM_SETTEXT, TextBox2.Text, 0 );//发送文本框2里面的内容(QQpassword)

System.Threading.Thread.Sleep ( 1000);   //暂停1秒让你看到效果
SendMessage ( hwndLogin, BM_CLICK, 0, 0 );//点击登录
}
else
{
MessageBox.Show ("没有启动 [QQ2011]");
}
}

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

C#查找指定窗口的子窗口的句柄

2009年更新
通过实验得知,FindWindowEx可以通过classname或caption(也就是窗口的title)查找窗口,且如果第一个参数传IntPtr.Zero的话,将从Windows最顶层窗口开始查找,但是窗口很多的话这样会非常的慢,所以加入Timeout的判断,如果超时还没找到,返回false。

用法:FindWindow fw = new FindWindow(IntPtr.Zero, null, "ThunderDFrame", 10);//查找Title为ThunderDFrame的窗口,如果10秒内还没找到,返回false

代码如下:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace Util
{
    class FindWindow
    {
        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        //IMPORTANT : LPARAM  must be a pointer (InterPtr) in VS2005, otherwise an exception will be thrown
        private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
        //the callback function for the EnumChildWindows
        private delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

        //if found  return the handle , otherwise return IntPtr.Zero
        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);

        private string m_classname; // class name to look for
        private string m_caption; // caption name to look for

        private DateTime start;
        private int m_timeout;//If exceed the time. Indicate no windows found.

        private IntPtr m_hWnd; // HWND if found
        public IntPtr FoundHandle
        {
            get { return m_hWnd; }
        }

        private bool m_IsTimeOut;
        public bool IsTimeOut
        {
            get{return m_IsTimeOut;}
            set { m_IsTimeOut = value; }
        }

        // ctor does the work--just instantiate and go
        public FindWindow(IntPtr hwndParent, string classname, string caption, int timeout)
        {
            m_hWnd = IntPtr.Zero;
            m_classname = classname;
            m_caption = caption;
            m_timeout = timeout;
            start = DateTime.Now;
            FindChildClassHwnd(hwndParent, IntPtr.Zero);
        }

        /**/
        /// <summary>
        /// Find the child window, if found m_classname will be assigned 
        /// </summary>
        /// <param name="hwndParent">parent's handle</param>
        /// <param name="lParam">the application value, nonuse</param>
        /// <returns>found or not found</returns>
        //The C++ code is that  lParam is the instance of FindWindow class , if found assign the instance's m_hWnd
        private bool FindChildClassHwnd(IntPtr hwndParent, IntPtr lParam)
        {
            EnumWindowProc childProc = new EnumWindowProc(FindChildClassHwnd);
            IntPtr hwnd = FindWindowEx(hwndParent, IntPtr.Zero, m_classname, m_caption);
            if (hwnd != IntPtr.Zero)
            {
                this.m_hWnd = hwnd; // found: save it
                m_IsTimeOut = false;
                return false; // stop enumerating
            }

            DateTime end = DateTime.Now;

            if (start.AddSeconds(m_timeout) < end)
            {
                m_IsTimeOut = true;
                return false;
            }

            EnumChildWindows(hwndParent, childProc, IntPtr.Zero); // recurse  redo FindChildClassHwnd
            return true;// keep looking
        }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325152742&siteId=291194637