Hide minimize, maximize, close buttons from a window and show the icon - c#

I'm trying to hide the minimize, maximize and close buttons from the top of my window and still display my icon.
I have tried a couple different things but can't get the icon to stay. This is the code I am working with:
private const int GWL_STYLE = -16;
private const int WS_SYSMENU = 0x00080000;
[DllImport("user32.dll")]
private extern static int SetWindowLong(IntPtr hwnd, int index, int value);
[DllImport("user32.dll")]
private extern static int GetWindowLong(IntPtr hwnd, int index);
public Window()
{
SourceInitialized += MainWindow_SourceInitialized;
InitializeComponent();
Uri iconUri = new Uri("pack://application:,,,/Icon1.ico", UriKind.RelativeOrAbsolute);
this.Icon = BitmapFrame.Create(iconUri);
}
void MainWindow_SourceInitialized(object sender, EventArgs e)
{
WindowInteropHelper wih = new WindowInteropHelper(this);
int style = GetWindowLong(wih.Handle, GWL_STYLE);
SetWindowLong(wih.Handle, GWL_STYLE, style & ~WS_SYSMENU);
}
Any help will be greatly appreciated!
Thanks!

You can set the WindowStyle property of the WPF window in XAML to None.
i.e.
WindowStyle="None"
Using code you can do the same thing as follows:-
WindowName.WindowStyle = WindowStyle.None;
It must work to hide all the three buttons.

This is code I have used to enable and disable the close button in winforms. I realize that's different than what you want in 3 ways
1) It only deals with the close button (although, if Oscar is correct, it's the only one you need to worry about)
2) it doesn't hide it, it just disables/greys it out (though you may be able to change a parameter to completely hide it instead)
3) It is for winforms, not wpf
Despite these differences, perhaps looking at the code will help you figure out what you are missing. If it you do figure it out, I'd be interested in you posting your solution :)
#region Enable / Disable Close Button
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
private const int SC_CLOSE = 0xF060;
private const int MF_BYCOMMAND = 0x0000;
private const int MF_ENABLED = 0x0000;
private const int MF_GRAYED = 0x0001;
protected void DisableCloseButton()
{
try
{
EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
this.CloseButtonIsDisabled = true;
}
catch{}
}
protected void EnableCloseButton()
{
try
{
EnableMenuItem(GetSystemMenu(this.Handle, false), SC_CLOSE, MF_BYCOMMAND | MF_ENABLED);
this.CloseButtonIsDisabled = false;
}
catch{}
}
protected override void OnSizeChanged(EventArgs e)
{
if (this.CloseButtonIsDisabled)
this.DisableCloseButton();
base.OnSizeChanged(e);
}
#endregion

Note that some window styles can not be changed after window creation but I don't know whether this applies to these flags or not... As far as I know if your titlebar is painted by the system you either have both an icon and a close button or none of these because both of them are controlled by the WS_SYSMENU window style.

In the Form properties, for example in a WPF application, you can only hide the minimize and mazimize buttons.
There is a property called ResizeMode, and if you put to NoResize, this two button will be hidden. ;)

Related

Disable maximize button of WPF window, keeping resizing feature intact

