MoveWindow返回"无效的窗口句柄"

时间:2014-06-12 12:15:12

标签: c# pinvoke

我正在尝试复制我通过Process.Start()启动的资源管理器窗口的Aero Snap功能。我使用MoveWindow,当资源管理器启动时,我无法调整大小以使用任何应用程序。函数本身返回false,Marshal.GetLastWin32Error()返回1400(无效窗口句柄)。

MoveWindow声明:

[DllImport("user32.dll", SetLastError = true)]
public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool bRepaint);

用法:

Process explorer = new Process
{
 StartInfo =
   {
    FileName = "explorer.exe",
    Arguments = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
    UseShellExecute = false
   }
 };

 explorer.Start();

 // returns false               
 var return = NativeDeclarations.MoveWindow(
         explorer.Handle,
         SystemParameters.WorkArea.Left.ToInt32(),
         SystemParameters.WorkArea.Top.ToInt32(),
         (SystemParameters.WorkArea.Width/2).ToInt32(),
         SystemParameters.WorkArea.Height.ToInt32(),
         true);

 // returns 1400
 var err = Marshal.GetLastWin32Error();

我已经尝试将x / y / width / height参数转换为UInt32,因为我在pinvoke.net上读到可能存在计算值的错误(就像我所做的那样),但这没有帮助无论是。 explorer.Handle似乎有效,而explorer.MainWindowHandle始终为0.我的代码有什么问题吗?我也尝试了SetWindowPos,但是它有同样的问题(无效的窗口句柄)。

我尝试的另一种方法是使用SHDocVw:

string filename;
foreach (SHDocVw.InternetExplorer window in new SHDocVw.ShellWindows())
{
 filename = Path.GetFileNameWithoutExtension(window.FullName).ToLower();
 if (filename.ToLowerInvariant() == "explorer")
 {
   window.Left = SystemParameters.WorkArea.Left.ToInt32();
   window.Top = SystemParameters.WorkArea.Top.ToInt32();
   window.Width = (SystemParameters.WorkArea.Width / 2).ToInt32();
   window.Height = SystemParameters.WorkArea.Height.ToInt32();
 }
}

虽然这似乎不会导致错误,但Left / Top / Width / Height的值仅保留旧值。如果那是相关的,我使用的是Windows 8.1 x64和.Net 4.0。

1 个答案:

答案 0 :(得分:2)

首先,您将Process.Handle视为窗口句柄。它不是。这是一个流程句柄。无论如何,我不认为你会用这种方法走得很远。我们无法保证您启动的流程将拥有新窗口。

我认为您需要使用SetWindowsHookExWH_SHELL RegisterShellHookWindow。这些中的任何一个这将为您提供有关何时创建顶级shell窗口及其句柄的通知。此时你可以移动窗口,因为你实际上有它的句柄。

顺便说一句,让我评论一下,如果文档告诉你,你应该只检查最后一个错误。对于MoveWindowMoveWindow返回false。请不要忽略Win32 API函数的返回值。