[英]Hooking into Windows message loop in WPF window adds white border on the inside
我正在嘗試創建一個WPF窗口,其中WindowStyle="None"
(對於自定義按鈕,沒有標題)無法調整大小。 將ResizeMode
設置為NoResize
將刪除我想要保留的aero邊框。
我可以設置最小/最大尺寸屬性並完成它,除了:
所以,我有一個簡單的方案,讓我99%的方式:
public class BorderedWindowNoResize : Window
{
[DllImport( "DwmApi.dll" )]
public static extern int DwmExtendFrameIntoClientArea(
IntPtr hwnd,
ref MARGINS pMarInset );
[DllImport( "user32.dll", CharSet = CharSet.Auto )]
public static extern IntPtr DefWindowProc(
IntPtr hWnd,
int msg,
IntPtr wParam,
IntPtr lParam );
public BorderedWindowNoResize()
{
Loaded += BorderedWindowNoResize_Loaded;
}
private void BorderedWindowNoResize_Loaded( object sender, RoutedEventArgs e )
{
IntPtr mainWindowPtr = new WindowInteropHelper( this ).Handle;
HwndSource mainWindowSrc = HwndSource.FromHwnd( mainWindowPtr );
mainWindowSrc.AddHook( WndProc );
}
private IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled )
{
var htLocation = DefWindowProc( hwnd, msg, wParam, lParam ).ToInt32();
if( msg == (uint)WM.NCHITTEST )
{
handled = true;
switch( htLocation )
{
case (int)HitTestResult.HTBOTTOM:
case (int)HitTestResult.HTBOTTOMLEFT:
case (int)HitTestResult.HTBOTTOMRIGHT:
case (int)HitTestResult.HTLEFT:
case (int)HitTestResult.HTRIGHT:
case (int)HitTestResult.HTTOP:
case (int)HitTestResult.HTTOPLEFT:
case (int)HitTestResult.HTTOPRIGHT:
htLocation = (int)HitTestResult.HTBORDER;
break;
}
}
return new IntPtr( htLocation );
}
}
基本上;
WM_NCHITTEST
,請檢查邊框結果。 HTBORDER
。 這可以讓我保持aero窗口邊框並隱藏調整大小的光標,但它在我的窗口內部添加了一個~5像素的白色邊框。
實際上,即使我在WndPrc
頂部返回默認的Windows程序結果,也沒有做其他任何事情,邊框仍然存在。 我的窗口需要不同的背景顏色,所以這對我不起作用。
有任何想法嗎? 一如既往地感謝您。
添加掛鈎時,應該只處理所需的消息,而忽略其他消息。 我相信你正在處理某些消息兩次,因為你調用了DefWindowProc,但從未將handle參數設置為true。
所以在你的情況下,你會使用:
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
if (msg == (uint)WM.NCHITTEST) {
handled = true;
var htLocation = DefWindowProc(hwnd, msg, wParam, lParam).ToInt32();
switch (htLocation) {
case (int)HitTestResult.HTBOTTOM:
case (int)HitTestResult.HTBOTTOMLEFT:
case (int)HitTestResult.HTBOTTOMRIGHT:
case (int)HitTestResult.HTLEFT:
case (int)HitTestResult.HTRIGHT:
case (int)HitTestResult.HTTOP:
case (int)HitTestResult.HTTOPLEFT:
case (int)HitTestResult.HTTOPRIGHT:
htLocation = (int)HitTestResult.HTBORDER;
break;
}
return new IntPtr(htLocation);
}
return IntPtr.Zero;
}
另外,我可能會在OnSourceInitialized覆蓋中添加鈎子,如下所示:
protected override void OnSourceInitialized(EventArgs e) {
base.OnSourceInitialized(e);
IntPtr mainWindowPtr = new WindowInteropHelper(this).Handle;
HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
mainWindowSrc.AddHook(WndProc);
}
您可以在WPF應用程序的任何位置嘗試
ComponentDispatcher.ThreadFilterMessage += new ThreadMessageEventHandler(ComponentDispatcherThreadFilterMessage);
和:
// ******************************************************************
private static void ComponentDispatcherThreadFilterMessage(ref MSG msg, ref bool handled)
{
if (!handled)
{
if (msg.message == WmHotKey)
{
HotKey hotKey;
if (_dictHotKeyToCalBackProc.TryGetValue((int)msg.wParam, out hotKey))
{
if (hotKey.Action != null)
{
hotKey.Action.Invoke(hotKey);
}
handled = true;
}
}
}
}
希望能幫助到你... :-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.