So WPF windows only have four resize mode options: NoResize, CanMinimize, CanResize and CanResizeWithGrip. Unfortunately, the options that enable resizing also enable maximizing the window, and those that don't are useless to me.
Is there an option to disable the maximize button while keeping the resize feature?
I'd prefer solutions that don't involve WinAPI stuff.
Disabled only Maximize:
ResizeMode="CanMinimize"
WPF does not have the native capability to disable the Maximize button alone, as you can do with WinForms. You will need to resort to a WinAPI call. It's not scary:
[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
private const int GWL_STYLE = -16;
private const int WS_MAXIMIZEBOX = 0x10000;
private void Window_SourceInitialized(object sender, EventArgs e)
{
var hwnd = new WindowInteropHelper((Window)sender).Handle;
var value = GetWindowLong(hwnd, GWL_STYLE);
SetWindowLong(hwnd, GWL_STYLE, (int)(value & ~WS_MAXIMIZEBOX));
}
If you set
WindowStyle="ToolWindow"
In your window's properties, it will give you a resizable window with no minimize or maximize buttons at the top. It'll be square looking and the close button is also square, but at least minimize and maximize aren't there!
P/Invoke Method
The easiest way to call unmanaged code (C++ in this case) from managed (.NET) code is to use the Platform Invocation Services, often also referred to as P/Invoke. You simply provide the compiler with a declaration of the unmanaged function and call it like you would call any other managed method. There is an unmanaged SetWindowLong method that can be used to change an attribute of a specified window. To be able to call this method from your WPF window class using P/Invoke, you simply add the following declaration to the window class:
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
The DllImport attribute specifies the name of the DLL that contains the method and the extern keyword tells the C# compiler that the method is implemented externally and that it won’t find any implementation or method body for it when compiling the application. The first argument to be passed to the SetWindowLong method is a handle for the window for which you want to disable any of the mentioned buttons. You can get handle for a WPF window by creating an instance of the managed WindowInteropHelper class and access its Handle property in an event handler for the window’s SourceInitialized event. This event is raised when the handle has been completely created. The second argument of the SetWindowLong method specifies the attribute or value of the window to be set, expressed as a constant integer value. When you want to change the window style, you should pass the GWL_STYLE (= -16) constant as the second argument to the method.
private const int GWL_STYLE = -16;
Finally the third argument specifies the the replacement value. There are a set of constants that you could use here:
private const int WS_MAXIMIZEBOX = 0x10000; //maximize button
private const int WS_MINIMIZEBOX = 0x20000; //minimize button
Note however that since you are supposed to pass in a DWORD that specifies the complete value for the “property” specified by the second argument, i.e. the window style in this case, you cannot simply pass any of these constants by themselves as the third argument to the method. There is another GetWindowLong method that retrieves the current value of a specific property – again the GWL_STYLE in this case – and you can then use bitwise operators to get the correct value of the third parameter to pass to the SetWindowLong method. Below is a complete code sample of how you for example could disable the minimize button for a window in WPF:
public partial class MainWindow : Window
{
[DllImport("user32.dll")]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
private const int GWL_STYLE = -16;
private const int WS_MAXIMIZEBOX = 0x10000; //maximize button
private const int WS_MINIMIZEBOX = 0x20000; //minimize button
public MainWindow() {
InitializeComponent();
this.SourceInitialized += MainWindow_SourceInitialized;
}
private IntPtr _windowHandle;
private void MainWindow_SourceInitialized(object sender, EventArgs e) {
_windowHandle = new WindowInteropHelper(this).Handle;
//disable minimize button
DisableMinimizeButton();
}
protected void DisableMinimizeButton() {
if (_windowHandle == IntPtr.Zero)
throw new InvalidOperationException("The window has not yet been completely initialized");
SetWindowLong(_windowHandle, GWL_STYLE, GetWindowLong(_windowHandle, GWL_STYLE) & ~WS_MAXIMIZEBOX);
}
}
Disabling the minimize button is then simply a matter of replacing the WS_MAXIMIZEBOX constant with the WS_MINIMIZEBOX
Another option is catching the StateChanged event which is raised when the window is maximized. Then simply set the WindowState to "Normal".
This however does not hide the maximize box!
private void Window_StateChanged(object sender, EventArgs e)
{
if (WindowState == WindowState.Maximized)
{
WindowState = WindowState.Normal;
}
}
You can create a custom window by setting WindowStyle to None, which removes the Minimize, Maximize and Close buttons, and create yourself the buttons you need.
That's a great example for this:
http://www.codeproject.com/Articles/131515/WPF-Custom-Chrome-Library
It gives you some extra work, but if you realy don't want to use WinAPI, that's an option.

Size option disable from the system menu in c# application

I have a c# windows base application.Now I want that the in the system menu the size option should be disable.
To add the option in system menu I am using user32.dll.
I am using windows form.
If you have a dialog box (you haven't specified that) ...
... and if you're using Winforms (you haven't specified that, either) ...
then you can disable the ability to resize by specifying a Fixed border type; and y7ou can disable the ability to minimize or maximize by setting the respective form properties to "false".
For example:
form1.FormBorderStyle = FormBorderStyle.FixedDialog;
form1.MaximizeBox = false;
form1.MinimizeBox = false;
Otherwise, please specify what you're doing, and how you're trying to do it. Sample code is always helpful :)
Now I found the solution,
private const int WM_SYSCOMMAND = 0x112;
private const int MF_BYCOMMAND = 0x00000000;
private const int SC_SIZE = 0xF000 ;
[DllImport("user32.dll")]
private static extern int GetSystemMenu(int hwnd, int bRevert);
[DllImport("user32.dll")]
private static extern bool DeleteMenu(int hMenu, int uPosition, int uFlags);
int menu = GetSystemMenu(this.Handle.ToInt32(), 0);
DeleteMenu(menu, SC_SIZE, MF_BYCOMMAND);

Is there way to check whether a Form has a Form Border? (by handle)

