P/调用方法
从托管 (.NET) 代码调用非托管代码(在本例中为 C++)的最简单方法是使用平台调用服务,通常也称为 P/Invoke。您只需向编译器提供非托管函数的声明,然后像调用任何其他托管方法一样调用它。有一个非托管的 SetWindowLong 方法可用于更改指定窗口的属性。为了能够使用 P/Invoke 从 WPF 窗口类调用此方法,您只需将以下声明添加到窗口类:
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
DllImport 属性指定包含该方法的 DLL 的名称,extern 关键字告诉 C# 编译器该方法是在外部实现的,并且在编译应用程序时它不会找到任何实现或方法体。传递给 SetWindowLong 方法的第一个参数是要禁用任何上述按钮的窗口的句柄。您可以通过创建托管 WindowInteropHelper 类的实例并在窗口的 SourceInitialized 事件的事件处理程序中访问其 Handle 属性来获取 WPF 窗口的句柄。当句柄完全创建时引发此事件。 SetWindowLong 方法的第二个参数指定要设置的窗口的属性或值,以常量整数值表示。当您想更改窗口样式时,您应该将 GWL_STYLE (= -16) 常量作为第二个参数传递给该方法。
private const int GWL_STYLE = -16;
最后第三个参数指定替换值。您可以在这里使用一组常量:
private const int WS_MAXIMIZEBOX = 0x10000; //maximize button
private const int WS_MINIMIZEBOX = 0x20000; //minimize button
但是请注意,由于您应该传入一个 DWORD,该 DWORD 指定由第二个参数指定的“属性”的完整值,即本例中的窗口样式,因此您不能简单地将这些常量中的任何一个单独传递为方法的第三个参数。还有另一个 GetWindowLong 方法可以检索特定属性的当前值(在本例中也是 GWL_STYLE),然后您可以使用按位运算符获取第三个参数的正确值以传递给 SetWindowLong 方法。下面是一个完整的代码示例,例如如何禁用 WPF 中窗口的最小化按钮:
public partial class MainWindow : Window
{
[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
private const int GWL_STYLE = -16;
private const int WS_MAXIMIZEBOX = 0x10000; //maximize button
private const int WS_MINIMIZEBOX = 0x20000; //minimize button
public MainWindow() {
InitializeComponent();
this.SourceInitialized += MainWindow_SourceInitialized;
}
private IntPtr _windowHandle;
private void MainWindow_SourceInitialized(object sender, EventArgs e) {
_windowHandle = new WindowInteropHelper(this).Handle;
//disable minimize button
DisableMinimizeButton();
}
protected void DisableMinimizeButton() {
if (_windowHandle == IntPtr.Zero)
throw new InvalidOperationException("The window has not yet been completely initialized");
SetWindowLong(_windowHandle, GWL_STYLE, GetWindowLong(_windowHandle, GWL_STYLE) & ~WS_MAXIMIZEBOX);
}
}
禁用最小化按钮只需将 WS_MAXIMIZEBOX 常量替换为 WS_MINIMIZEBOX