获取子 window 的句柄以在 C# 中发布消息
Get handle of child window to postmessage in C#
我正在寻找如何获取子 window 的句柄并在那里发送消息。
我的代码:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//This send postmessage to window "192.168.0.94 - Remote Desktop Connection"//
IntPtr hwnd10 = FindWindow(null, "192.168.0.94 - Remote Desktop Connection");
Point location = new Point(636, 324);
PostMessage(hwnd10, WM_MOUSEMOVE, 0, MAKELPARAM(location.X, location.Y));
PostMessage(hwnd10, WM_LBUTTONDOWN, 0x1, MAKELPARAM(location.X, location.Y));
PostMessage(hwnd10, WM_LBUTTONUP, 0, MAKELPARAM(location.X, location.Y));
// But now how can i do the same to child window "Input Capture Window"?
我做了一些研究,我发现 [pageenumchildwindows][1] 但我不知道如何在我的示例中使用它。
截图看看 window 我到底在找什么 :
好的,感谢 Oguz Ozgul,我找到了解决方案。
我是通过 FindWindowEx 完成的,比如 :
IntPtr child = FindWindowEx(hwnd10, IntPtr.Zero, "TscShellAxHostClass", null);
//check if window is caught
if(child!=IntPtr.Zero)
{
Console.WriteLine("Findow TscShellAxHostClass found!!!");
child = FindWindowEx(child, IntPtr.Zero, "ATL:00007FFC92EAF400", null);
if (child != IntPtr.Zero)
{
Console.WriteLine("Findow ATL:00007FFC92EAF400 found!!!");
child = FindWindowEx(child, IntPtr.Zero, "UIMainClass", null);
if (child != IntPtr.Zero)
{
Console.WriteLine("Findow UIMainClass found!!!");
child = FindWindowEx(child, IntPtr.Zero, "UIContainerClass", null);
if (child != IntPtr.Zero)
{
Console.WriteLine("Findow UIContainerClass found!!!");
child = FindWindowEx(child, IntPtr.Zero, "IHWindowClass", null);
if (child != IntPtr.Zero)
{
Console.WriteLine("Findow IHWindowClass found!!!");
}
}
}
}
}
这是另一个实现,使用 EnumWindows
和 EnumChildWindows
。
这个答案并不意味着要被标记,而是展示了解决同一问题的不同方法。
搜索深度为3,可以在代码中增加,甚至可以作为构造函数或方法参数获取。
有效。
public class RecursiveWindowSearcher
{
public delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32")]
public extern static int EnumWindows(EnumWindowsProc lpEnumFunc, int lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
private IntPtr windowParent;
private string windowName;
private IntPtr windowPointer;
public RecursiveWindowSearcher(string windowName, IntPtr windowParent)
{
this.windowName = windowName;
this.windowParent = windowParent;
}
public bool WinApiCallback(IntPtr hwnd, IntPtr lParam)
{
Console.WriteLine("Window: {0}", hwnd);
StringBuilder windowNameFar = new StringBuilder(256);
GetWindowText(hwnd, windowNameFar, 256);
if (windowNameFar.ToString() == windowName)
{
windowPointer = hwnd;
return false;
}
Console.WriteLine("Name: {0}", windowNameFar);
if(indent == 6)
{
return false;
}
indent += 2;
EnumChildWindows(hwnd, WinApiCallback, IntPtr.Zero);
indent -= 2;
return true;
}
public IntPtr Find()
{
this.windowPointer = IntPtr.Zero;
if (windowParent == IntPtr.Zero)
{
EnumWindows(WinApiCallback, 0);
}
else
{
EnumChildWindows(windowParent, WinApiCallback, IntPtr.Zero);
}
return windowPointer;
}
}
而且用法很简单:
第二个构造函数参数是指向现有 window 的指针,从中开始搜索。如果您有此句柄,则可以传递它以将搜索范围缩小到特定的 window 及其子项。
static void Main()
{
IntPtr windowFound = new RecursiveWindowSearcher("Skype for Business ", IntPtr.Zero).Find();
Console.ReadLine();
}
我正在寻找如何获取子 window 的句柄并在那里发送消息。
我的代码:
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
//This send postmessage to window "192.168.0.94 - Remote Desktop Connection"//
IntPtr hwnd10 = FindWindow(null, "192.168.0.94 - Remote Desktop Connection");
Point location = new Point(636, 324);
PostMessage(hwnd10, WM_MOUSEMOVE, 0, MAKELPARAM(location.X, location.Y));
PostMessage(hwnd10, WM_LBUTTONDOWN, 0x1, MAKELPARAM(location.X, location.Y));
PostMessage(hwnd10, WM_LBUTTONUP, 0, MAKELPARAM(location.X, location.Y));
// But now how can i do the same to child window "Input Capture Window"?
我做了一些研究,我发现 [pageenumchildwindows][1] 但我不知道如何在我的示例中使用它。
截图看看 window 我到底在找什么 :
好的,感谢 Oguz Ozgul,我找到了解决方案。 我是通过 FindWindowEx 完成的,比如 :
IntPtr child = FindWindowEx(hwnd10, IntPtr.Zero, "TscShellAxHostClass", null);
//check if window is caught
if(child!=IntPtr.Zero)
{
Console.WriteLine("Findow TscShellAxHostClass found!!!");
child = FindWindowEx(child, IntPtr.Zero, "ATL:00007FFC92EAF400", null);
if (child != IntPtr.Zero)
{
Console.WriteLine("Findow ATL:00007FFC92EAF400 found!!!");
child = FindWindowEx(child, IntPtr.Zero, "UIMainClass", null);
if (child != IntPtr.Zero)
{
Console.WriteLine("Findow UIMainClass found!!!");
child = FindWindowEx(child, IntPtr.Zero, "UIContainerClass", null);
if (child != IntPtr.Zero)
{
Console.WriteLine("Findow UIContainerClass found!!!");
child = FindWindowEx(child, IntPtr.Zero, "IHWindowClass", null);
if (child != IntPtr.Zero)
{
Console.WriteLine("Findow IHWindowClass found!!!");
}
}
}
}
}
这是另一个实现,使用 EnumWindows
和 EnumChildWindows
。
这个答案并不意味着要被标记,而是展示了解决同一问题的不同方法。
搜索深度为3,可以在代码中增加,甚至可以作为构造函数或方法参数获取。
有效。
public class RecursiveWindowSearcher
{
public delegate bool EnumWindowsProc(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32")]
public extern static int EnumWindows(EnumWindowsProc lpEnumFunc, int lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
private IntPtr windowParent;
private string windowName;
private IntPtr windowPointer;
public RecursiveWindowSearcher(string windowName, IntPtr windowParent)
{
this.windowName = windowName;
this.windowParent = windowParent;
}
public bool WinApiCallback(IntPtr hwnd, IntPtr lParam)
{
Console.WriteLine("Window: {0}", hwnd);
StringBuilder windowNameFar = new StringBuilder(256);
GetWindowText(hwnd, windowNameFar, 256);
if (windowNameFar.ToString() == windowName)
{
windowPointer = hwnd;
return false;
}
Console.WriteLine("Name: {0}", windowNameFar);
if(indent == 6)
{
return false;
}
indent += 2;
EnumChildWindows(hwnd, WinApiCallback, IntPtr.Zero);
indent -= 2;
return true;
}
public IntPtr Find()
{
this.windowPointer = IntPtr.Zero;
if (windowParent == IntPtr.Zero)
{
EnumWindows(WinApiCallback, 0);
}
else
{
EnumChildWindows(windowParent, WinApiCallback, IntPtr.Zero);
}
return windowPointer;
}
}
而且用法很简单:
第二个构造函数参数是指向现有 window 的指针,从中开始搜索。如果您有此句柄,则可以传递它以将搜索范围缩小到特定的 window 及其子项。
static void Main()
{
IntPtr windowFound = new RecursiveWindowSearcher("Skype for Business ", IntPtr.Zero).Find();
Console.ReadLine();
}