Windows API 不能在 WPF 中工作?

Windows API not working in WPF?

似乎 GetClassName 和其他一些 Windows API 在 WPF 中根本不起作用,而是使应用程序崩溃(无异常)。复制它非常简单。这是完整的代码(在创建新的 WPF 应用程序后将其粘贴到 Window1 的代码隐藏中):

using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Input;

namespace WpfApplication1
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window
  {
    [DllImport("user32.dll")]
    static extern IntPtr WindowFromPoint(POINT p);

    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

    [StructLayout(LayoutKind.Sequential)]
    public struct POINT
    {
      public int X, Y;
    }

    public MainWindow()
    {
      InitializeComponent();
    }

    private void Window_MouseDown(object sender, MouseButtonEventArgs e)
    {
      var Pos = e.GetPosition(this);
      var WindowUnderMouse = WindowFromPoint(new POINT() { X = (int)Pos.X, Y = (int)Pos.Y });
      StringBuilder SB = new StringBuilder();
      GetClassName(WindowUnderMouse, SB, 50);
      MessageBox.Show(SB.ToString());
    }
  }
}

我的应用程序在 GetClassName 调用时崩溃。我正在使用 VS2015 + .NET 4.5。

还是我有事?

GetClassName 效果很好。但是,您错误地调用了它。当你写:

GetClassName(WindowUnderMouse, SB, 50);

您承诺提供长度为 50 的缓冲区。您没有这样做。而不是:

StringBuilder SB = new StringBuilder();

使用

StringBuilder SB = new StringBuilder(50);

现在,window class 的最大名称是 256。所以我会这样写代码,包括错误检查:

StringBuilder SB = new StringBuilder(256);
if (GetClassName(WindowUnderMouse, SB, SB.Capacity) == 0)
    throw new Win32Exception();