Say you want your WPF application to have no Title bar, and will be maximized to Full Screen, what do you first think of. It's the easiest to do.
- Set WindowStyle to Maximized: By this, the Window will not show up any title bar. The window style will be transformed to a Box with border in it.
- Set WindowState to None: By this, the window will be maximized to the whole screen and will show only the window and nothing else.
Oh.. hold on... hold on... As I say, it hides the whole screen, it means it even will not show up the Taskbar or any external gadgets applied to your desktop if it is not set to Always on Top attribute to it.
Yes, this is the problem that I faced recently, when people wanted me to show the TaskBar
even though the application should be Maximized.
Is It a Bug ?
If I am not wrong, WPF builds application based on the Screen Resolution. It produces DPI independent pixels. If you specify it to be full screen, it first gets the Resolution of the screen, and draws the pixel based on its own algorithm. Hence, when you specify it to Maximized, it takes up the whole screen, as otherwise some portion of the screen will be hidden outside the range of the boundary.
When you restore a WPF screen, it will also recalculate the work area based on the distance between the resolution boundaries and resize itself accordingly. Now do you think Microsoft should really have an alternative state which show up the Taskbar as it does with normal Windows? I think yes.
The Solution
As I needed to do this, I have just tried out a few workarounds to this myself.
Following Lester's Blog on this issue, I have to use:
private static 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;
}
return (System.IntPtr)0;
}
private static 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);
}
The call to API WmGetMinMaxInfo
gets you the size of Maximize window for the current desktop.
[DllImport("user32")]
internal static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);
[DllImport("User32")]
internal static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);
The call to GetMonitorInfo
gets you a MONITORINFO
object and if you see the code carefully, it actually positions the window in such a way that it absolutely resizes itself to the height and width of the rectangular area.
To call this method, I can use SourceInitialized
event which will eventually be called whenever the WindowState
is modified.
void win_SourceInitialized(object sender, EventArgs e)
{
System.IntPtr handle = (new WinInterop.WindowInteropHelper(this)).Handle;
WinInterop.HwndSource.FromHwnd(handle).AddHook
(new WinInterop.HwndSourceHook(WindowProc));
}
Sounds good ?
Oh... let's give another easier solution that I have used. It's very simple.
Set properties for your window:
WindowStyle="None"
WindowState="Maximized"
ResizeMode="NoResize"
And go to your code and just resize your window based on PrimaryScreen
width and height. Make sure you do set the Left and Top of the window as well.
this.Width = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Width;
this.Height = System.Windows.Forms.Screen.PrimaryScreen.WorkingArea.Height;
this.Left = 0;
this.Top = 0;
this.WindowState = WindowState.Normal;
Making WindowState.Normal
will ensure that the default behaviour of the window is overridden and also makes the Taskbar Reappear.
I have included my sample application.
Have fun.
Did you like his post?
Oh, lets go a bit further to know him better.
Visit his Website :
www.abhisheksur.com to know more about Abhishek.
Abhishek also authored a book on .NET 4.5 Features and recommends you to read it, you will learn a lot from it.
http://bit.ly/EXPERTCookBook
Basically he is from India, who loves to explore the .NET world. He loves to code and in his leisure you always find him talking about technical stuffs.
Working as a VP product of
APPSeCONNECT, an integration platform of future, he does all sort of innovation around the product.
Have any problem? Write to him in his
Forum.
You can also mail him directly to
abhi2434@yahoo.com
Want a Coder like him for your project?
Drop him a mail to
contact@abhisheksur.com
Visit His Blog
Dotnet Tricks and Tips
Dont forget to vote or share your comments about his Writing