WPFで枠を消す の続きです。
前回紹介した方法は、以下のような内容でした。
- WindowStyle=None, AllowsTransparency=True にすると枠が消える
- 移動できるように、WM_NCLBUTTONDOWN + HTCAPTION を送信する
しかし、この方法には欠点があります。
AllowsTransparencyを有効にしていると、WindowsFormsHostが表示されなくなってしまうのです。
http://msdn.microsoft.com/ja-jp/library/aa970911(VS.80).aspx
HwndHost クラスは、レイヤ表示をサポートしません。つまり、WindowsFormsHost 要素で Opacity プロパティを設定しても何の効果もなく、AllowsTransparency が true に設定されている他の WPF ウィンドウとのブレンド操作は行われません。
そこで、DirectX と連携する際などは、AllowsTransparency を False のままにしておく必要があります。
困ったときのWinAPI。直接ウィンドウスタイルを設定して、枠を消してしまいましょう。
Windows Forms Application 時代は、CreateParams で設定していたような内容ですね。
[DllImport("user32.dll")] static extern long GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("user32.dll")] static extern long SetWindowLong(IntPtr hWnd, int nIndex, long dwNewLong); [DllImport("user32.dll")] static extern UInt32 SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, int wFlags); private void RemoveFrame() { long WS_THICKFRAME = 0x00040000L; int GWL_STYLE = -16; int SWP_FRAMECHANGED = 0x0020; int SWP_NOSIZE = 0x1; int SWP_NOMOVE = 0x2; int SWP_NOZORDER = 0x4; IntPtr hwnd = new System.Windows.Interop.WindowInteropHelper(window).Handle; SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) ^ WS_THICKFRAME); SetWindowPos(hwnd, IntPtr.Zero, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); }
やっていることは以下のような感じです。
- GetWindowLongでWindowStyleを取得
- SetWindowLongで、今までのスタイルからWS_THICKFRAME(ウィンドウ枠)を除いたものを設定
- SetWindowPosで表示を更新
最後のSetWindowPostをやらないと、サイズ変更するまで描画が崩れてしまいます。
注意点としては、WS_THICKFRAME を外すと、WM_NCLBUTTONDOWN で HTBOTTOMRIGHT を送信しても、サイズ変更できなくなります。
諦めて、自分でサイズ変更処理を書くしかないみたいですね。