微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

获取线程的可见窗口的标题

我想知道如何去做这件事,因为我已经尝试了许多不同的user32函数,并在网上进行了相当广泛的研究,但不幸的是我还没有能够提出解决scheme。

一个应用程序有5个线程。 通过.NET Process类GetProcessById方法可以轻松地访问这些线程,并提供进程的PID。 但是,似乎没有一个函数可以用来提供线程ID并枚举它的窗口(父或子)。 其中一个线程总共有10个窗口,9个隐藏,一个可见。 该可见的线程的标题是我想要以编程方式获得。

我最新的方法是抓住进程句柄,通过EnumChildWindows,并尝试将每个窗口句柄添加到集合,但我的集合总是空的。

以下是我在ProcessthreadsView工具中看到的屏幕截图:

为什么EM_SETMARGINS在Windows 7下不起作用?

C ++ GUI教程:对textout的未定义引用

Java服务与GUI工具

用asynchronousftp操作连接GUI界面

在C,multithreading,多个窗口调用一个窗口过程,将每个调用使用新的局部variables,或者我需要一个互斥体?

有什么我失踪? 我发邮件给这个工具的作者,看看他是怎么做的,但我想我会问你们是否有一个确定的方法

更新:我已经尝试使用GetGUIThreadInfo,这是我如何调用它:

[StructLayout(LayoutKind.Sequential)] public struct Rect { public int Left; public int Top; public int Right; public int Bottom; } [StructLayout(LayoutKind.Sequential)] public struct GUITHREADINFO { public uint cbSize; public uint flags; public IntPtr hwndActive; public IntPtr hwndFocus; public IntPtr hwndCapture; public IntPtr hwndMenuOwner; public IntPtr hwndMoveSize; public IntPtr hwndCaret; public Rect rcCaret; } static IEnumerable<IntPtr> EnumerateThreadWindowHandlesByProcessId(int processId) { List<IntPtr> threadWindowHandles = new List<IntPtr>(); foreach (Processthread thread in Process.GetProcessById(processId).Threads) { GUITHREADINFO threadInfo = new GUITHREADINFO(); threadInfo.cbSize = (uint)Marshal.SizeOf(threadInfo); bool returnValue = GetGUIThreadInfo((uint)thread.Id,out threadInfo); threadWindowHandles.Add(threadInfo.hwndActive); } return threadWindowHandles; }

更新2:

使用EnumThreadWindows,这是我得到的:

public delegate bool EnumThreadDelegate(IntPtr hWnd,IntPtr lParam); [DllImport("user32.dll")] static extern bool EnumThreadWindows(int dwThreadId,EnumThreadDelegate lpfn,IntPtr lParam); private static bool ThreadWindows(IntPtr handle,IntPtr param) { //get window from handle later,testing for Now logger.Info("foo bar"); return true; } [STAThread] public void Execute() { Process[] processes = Process.GetProcessesByName("MyProcessName"); Process processOfInterest = processes[0]; foreach (Processthread thread in processOfInterest.Threads) { EnumThreadWindows(thread.Id,new EnumThreadDelegate(ThreadWindows),IntPtr.Zero); } }

通过Linuxterminal运行Java GUI应用程序

使用Tab移动到主应用程序窗口中的另一个编辑控件

基于Windows GUI的任务自动

对话使用分析/热图工具

embedded式web浏览器

我相信你正在寻找GetGUIThreadInfo 。

更新 :你的p / invoke有几个错误

rect字段是错误的(不是这里真的很重要)。 用这个:

[StructLayout(LayoutKind.Sequential)] public struct Rect { public int Left; public int Top; public int Right; public int Bottom; }

而不是System.Drawing.Rectangle 。

其他字段的类型声明也是关闭的。 应该是这样的:

[StructLayout(LayoutKind.Sequential)] public struct GUITHREADINFO { public uint cbSize; public uint flags; public IntPtr hwndActive; public IntPtr hwndFocus; public IntPtr hwndCapture; public IntPtr hwndMenuOwner; public IntPtr hwndMoveSize; public IntPtr hwndCaret; public Rect rcCaret; }

您将明智地检查您的返回值,并在您的DllImport属性中使用SetLastError = true ,以便您可以辨别函数调用失败的原因。 此外,你应该通过ref传递结构,因为你传递的结构大小。

[DllImport("user32.dll",SetLastError=true)] static extern bool GetGUIThreadInfo(uint idThread,ref GUITHREADINFO lpgui);

使用Marshal.GetLastWin32Error()获取错误代码。 但是只有在GetGUIThreadInfo返回false的情况下才能检查。

通过上述更改,当给定一个有效的线程ID时,对GetGUIThreadInfo的调用将起作用。 另外请注意,其他进程需要有输入焦点,以使GetGUIThreadInfo返回任何有用的东西。

如果指定的线程不存在或没有输入队列,则该函数将失败。

(道歉,如果我以前的回答来得严厉;我说“看似明显”,因为它似乎很明显,所以我认为这也是显而易见的,因此是错误的,但他没有给出任何细节,没有被试过。)

EnumThreadWindows绝对是你想要的功能,它应该工作。 我能够使用EnumThreadWindows和IsWindowVisible从ProcessthreadsView中复制我系统上运行的每个应用程序的信息。 (另外请记住,“可见”与“有效”不一样)。

[UnmanagedFunctionPointer(CallingConvention.StdCall)] [return: MarshalAs(UnmanagedType.Bool)] private delegate bool EnumThreadWindowsProc(IntPtr handle,int param); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool EnumThreadWindows(uint threadId,EnumThreadWindowsProc callback,int param); [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] static extern bool IsWindowVisible(IntPtr handle); [DllImport("user32.dll",CharSet = CharSet.Unicode)] static extern int GetwindowText( IntPtr handle,[MarshalAs(UnmanagedType.LPWStr)] StringBuilder caption,int count); [DllImport("user32.dll",CharSet = CharSet.Unicode)] static extern int GetwindowTextLength(IntPtr handle); static void Main(string[] args) { var callback = new EnumThreadWindowsProc(Program.ThreadWindows); foreach (var proc in Process.GetProcesses()) { foreach (Processthread thread in proc.Threads) { Program.EnumThreadWindows((uint)thread.Id,callback,0); } } Console.ReadLine(); } private static bool ThreadWindows(IntPtr handle,int param) { if (Program.IsWindowVisible(handle)) { var length = Program.GetwindowTextLength(handle); var caption = new StringBuilder(length + 1); Program.GetwindowText(handle,caption,caption.Capacity); Console.WriteLine("Got a visible window: {0}",caption); } return true; }

当你尝试使用EnumThreadWindows的时候你究竟得到了什么? 你的回调有没有触发?

你的代码更新2是好的(假设eraAccessprocess实际上是为了processOfInterest )。 该代码有效。 我能看到的唯一可能的失败原因是:

processOfInterest不是你真正感兴趣的过程。

该进程确实没有与Windows关联的线程。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