【问题标题】:manipulating window / process by its handle (even if there's no title or a window) [closed]通过其句柄操作窗口/进程(即使没有标题或窗口)[关闭]
【发布时间】:2012-09-01 19:05:59
【问题描述】:

我想检查一下这段代码,看看你能不能帮我实现它

如果是这样, 有没有办法查询得更快 以“a”开头的进程和以“b”开头的进程

(是不是用filter参数)

是否可以通过其他方法使用所需的参数来完成

EnumDesktopWindows(IntPtr.Zero, filter, IntPtr.Zero)

我怎样才能调用EnumDesktopWindows() 另一个可能不仅使用本机方法 - 如上所述的过滤...一种“帮助”方法

 private const string USER32 = "user32.dll";

    internal delegate bool EnumDelegate(IntPtr hWnd, int lParam);

    [DllImport(WindowsFunctions.USER32, EntryPoint = "GetWindowText", ExactSpelling = false, CharSet = CharSet.Auto, SetLastError = true)]
    internal static extern int GetWindowText(IntPtr hWnd, StringBuilder lpWindowText, int nMaxCount);

    [DllImport(WindowsFunctions.USER32)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool IsWindowVisible(IntPtr hWnd);

    [DllImport(WindowsFunctions.USER32)]
    internal static extern int GetWindowThreadProcessId(IntPtr hWnd, out int processId);

    [DllImport(WindowsFunctions.USER32)]
    internal static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpfn, IntPtr lParam);







public class WindowData
{
    public string Title { get; set; }
    public long ProcessId { get; set; }
    public long ThreadId { get; set; }
    public IntPtr HWindow { get; set; }
}


        var collection = new List<WindowData>();

        EnumDelegate filter = delegate(IntPtr hWnd, int lParam)
        {
            StringBuilder strbTitle = new StringBuilder(255);
            int nLength = WindowsFunctions.GetWindowText(hWnd, strbTitle, strbTitle.Capacity + 1);
            string strTitle = strbTitle.ToString();

            if (IsWindowVisible(hWnd) && !string.IsNullOrEmpty(strTitle))
            {
                int pid;
                int threadId = WindowsFunctions.GetWindowThreadProcessId(hWnd, out pid);

                collection.Add(new WindowData()
                {
                    Title = strbTitle.ToString(),
                    ProcessId = pid,
                    ThreadId = threadId,
                    HWindow = hWnd
                });
            }

            return true;
        };



        if (EnumDesktopWindows(IntPtr.Zero, filter, IntPtr.Zero))
        {
            return collection.ToArray();
        }

        return null;
    }

【问题讨论】:

  • 请提出一个简短而直接的问题。
  • 这里真的没有问题。您的问题真的是“我如何执行最终的 sn-p 代码?”如果是这样,请删除所有问题的其余部分并仅提出问题。
  • 不完全是,我问的是一种优雅的方式来查询那个“丢失的”hWnd 如何以最巧妙的方法获取它你会使用不安全的代码来获得更多的性能吗?任务,你会选择什么方法,关于我发布的最后一个方法,我认为使用 pinvoke 将完成我提到的工作,优雅而性能优化,如果这个代码(最后一个)可以做到,我想看看如何,但主要问题是你会选择怎么做?
  • 我仍然无法理解这一点,仍然看不到真正的问题。对不起。
  • @DavidHeffernan 将其重新精简为一个尽可能短的问题

标签: c# winapi enumeration window-handles


【解决方案1】:

这是我想出的临时解决方案

public static class MyProc
    {
        public static IntPtr WoWhWnd;
        public static string WoWProcName;
        public static string WowMainWinTitle;
        public static int WowID;
        public static IntPtr MyApphWnd;
        public static string MyAppProcName;
        public static string MyAppMainWinTitle;
        public static int MyAppID;
    }


    public void bring(string handletoFront)
    {
        switch (handletoFront)
        {
            default:

                SetForegroundWindow(MyProc.WoWhWnd);

                break;
            case "MyApp":

                SetForegroundWindow(MyProc.MyApphWnd);
                                    break;
        }


    }


           #region <<=========== Enumerating Processes   ============>>

        void  ShowP1(){

            IEnumerable<Process> processes = from p in Process.GetProcesses() where p.ProcessName.StartsWith(TBXSearchWindowTerm.Text) || p.ProcessName.StartsWith("WindowsF") orderby p.ProcessName select p;
            MyProc.MyApphWnd = processes.ElementAt(1).MainWindowHandle;
            MyProc.MyAppMainWinTitle = processes.ElementAt(1).MainWindowTitle;
            MyProc.MyAppID = processes.ElementAt(1).Id;
            MyProc.WoWhWnd = processes.ElementAt(0).MainWindowHandle;
            MyProc.WowMainWinTitle = processes.ElementAt(0).MainWindowTitle;
            MyProc.WowID = processes.ElementAt(0).Id;
            pause(350);
            SetForegroundWindow(MyProc.WoWhWnd);
            pause(850);
            SetForegroundWindow(MyProc.MyApphWnd);
        }

在其中一个查询中,我使用了一个文本框值,因此它可以是一个恒定搜索和一个动态可选搜索,如果您发现我做错了什么或者我可以做得更好,请发表评论。谢谢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 2012-12-02
    • 1970-01-01
    • 2011-01-28
    • 2013-12-08
    相关资源
    最近更新 更多