0

アプリ外のフォームのウィンドウ スタイルを変更する方法は?難しい質問ですか?
私は実際に魔女が一番上にあり、境界線がないフォームを移動しようとしています。
ウィンドウのハンドル(hWnd)があります。
動作することが保証されていれば、何千行ものコードを書くことができます。

4

1 に答える 1

3

このウィンドウが任意の種類の Win32 ベースのランタイムから生成された任意のアプリからのものである可能性があると仮定すると、ウィンドウ操作のためにコア Win32 API の p/invoke に頼る必要があるようです。

たとえば、user32.dll からインポートできるSetWindowPosを使用できます。その署名は次のとおりです。

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 を置き換えます。SWP_NOZORDER および SWP_NOREPOSITION フラグで並べ替えが無効になっているため、ここでの HWND_TOP は完全にオプションです。

これが正しい軌道に乗るのに役立つことを願っています!

于 2010-01-11T16:27:45.220 に答える