Customize System Menu in WPF.

Most of the times, I wonder how System Menu in Native Window has been replaced with custom Menu in WPF. Finally I found the trick. I just want to share the idea here.

Normally WPF does not allow direct customization to Non-client area of Window. But that can be done using native methods. We need to hook the WndProc method. WPF has no override method as Win Forms does. The following code shows how to hook WndProc();

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            IntPtr windowhandle = new WindowInteropHelper(this).Handle;
            HwndSource hwndSource = HwndSource.FromHwnd(windowhandle);
            hwndSource.AddHook(new HwndSourceHook(WndProc));
        }

        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            //Code goes here...
           
            return IntPtr.Zero;
        }

First we should hide the default System Menu in Window.

To hide the default System Menu in Window, we should handle the particular message. Corresponding window message and parameter for opening System Menu is 0xa4 and 0x02 respectively.

        private const uint WM_SYSTEMMENU = 0xa4;
        private const uint WP_SYSTEMMENU = 0x02;

        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {

            //Message for System Menu...

            if ((msg == WM_SYSTEMMENU) && (wParam.ToInt32() == WP_SYSTEMMENU))
            {
                ShowContextMenu();
                handled = true;
            }
                      
            return IntPtr.Zero;
        }
 
ShowContextMenu() method will show our custom Context Menu declared in Window resources.
 
    <Window.Resources>
        <ContextMenu x:Key="systemMenu">
            <MenuItem Header="Help" InputGestureText="F1">
                <MenuItem.Icon>
                    <Image Source="Help.png" Height="16"/>
                </MenuItem.Icon>
            </MenuItem>
            <MenuItem Header="Choose theme">
                <MenuItem.Icon>
                    <Image Source="ChooseColor.png" Height="16"/>
                </MenuItem.Icon>
            </MenuItem>
            <MenuItem Header="Add Note">
                <MenuItem.Icon>
                    <Image Source="NoteHS.png" Height="16"/>
                </MenuItem.Icon>
            </MenuItem>
            <Separator />
            <MenuItem Header="Exit"/>
        </ContextMenu>
    </Window.Resources>

        public ContextMenu SystemMenu
        {
            get
            {
                return Resources["systemMenu"as ContextMenu;
            }
        }
 
        private void ShowContextMenu()
        {
            if (SystemMenu != null)
            {
                SystemMenu.IsOpen = true;
            }
        } 
 
Now you can see the below output.

 
Download the sample from below location:
 
http://www.4shared.com/zip/Sno5IMwy/WpfApplication1.html
 
Happy coding... 






 

2 thoughts on “Customize System Menu in WPF.

Add yours

Leave a comment

Up ↑