所有していないウィンドウのサイズを変更する場合(およびフックを使用せずに)、SWP_NOSENDCHANGING(0x0400)フラグを設定してWindowsSetWindowPosAPIを使用できます。
BOOL WINAPI SetWindowPos(
__in HWND hWnd,
__in_opt HWND hWndInsertAfter,
__in int X,
__in int Y,
__in int cx,
__in int cy,
__in UINT uFlags // ** SWP_NOSENDCHANGING must be passed here **
);
これにより、WM_GETMINMAXINFO制限をトリガーするWM_WINDOWPOSCHANGINGメッセージが送信されなくなります。ウィンドウの他のサイズ設定では、メッセージが送信されてウィンドウサイズが適用されるため、制限によってウィンドウがデスクトップの制限されたサイズにスナップバックされます。
ウィンドウリサイザー(C#)
以下は、メモ帳のサイズを6000x6000に変更する小さなサンプルプログラムです(文字列「無題-メモ帳」をサイズ変更するウィンドウのタイトルに変更するか、コマンドライン引数からウィンドウ名と目的のサイズを取得します)
namespace Example
{
class Program
{
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(String className, String windowName);
[DllImport("USER32.DLL", SetLastError = true)]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int left, int top, int width, int height, uint flags);
static void Main(string[] args)
{
var TOP = new IntPtr(0);
uint SHOWWINDOW = 0x0040, NOCOPYBITS = 0x0100, NOSENDCHANGING = 0x0400;
var hwnd = FindWindow(null, "Untitled - Notepad");
SetWindowPos(hwnd, TOP, 0, 0, 6000, 6000, NOCOPYBITS | NOSENDCHANGING | SHOWWINDOW);
}
}
}
制限と警告
このアプローチは一般的に機能しますが、ウィンドウのサイズ変更や便利な方法でのサイズ変更を妨げる可能性のあるいくつかの制限があります。
安全
Windows Vista以降、Microsoftはウィンドウメッセージのセキュリティを強化するように実装しました。実行可能ファイルは、それ自体のセキュリティコンテキスト以下のウィンドウとのみ対話できます。たとえば、[コンピュータの管理]ウィンドウ(常に昇格して実行されます)のサイズを変更するには、このプログラムも昇格して実行する必要があります。
Windowsとレイアウトロジックを修正
ウィンドウサイズは、プログラムによって受動的または能動的に適用される場合があります。サイズが強制されたウィンドウは、初期サイズを受動的に設定し、ユーザーがウィンドウのサイズを変更する機能を公開しません(たとえば、サイズグリップコントロールがありません)。これらのウィンドウは通常、説明されているようにメッセージを送信することでサイズを変更できますが、レイアウトロジックがないため、追加の空のクライアント領域以外は表示されません。
アクティブな強制機能を備えたWindowsは、WM_SIZEなどのWindowsメッセージをキャッチするか、より高度なレイアウトロジックで、サイズを監視します。これらのウィンドウはメッセージを受け入れる場合がありますが、独自のコードで最終的なサイズを制限または制限します。
いずれの場合も、固定サイズのWindowsには通常、大きなサイズを利用するためのレイアウトロジックがないため、強制的にサイズを変更してもメリットはありません。
WPF
WPFのWindow
クラスにはHwndSource
、WPFウィンドウに送信されるウィンドウメッセージを処理するがあります。プライベートメソッドは、、、、およびメッセージをLayoutFilterMessage
キャッチします。この場合、メッセージはプライベートによって処理されます。プライベートは、事実上、フラグをバイパスして、WPFクライアント領域のを変更します。これは、レガシーWin32メッセージをWPFイベントに適応させるプロセス全体の一部です。WM_SYSCOMMAND
WM_SIZING
WM_WINDOWPOSCHANGING
WM_SIZE
WM_SIZE
Process_WM_SIZE
NOSENDCHANGING
RenderSize
正味の効果は、Win32ホストウィンドウのサイズが変更されることです(SizeToContentがSizeToContent.WidthAndHeightに設定されていない場合)が、NOSENDCHANGINGフラグが設定されていないかのように、WPFレンダリング領域はデスクトップ領域にロックされます。上記のコードサンプルをWPFアプリに対して実行すると、タスクバーまたはWindows-TabスイッチャーのウィンドウプレビューからAero Peekの6000x6000ウィンドウを確認できますが、WPFコンテンツとレイアウトロジックがクリップされていることも確認できます。デスクトップ領域。このように、WPFウィンドウはアクティブに適用されるウィンドウに似ていますが、特定のサイズを適用するのではなく、特定の最大値WM_WINDOWPOSCHANGING
(RenderAreaの場合)を適用し、メッセージを考慮しません。
独自のアプリであり、 (を介して) Windowsフォームウィンドウ内でWPFをホストしている場合ElementHost
は、ウィンドウのサイズを変更できます。WPFコンテンツは、デスクトップよりも大きいWindowsフォームウィンドウを尊重します。
その他のフレームワーク
GTKやQtなどの他のフレームワークは、サイズの動作と制限を強制する場合と強制しない場合があり、これらの制限を克服するために可能なさまざまな回避策がある場合があります。特定のプログラムは、ウィンドウメッセージを無視、書き換え、またはバイパスする可能性があり、フレームワークは、上記のWPFなど、アプリケーションのクラス全体にメッセージを適用できます。
SetWindowPos APIの詳細:
Process_WM_SIZE
のメソッドの参照ソースHwndSource
:
http://referencesource.microsoft.com/#PresentationCore/Core/CSharp/System/Windows/Interop/HwndSource.cs,da4aa32ad121c1b9,references