我正在開發一個WPF應用程序。我完全擺脫了標準的窗口邊框,並通過將WindowStyle設置爲None和AllowsTransparency爲true來創建我自己的窗口。唯一的問題是,當窗口最大化時,它會填滿整個屏幕,覆蓋任務欄。有沒有什麼辦法可以創建自己的邊界而不發生這種情況?使用WPF維護任務欄可見性Window.WindowStyle =無
1
A
回答
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;
,窗口將不包括任務欄。
相關問題
- 1. ViewManagement.FullScreenSystemOverlayMode和任務欄可見性
- 2. 可維護性
- 3. 維護子菜單可見
- 4. 關閉WPF窗口仍然可見任務欄
- 5. 切換欄的可見性使用類
- 6. WPF - SharedSizeGroup +可見性
- 7. 用vba維護圖像對象的可見性
- 8. 使WPF應用程序全屏幕(封面任務欄)可靠
- 9. 在任務中維護引用?
- 10. 最大化窗口維護任務欄限制
- 11. 一流的可維護性
- 12. WPF全屏任務欄appearence
- 13. WPF PasswordBox標籤可見性
- 14. WPF按鈕可見性
- 15. WPF Splitter的可見性
- 16. WPF Datatrigger可見性+空值
- 17. WPF控件可見性
- 18. ElastiCache維護窗口可用性
- 19. 應用程序在任務欄上可見嗎?
- 20. Windows服務或任務計劃程序的維護任務?
- 21. .NET線程安全調用Window.WindowStyle屬性
- 22. 任何用於Node.JS的維護庫可使用Amazon SES(電子郵件服務)?
- 23. 「保護」和「公共」可見性對班級領域無用嗎?
- 24. 如何配置連接維護任務?
- 25. SQL維護計劃 - 結束任務
- 26. 實體框架下的維護任務
- 27. 維護任務警報/反饋
- 28. XamDataGrid列可見性無法使用MVVM
- 29. 如何維護UIScrollView,使子視圖始終可見?
- 30. 處理WPF表項可見性屬性