0

如何在您的应用程序之外更改窗体的窗口样式?难题?
我实际上是想移动一个表格,女巫是最上面的,没有边界。
我有窗口的句柄(hWnd)。
如果保证可以工作,我可以编写数千行代码。

4

1 回答 1

3

假设这个窗口可能来自任何基于 Win32 的运行时生成的任何应用程序,看起来您将不得不求助于核心 Win32 api 的 p/invoke 来进行窗口操作。

例如,您可以使用SetWindowPos,它可以从 user32.dll 导入。它的签名是这样的:

BOOL SetWindowPos(HWND hWnd, 
  HWND hWndInsertAfter,
  int X,
  int Y,
  int cx,
  int cy,
  UINT uFlags
);

我不会假设您之前已经完成了 ap/invoke 导入,所以让我们从头开始。让我们猛烈抨击一个 Windows 窗体应用程序:

1) 创建一个 windows 窗体应用程序,然后将这些声明添加到 Form1 类:

/* hWndInsertAfter constants.  Lifted from WinUser.h, 
 * lines 4189 onwards depending on Platform SDK version */
public static IntPtr HWND_TOP = (IntPtr)0;
public static IntPtr HWND_BOTTOM = (IntPtr)1;
public static IntPtr HWND_TOPMOST = (IntPtr)(-1);
public static IntPtr HWND_NOTOPMOST = (IntPtr)(-2);

/* uFlags constants.  Lifted again from WinUser.h, 
 * lines 4168 onwards depending on Platform SDK version */
/* these can be |'d together to combine behaviours */
public const int SWP_NOSIZE          = 0x0001;
public const int SWP_NOMOVE          = 0x0002;
public const int SWP_NOZORDER        = 0x0004;
public const int SWP_NOREDRAW        = 0x0008;
public const int SWP_NOACTIVATE      = 0x0010;
public const int SWP_FRAMECHANGED    = 0x0020;
public const int SWP_SHOWWINDOW      = 0x0040;
public const int SWP_HIDEWINDOW      = 0x0080;
public const int SWP_NOCOPYBITS      = 0x0100;
public const int SWP_NOOWNERZORDER   = 0x0200;  /* Don't do owner Z ordering */
public const int SWP_NOSENDCHANGING  = 0x0400;  /* Don't send WM_WINDOWPOSCHANGING */
public const int SWP_DRAWFRAME       = SWP_FRAMECHANGED;
public const int SWP_NOREPOSITION    = SWP_NOOWNERZORDER;
public const int SWP_DEFERERASE      = 0x2000;
public const int SWP_ASYNCWINDOWPOS  = 0x4000;

[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SetWindowsPos(IntPtr hWnd,
  IntPtr hWndInsertAfter,
  int x,
  int y,
  int cx,
  int cy,
  UInt32 uFlags);

Win32 windows 方法的 p/invoke 令人讨厌的事情是,您必须开始导入 Win32 使用的各种数字常量等 - 因此事先所有口香糖。

请参阅 SetWindowPos 方法的 MSDN 链接,了解它们的作用。

2) 在窗体中添加一个名为 cmdMakeHidden 的按钮,然后编写如下处理程序:

private void cmdMakeHidden_Click(object sender, EventArgs e)
{
  //also causes the icon in the start bar to disappear
  //SWP_HIDEWINDOW is the 'kill -9' of the windows world without actually killing!
  SetWindowPos(this.Handle, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_HIDEWINDOW);
}

将“this.Handle”替换为您选择的窗口句柄以隐藏该窗口。

此方法实际上用于一次应用多个更改,因此需要使用一些SWP_NO*选项。例如,您应该指定 SWP_NOSIZE 否则为 cx 和 cy 传递 0 将导致窗口同时缩小到零宽度和高度。

要演示移动窗口,请在表单中添加另一个名为 cmdMove 的按钮,然后编写单击处理程序,如下所示:

private void cmdMove_Click(object sender, EventArgs e)
{
  SetWindowPos(this.Handle, HWND_TOP, 100, 100, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOREPOSITION);
}

每当您点击按钮时,此代码会将您的表单移动到 100,100。

再次,替换 this.Handle 你认为合适的。这里的 HWND_TOP 是完全可选的,因为重新排序已被 SWP_NOZORDER 和 SWP_NOREPOSITION 标志禁用。

希望这可以帮助您走上正轨!

于 2010-01-11T16:27:45.220 回答