2013-02-21 341 views
2

首先在這裏重新調整大小時,都忽略的一個窗口本身的XAML代碼:窗口的minWidth和了minHeight與ResizeGrip

<!-- Window Main --> 
<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Name="Window_Main" x:Class="WPF_Test.General_Window" 
    Title="General_Window" Height="500" Width="1000" BorderThickness="30" ResizeMode="CanResizeWithGrip" AllowsTransparency="True" WindowStyle="None" StateChanged="Window_Main_StateChanged"> 
<!-- Effects --> 
<Window.Effect> 
    <DropShadowEffect x:Name="Border_Effect" ShadowDepth="0" BlurRadius="30" Direction="0" Opacity="0.5"/> 
</Window.Effect> 
<!-- Border Main --> 
<Border x:Name="Border_Main" BorderBrush="Gray" BorderThickness="1"> 
    <!-- Panel Main --> 
    <DockPanel x:Name="Panel_Main"> 
     <DockPanel x:Name="Panel_Title" Height="25" LastChildFill="False" Background="#FFEEEEEE" MouseDown="Panel_Title_MouseDown" VerticalAlignment="Top" DockPanel.Dock="Top"> 

     </DockPanel> 
     <DockPanel x:Name="Panel_Secondary" LastChildFill="true" Background="#FFEEEEEE"/> 
    </DockPanel> 
</Border> 

這裏的構造爲的C#代碼窗口,在這裏我明確界定窗口的最小尺寸,但調整大小時,他們依然被忽略:

public void Window_Init() 
    { 

     Window_Main.MinHeight = Window_Minimum_Height + Window_Thickness * 2; 
     Window_Main.MinWidth = Window_Minimum_Width + Window_Thickness * 2; 
     Window_Main.BorderThickness = new Thickness(Window_Thickness); 
    } 

所以,當我重新大小使用0窗口(由CanResizeWithGrip屬性提供)窗口本身將停止重新調整大小,此時它將達到最小寬度和高度。儘管包含窗口的渲染區域仍然可以重新調整大小以適應更小的尺寸,因此它看起來像是桌面上窗口的截圖。

回答

4

我解決了這個錯誤。 您可以使用手柄調整大小或創建您自己的大小調整控件,使用OnMouseDown事件向HWND發送消息以調整窗口大小,同時不會超過先前爲窗口定義的最小大小。 此代碼將限制窗口大小,當最大化以及以確保該窗口永遠不會在屏幕之外或通過任務欄呈現。