I want to check whether a form has a Form Border by its handle.
And, the handle is from the another Application.
How can I handle this?
Please help me.. Thanks!
[DllImport("user32.dll")]
extern static int GetWindowLong(IntPtr hWnd, int nIndex);
const int GWL_STYLE = -16;
const int WS_BORDER = 0x00800000; // thin border
const int WS_THICKFRAME = 0x00040000; // sizing (thick) border
public static bool NativeWindowHasBorder(IntPtr hWnd)
{
return (GetWindowLong(hWnd, GWL_STYLE) & (WS_BORDER | WS_THICKFRAME)) != 0;
}
Controls themselves don't actually have a handle. Control.Handle actually returns it's parent window's .Handle.
From MSDN for Control.Handle:
Gets the window handle that the control is bound to.
If you look at the decompiled source for Control, you'll see:
internal IntPtr HandleInternal
{
get
{
return this.window.Handle;
}
}
Edit
What I've stated above is completely incorrect. I'm leaving it for historical sake.
One can prove this very easily by putting a Button on a Form, and looking at the IntPtr Handle value for them. They are different.

WPF window not fading when closing on Vista/Windows 7

I'm writing a sample application that is both GDI and WPF. I have a WPF window that has a button with a click handler with the following body:
this.DialogResult = true;
This closes the WPF dialog as it should. However, when closing this dialog, there is no "fade" effect on Windows 7/Vista. Alternatively, using a GDI window, the fade works. I'm either doing something wrong or this is the default behavior when closing WPF windows. Additionally, using the X button to close performs the same unwanted behaviour.
Ideally, I'd like both types of windows to close with the same style. Has anyone else encountered this? Is this something easily fixed for all of my WPF windows?
EDIT: Ok so I noticed something very interesting. When the window to closed is not over the parent window (e.g. it's moved to a different monitor) and closed, the usual fade fires correctly! However, if the window to close is over the parent window, no fade occurs. Lovely!
If your window is borderless,
<Window
xmlns="blahblahblah"
AllowsTransparency="True" WindowStyle="None">
you can likely get away with making a fade animation to transparent, and write a close event handler that calls the animation then completes the close. If the window has a border, I am pretty sure the border will stay there and will look wierd.
I've come up with a solution, although I think it's still quite the hack to actually have fade working. I also tested with a pure WPF application and the window will still only fade when not overlapping its parent window. If anyone has a better solution than the code below, please let me know!
public class WindowBase : Window
{
private bool hasFadeCompleted = false;
protected override void OnClosing(CancelEventArgs e)
{
if (this.hasFadeCompleted)
{
base.OnClosing(e);
return;
}
e.Cancel = true;
var hWnd = new WindowInteropHelper(this).Handle;
User32.AnimateWindow(hWnd, 1, AnimateWindowFlags.AW_BLEND | AnimateWindowFlags.AW_HIDE);
Task.Factory.StartNew(() =>
{
this.Dispatcher.Invoke(new Action(() =>
{
this.hasFadeCompleted = true;
this.Close();
}), DispatcherPriority.Normal);
});
}
}
public static class User32
{
[DllImport("user32.dll")]
public static extern bool AnimateWindow(IntPtr hWnd, int time, uint flags);
}
public static class AnimateWindowFlags
{
public const uint AW_HOR_POSITIVE = 0x00000001;
public const uint AW_HOR_NEGATIVE = 0x00000002;
public const uint AW_VER_POSITIVE = 0x00000004;
public const uint AW_VER_NEGATIVE = 0x00000008;
public const uint AW_CENTER = 0x00000010;
public const uint AW_HIDE = 0x00010000;
public const uint AW_ACTIVATE = 0x00020000;
public const uint AW_SLIDE = 0x00040000;
public const uint AW_BLEND = 0x00080000;
}
I'm still surprised that this hasn't been an issue for anyone else.

Can a windows form display the min and max buttons without the close button?

Is there any way (in C#) to display a form with just the minimise and maximise buttons? Without the close button?
The only way of removing the close button (that I'm aware of) is:
form.ControlBox = false;
But this also gets rid of both the other buttons.
I wrote a function to do this once
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
if (EnableMenuItem(GetSystemMenu(this.Handle, 0), SC_CLOSE, MF_GRAYED) == -1)
throw new Win32Exception("The message box did not exist to gray out its X");
}
private const int SC_CLOSE = 0xF060;
private const int MF_GRAYED = 0x1;
[DllImport("USER32")]
internal static extern int EnableMenuItem(IntPtr WindowHandle, int uIDEnableItem, int uEnable);
[DllImport("USER32")]
internal static extern IntPtr GetSystemMenu(IntPtr WindowHandle, int bReset);
}
Note alt-f4 still works and right click "close this window" when you are looking at it from the task bar. (tested in windows 7)
There's an article here showing how to do that. It requires using the unmanaged User32.dll

Categories