2012-03-16 3 views
1

WPF 응용 프로그램을 개발 중입니다. 나는 표준 Window 테두리를 완전히 제거하고 WindowStyle을 None으로 설정하고 AllowsTransparency를 true로 설정하여 내 자신을 만들었습니다. 유일한 문제는 창이 최대화되면 전체 화면을 채우고 작업 표시 줄을 덮는 것입니다. 이런 일이 발생하지 않고 자신 만의 국경을 만들 수있는 방법이 있습니까?WPF로 작업 표시 줄을 유지 관리 Window.WindowStyle = none

답변

0

사용 방법 CompatibilityMaximizedNoneWindow.

using System; 
using System.Drawing; 
using System.Runtime.InteropServices; 
using System.Windows; 
using System.Windows.Interop; 

using Point = System.Drawing.Point; 

internal static class WindowExtensions 
{ 
    public static PointF StandartDPI = new PointF(96f, 96f); 
    private static PointF? currentDpi = null; 
    public static float WidthZoom {get{return CurrentDPI.X/ StandartDPI.X; } } 
    public static float HeigthZoom { get { return CurrentDPI.Y/StandartDPI.Y; } } 

    public static PointF CurrentDPI 
    { 
     get 
     { 
      if (!currentDpi.HasValue) 
      { 
       var wiHelper = new WindowInteropHelper(App.Current.MainWindow); 
       Graphics g = Graphics.FromHwnd(wiHelper.Handle); 
       try 
       { 
        currentDpi = new PointF(g.DpiX, g.DpiY); 
       } 
       catch 
       { 
        currentDpi = StandartDPI; 
       } 
       finally 
       { 
        g.Dispose(); 
       } 
      } 
      return currentDpi.Value; 
     } 
    } 


    public static Window GetWindowFromTemplate(this object templateFrameworkElement) 
    { 
     var window = ((FrameworkElement)templateFrameworkElement).TemplatedParent as Window; 
     return window; 
    } 

    private static int minWidth; 
    private static int minHeight; 

    public static void CompatibilityMaximizedNoneWindow(this Window window) 
    { 
     var wiHelper = new WindowInteropHelper(window); 
     minHeight = (int)window.MinHeight; 
     minWidth = (int)window.MinWidth; 

     var handle = wiHelper.Handle; 
     var hwndSource = HwndSource.FromHwnd(handle); 
     if (hwndSource != null) 
     { 
      hwndSource.AddHook(CompatibilityMaximizedNoneWindowProc); 
     } 
    } 

    [DllImport("user32")] 
    private static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);[DllImport("user32")] 
    private static extern IntPtr MonitorFromWindow(IntPtr handle, int flags); 

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)] 
    private 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)] 
    private struct RECT 
    { 
     public int left; 
     public int top; 
     public int right; 
     public int bottom; 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    private struct POINT 
    { 
     public int x; 
     public int y; 

     public POINT(int x, int y) 
     { 
      this.x = x; this.y = y; 
     } 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    private struct MINMAXINFO 
    { 
     public POINT ptReserved; 
     public POINT ptMaxSize; 
     public POINT ptMaxPosition; 
     public POINT ptMinTrackSize; 
     public POINT ptMaxTrackSize; 
    } 

    private static IntPtr CompatibilityMaximizedNoneWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
    { 
     const int WM_GETMINMAXINFO = 0x0024; 
     const int MONITOR_DEFAULTTONEAREST = 0x00000002; 
     switch (msg) 
     { 
      case WM_GETMINMAXINFO: 
       var mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO)); 
       var monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); 
       if (monitor != IntPtr.Zero) 
       { 
        var monitorInfo = new MONITORINFO(); 
        GetMonitorInfo(monitor, monitorInfo); 
        var rcWorkArea = monitorInfo.rcWork; 
        var 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); 
        //Hack для ограничения минимальных размеров окна 
        mmi.ptMinTrackSize.x = (int)(minWidth*WidthZoom); 
        mmi.ptMinTrackSize.y = (int)(minHeight*HeigthZoom); 
        //Hack для нормальной работы всплывающей панели задач 
        var taskbar = new TaskbarInfo(); 
        if (taskbar.AutoHide) 
        { 
         switch (taskbar.Position) 
         { 
          case TaskbarInfo.TaskbarPosition.Top: 
           mmi.ptMaxPosition.y++; 
           mmi.ptMaxSize.y--; 
           break; 
          case TaskbarInfo.TaskbarPosition.Bottom: 
           mmi.ptMaxPosition.y--; 
           mmi.ptMaxSize.y--; 
           break; 
          case TaskbarInfo.TaskbarPosition.Left: 
           mmi.ptMaxPosition.x++; 
           mmi.ptMaxSize.x--; 
           break; 
          case TaskbarInfo.TaskbarPosition.Right: 
           mmi.ptMaxPosition.x--; 
           mmi.ptMaxSize.x--; 
           break; 
         } 
        } 
       } 
       Marshal.StructureToPtr(mmi, lParam, true); handled = true; break; 
     } 
     return (IntPtr)0; 
    } 
} 
0

Microsoft.Windows.Shell을 살펴보십시오. 그것은 당신과 그 이상을 모두합니다. 그것을 추적하는 것은 다소 실망 스럽습니다. 사용하기에 가장 좋은 것은 latest ribbon control에 포함 된 것입니다.

1

훨씬 쉬운 방법은, 당신의 창 생성자에서 단지

this.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight; 

을 설정하고 윈도우 작업 표시 줄을 포함하지 않습니다.

관련 문제