我有一个很棒的工作就是创建一个.exe,它使用一个快捷方式调用,该快捷方式使用windows本机快捷方式调用方式来调用开始菜单文件夹中的元素。
它应该对最顶层的资源管理器窗口中的一个选定文件执行某些操作。
我找到了在所有资源管理器窗口中查找所有选定文件的方法,我知道如何获取最顶层窗口的窗口句柄,我知道如何在最顶层的窗口中选择所有文件如果获取最顶层的窗口句柄将会工作,在我的情况下它不是:
调用本机方法 GetForegroundWindow()不会给我顶部窗口的句柄,而是另一个,也许是我编写的程序之一,它甚至不使用控制台窗口或任何东西虽然可见,所以我甚至无法检查它是否是我的程序的句柄,而不是以显示控制台的方式更改它。
我想得到的处理使用在快捷方式选项中设置的键盘组合的前景窗口。
如何在调用程序之前获取前台窗口?
或者如何保存程序窃取焦点?
或者我如何将焦点重新放回到拥有它的最后一个窗口? /把它从当前的那个拿走。
或者我如何获得特定过程的最顶层窗口? (资源管理器)
答案 0 :(得分:0)
“或者我如何防止我的程序窃取焦点?”
试试这个......
将此代码添加到您的表单:
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;
}
}
答案 1 :(得分:0)
我找到了解决办法
感觉有点hacky,但它可靠地工作
解释一下它的作用:
1)它收集资源管理器窗口的所有当前句柄和它后面的SHDocVw.IE对象(我想知道是否有更好的方法)
2)我使用绝对不可靠和奇怪的GetNextWindow()函数,直到我得到第一个以前收集为资源管理器句柄的函数。这始终是最顶层的窗口。当前窗口和最后选择的资源管理器窗口之间通常有大约20个句柄
3)然后我返回在该文件夹窗口中选择的第一个文件的路径。
这真的感觉不应该那么难。
我和长猫一起过顶,但谁在乎呢
该方法应该有错误处理或检查不需要的状态,例如SelectedItems()可以为空或为空。
[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;
}