WPF - Maximizing a borderless window based on a custom taskbar

I am creating a WPF window with custom chrome, so I set ResizeMode="NoResize" and WindowStyle="None" to implement my own chrome. However, when enlarging a borderless window, a problem arises: it accepts the entire screen.

I found the following trick to fix part of the problem: http://chiafong6799.wordpress.com/2009/02/05/maximizing-a-borderlessno-caption-window/

This successfully limits the window size to prevent the taskbar from closing. However, if the user has his taskbar located on the left or on the top, this will not work, since the window is at position 0,0.

Is there a way to get a more accurate available area or to request the position of the user's taskbar so that I can properly position the window with the maximum value?

+4
source share
2 answers

I had a quick game and it seems that setting the Windows Left and Top properties is ignored when setting WindowState.Maximized with a WindowState.Maximized form.

One way would be to ignore WindowState functions and create your own Maximize / Restore functions

A rough example.

 public partial class MainWindow : Window { private Rect _restoreLocation; public MainWindow() { InitializeComponent(); } private void MaximizeWindow() { _restoreLocation = new Rect { Width = Width, Height = Height, X = Left, Y = Top }; System.Windows.Forms.Screen currentScreen; currentScreen = System.Windows.Forms.Screen.FromPoint(System.Windows.Forms.Cursor.Position); Height = currentScreen.WorkingArea.Height; Width = currentScreen.WorkingArea.Width; Left = currentScreen.WorkingArea.X; Top = currentScreen.WorkingArea.Y; } private void Restore() { Height = _restoreLocation.Height; Width = _restoreLocation.Width; Left = _restoreLocation.X; Top = _restoreLocation.Y; } private void Button_Click_1(object sender, RoutedEventArgs e) { MaximizeWindow(); } private void Button_Click_2(object sender, RoutedEventArgs e) { Restore(); } protected override void OnMouseMove(MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { DragMove(); } base.OnMouseMove(e); } } 

Xaml:

 <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="74.608" Width="171.708" ResizeMode="NoResize" WindowStyle="None"> <Grid> <Button Content="Max" HorizontalAlignment="Left" Margin="0,29,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/> <Button Content="Restore" HorizontalAlignment="Left" Margin="80,29,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_2"/> </Grid> </Window> 

Obviously, you will need to clear this code, but it works wherever the Taskbar is located. However, you may need to add some logic to get the correct Left , Top if the custom DPI font is more than 100%

+5
source

Another way to do this is to process the WM_GETMINMAXINFO Win32 message. The code here shows how to do this.

Note that there are several things that I would do differently: returning IntPtr.Zero instead of (System.IntPtr) 0 in WindowProc and creating the MONITOR_DEFAULTTONEAREST constant. But this coding style is changing and does not affect the net result.

Also note the update, where WindowProc connected during the SourceInitialized event instead of OnApplyTemplate . This is the best place to do it. If you are implementing a class derived from Window, then another option is to override OnSourceInitialized to bind WindowProc instead of binding to the event. This is what I usually do.

+2
source

All Articles