[英]Why doesn't getting the handle of the foreground window work in my scenario?
我有出色的工作来创建一个.exe文件,该文件将使用Windows本机快捷方式调用方式为开始菜单文件夹中的元素调用的快捷方式调用。
应该使用最上面的资源管理器窗口中的一个选定文件来执行某项操作。
我找到了在所有资源管理器窗口中查找所有选定文件的方法,我知道如何获取最顶部窗口的窗口句柄,并且我知道如何在获取最顶部窗口句柄的情况下在最顶部窗口中选择所有文件,就我而言不是 :
调用本机方法GetForegroundWindow()不会给我顶部窗口的句柄 ,而是另一个,可能是我编写的程序之一,它甚至不使用控制台窗口或任何可见的窗口,所以我可以。甚至可以检查它是否来自我的程序,而无需更改它以显示控制台。
我想使用快捷方式选项中设置的键盘组合来获取前景窗口的句柄。
在调用程序之前,如何获取位于前台的窗口?
或如何防止我的程序失去重点?
或如何将焦点返回到具有该焦点的最后一个窗口? /远离当前版本。
或者如何获得特定过程的最顶层窗口? (探索者)
“或者我如何防止我的程序失去重点?”
试试看...
将此代码添加到您的表单:
private const int WS_EX_NOACTIVATE = 0x8000000;
protected override System.Windows.Forms.CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle = cp.ExStyle | WS_EX_NOACTIVATE;
return cp;
}
}
我找到了解决方案。
感觉有点hacky,但工作可靠。
简要解释一下它的作用:
1)它收集浏览器窗口的所有当前句柄以及其背后的SHDocVw.IE对象(我想知道是否有更好的方法)
2)我正在使用绝对不可靠且怪异的GetNextWindow()函数,直到获得以前作为资源管理器句柄收集的第一个函数为止。 这始终是顶部窗口。 当前窗口和最后选择的资源管理器窗口之间通常有约20个句柄。
3)然后,我返回在该文件夹窗口中选择的第一个文件的路径。
确实感觉不应该那么难。
我和长猫在一起,但谁在乎。
该方法应具有错误处理或检查不良状态的方法,例如SelectedItems()可以为空或null。
[DllImport("user32.dll", SetLastError = true)]
private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
public static string returnSelectedFile()
{
IntPtr windowPtr = GetForegroundWindow();
Dictionary<string, SHDocVw.InternetExplorer> windows = new System.Collections.Generic.Dictionary<string, SHDocVw.InternetExplorer>();
foreach (SHDocVw.InternetExplorer window in new SHDocVw.ShellWindows())
if (Path.GetFileNameWithoutExtension(window.FullName).ToLower().Equals("explorer"))
windows.Add(window.HWND.ToString(), window);
long protectionCounter = 0;
while (true)
{
if (windows.ContainsKey(windowPtr.ToString()) || protectionCounter++ > 9999999)
break;
windowPtr = GetWindow(windowPtr, 2);
}
return ((Shell32.IShellFolderViewDual2)windows[windowPtr.ToString()].Document).SelectedItems().Item(0).Path;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.