這應該是在你的MainWindow.cs代碼底部:

 private const int WM_SYSCOMMAND = 0X112; 
    private HwndSource hwndSource; 
    enum SWP : uint 
    { 
     NOSIZE = 0x0001 , 
     NOMOVE = 0x0002 , 
     NOZORDER = 0x0004 , 
     NOREDRAW = 0x0008 , 
     NOACTIVATE = 0x0010 , 
     FRAMECHANGED = 0x0020 , 
     SHOWWINDOW = 0x0040 , 
     HIDEWINDOW = 0x0080 , 
     NOCOPYBITS = 0x0100 , 
     NOOWNERZORDER = 0x0200 , 
     NOSENDCHANGING = 0x0400 , 
    } 
    public override void OnApplyTemplate() 
    { 
     System.IntPtr handle = (new WindowInteropHelper(this)).Handle; 
     HwndSource.FromHwnd(handle).AddHook(new HwndSourceHook(WindowProc)); 
    } 
    private System.IntPtr WindowProc(System.IntPtr hwnd , int msg , System.IntPtr wParam , System.IntPtr lParam , ref bool handled) 
    { 
     switch (msg) 
     { 
      case 0x0024: 
       { 
        WmGetMinMaxInfo(hwnd , lParam); 
        handled = true; 
        break; 
       } 
      case 0x0046: 
       { 
        WINDOWPOS pos = (WINDOWPOS)Marshal.PtrToStructure(lParam , typeof(WINDOWPOS)); 
        if ((pos.flags & (int)(SWP.NOMOVE)) != 0) 
        { 
         return IntPtr.Zero; 
        } 

        Window wnd = (Window)HwndSource.FromHwnd(hwnd).RootVisual; 
        if (wnd == null) 
        { 
         return IntPtr.Zero; 
        } 

        bool changedPos = false; 
        if (pos.cx < MinWidth) { pos.cx = (int)MinWidth; changedPos = true; } 
        if (pos.cy < MinHeight) { pos.cy = (int)MinHeight; changedPos = true; } 
        if (!changedPos) 
        { 
         return IntPtr.Zero; 
        } 

        Marshal.StructureToPtr(pos , lParam , true); 
        handled = true; 
        break; 
       } 
     } 
     return (System.IntPtr)0; 
    } 
    private void WmGetMinMaxInfo(System.IntPtr hwnd , System.IntPtr lParam) 
    { 
     MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam , typeof(MINMAXINFO)); 
     int MONITOR_DEFAULTTONEAREST = 0x00000002; 
     System.IntPtr monitor = MonitorFromWindow(hwnd , MONITOR_DEFAULTTONEAREST); 
     if (monitor != System.IntPtr.Zero) 
     { 
      MONITORINFO monitorInfo = new MONITORINFO(); 
      GetMonitorInfo(monitor , monitorInfo); 
      RECT rcWorkArea = monitorInfo.rcWork; 
      RECT rcMonitorArea = monitorInfo.rcMonitor; 
      mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left); 
      mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top); 
      mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left); 
      mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top); 
     } 
     Marshal.StructureToPtr(mmi , lParam , true); 
    } 
    [StructLayout(LayoutKind.Sequential)] 
    public struct POINT 
    { 
     public int x; 
     public int y; 
     public POINT(int x , int y) 
     { 
      this.x = x; 
      this.y = y; 
     } 
    } 
    [StructLayout(LayoutKind.Sequential)] 
    public struct MINMAXINFO 
    { 
     public POINT ptReserved; 
     public POINT ptMaxSize; 
     public POINT ptMaxPosition; 
     public POINT ptMinTrackSize; 
     public POINT ptMaxTrackSize; 
    }; 
    [StructLayout(LayoutKind.Sequential , CharSet = CharSet.Auto)] 
    public class MONITORINFO 
    { 
     public int cbSize = Marshal.SizeOf(typeof(MONITORINFO)); 
     public RECT rcMonitor = new RECT(); 
     public RECT rcWork = new RECT(); 
     public int dwFlags = 0; 
    } 
    [StructLayout(LayoutKind.Sequential , Pack = 0)] 
    public struct RECT 
    { 
     public int left; 
     public int top; 
     public int right; 
     public int bottom; 
     public static readonly RECT Empty = new RECT(); 
     public int Width 
     { 
      get { return Math.Abs(right - left); } 
     } 
     public int Height 
     { 
      get { return bottom - top; } 
     } 
     public RECT(int left , int top , int right , int bottom) 
     { 
      this.left = left; 
      this.top = top; 
      this.right = right; 
      this.bottom = bottom; 
     } 
     public RECT(RECT rcSrc) 
     { 
      this.left = rcSrc.left; 
      this.top = rcSrc.top; 
      this.right = rcSrc.right; 
      this.bottom = rcSrc.bottom; 
     } 
     public bool IsEmpty 
     { 
      get 
      { 
       return left >= right || top >= bottom; 
      } 
     } 
     public override string ToString() 
     { 
      if (this == RECT.Empty) { return "RECT {Empty}"; } 
      return "RECT { left : " + left + "/top : " + top + "/right : " + right + "/bottom : " + bottom + " }"; 
     } 
     public override bool Equals(object obj) 
     { 
      if (!(obj is Rect)) { return false; } 
      return (this == (RECT)obj); 
     } 
     public override int GetHashCode() 
     { 
      return left.GetHashCode() + top.GetHashCode() + right.GetHashCode() + bottom.GetHashCode(); 
     } 
     public static bool operator ==(RECT rect1 , RECT rect2) 
     { 
      return (rect1.left == rect2.left && rect1.top == rect2.top && rect1.right == rect2.right && rect1.bottom == rect2.bottom); 
     } 
     public static bool operator !=(RECT rect1 , RECT rect2) 
     { 
      return !(rect1 == rect2); 
     } 
    } 
    [DllImport("user32")] 
    internal static extern bool GetMonitorInfo(IntPtr hMonitor , MONITORINFO lpmi); 
    [DllImport("User32")] 
    internal static extern IntPtr MonitorFromWindow(IntPtr handle , int flags); 
    [StructLayout(LayoutKind.Sequential)] 
    internal struct WINDOWPOS 
    { 
     public IntPtr hwnd; 
     public IntPtr hwndInsertAfter; 
     public int x; 
     public int y; 
     public int cx; 
     public int cy; 
     public int flags; 
    } 
    private void InitializeWindowSource(object sender , EventArgs e) 
    { 
     hwndSource = PresentationSource.FromVisual((Visual)sender) as HwndSource; 
    } 
    public enum ResizeDirection 
    { 
     Left = 1 , 
     Right = 2 , 
     Top = 3 , 
     TopLeft = 4 , 
     TopRight = 5 , 
     Bottom = 6 , 
     BottomLeft = 7 , 
     BottomRight = 8 , 
    } 
    [DllImport("user32" , CharSet = CharSet.Auto)] 
    private static extern IntPtr SendMessage(IntPtr hWnd , uint Msg , IntPtr wParam , IntPtr lParam); 
    private void ResizeWindow(ResizeDirection direction) 
    { 
     SendMessage(hwndSource.Handle , WM_SYSCOMMAND , (IntPtr)(61440 + direction) , IntPtr.Zero); 

    } 

而且不要忘了加入這行到你的窗口的構造函數,否則任何規定工作:

SourceInitialized += new EventHandler(InitializeWindowSource);