Edit system context menu for a window?

Post your questions regarding programming in C# in here.
5 posts Page 1 of 1
Contributors
User avatar
MrAksel
C# Coder
C# Coder
Posts: 1758
Joined: Fri Mar 26, 2010 12:27 pm

When you click on the icon in the top-left corner of a window or right click the caption-bar a context menu appears. I've seen CodenStuff post an example of how to edit this, but I can't seem to find it. Can anyone show me how to edit/disable this menu?? I also need help with drawing system-style caption buttons because im painting in the non-client which hides those buttons. I know how to get the size of the buttons but not how to draw them the system-style way.
LMAOSHMSFOAIDMT
Laughing my a** of so hard my sombrero fell off and I dropped my taco lmao;


Over 30 projects with source code!
Please give reputation to helpful members!

Image
Image
User avatar
mandai
Coding God
Coding God
Posts: 2585
Joined: Mon Apr 26, 2010 6:51 pm

It is possible to add and remove items from the system menu.
Here is an example:
Code: Select all
    Const WM_SYSCOMMAND As Integer = &H112

    Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)

        If m.Msg = WM_SYSCOMMAND Then
            If m.WParam.ToInt32() = 123 Then
                MsgBox("test clicked")
            End If
        End If
        MyBase.WndProc(m)
    End Sub

    <DllImport("user32.dll")> Shared Function GetSystemMenu(ByVal hWnd As IntPtr, ByVal bRevert As Boolean) As IntPtr
    End Function

    <DllImport("user32.dll")> Shared Function GetMenuItemCount(ByVal hMenu As IntPtr) As Integer
    End Function

    <DllImport("user32.dll")> Shared Function GetMenuItemID(ByVal hMenu As IntPtr, ByVal nPos As Integer) As UInteger
    End Function

    <DllImport("user32.dll")> Shared Function RemoveMenu(ByVal hMenu As IntPtr, ByVal uPosition As UInteger, ByVal uFlags As UInteger) As Boolean
    End Function

    <DllImport("user32.dll")> Shared Function AppendMenu(ByVal hMenu As IntPtr, ByVal uFlags As UInteger, ByVal uIDNewItem As IntPtr, ByVal lpNewItem As String) As Boolean
    End Function

    Const MF_BYPOSITION As UInteger = &H400

    Const SC_RESTORE As UInteger = &HF120

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

        Dim menu As IntPtr = GetSystemMenu(Me.Handle, False)

        Dim itemCount As Integer = GetMenuItemCount(menu)
        For i As Integer = 0 To itemCount - 1

            Dim id As UInteger = GetMenuItemID(menu, i)
            If id = SC_RESTORE Then
                RemoveMenu(menu, i, MF_BYPOSITION) 'example to remove the restore option
                Exit For
            End If
        Next

        Dim myid As IntPtr = New IntPtr(123) 'must be below 0xF000
        AppendMenu(menu, 0, myid, "test")

    End Sub
User avatar
DreadNought
VIP - Donator
VIP - Donator
Posts: 116
Joined: Fri Jan 08, 2010 12:37 pm

Thats vb -.-
Bound and boom tech,
The Future Of Coding
User avatar
mandai
Coding God
Coding God
Posts: 2585
Joined: Mon Apr 26, 2010 6:51 pm

Oh right my bad I didn't see this was posted in the C# section. I will translate it:
Code: Select all
        const int WM_SYSCOMMAND = 0x112;

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_SYSCOMMAND)
            {
                if (m.WParam.ToInt32() == 123)
                {
                    MessageBox.Show("test clicked");
                }
            }
            base.WndProc(ref m);
        }

        [DllImport("user32.dll")]
        static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

        [DllImport("user32.dll")]
        static extern int GetMenuItemCount(IntPtr hMenu);

        [DllImport("user32.dll")]
        static extern uint GetMenuItemID(IntPtr hMenu, int nPos);

        [DllImport("user32.dll")]
        static extern bool RemoveMenu(IntPtr hMenu, uint uPosition, uint uFlags);

        [DllImport("user32.dll")]
        static extern bool AppendMenu(IntPtr hMenu, uint uFlags, IntPtr uIDNewItem, string lpNewItem);

        const int MF_BYPOSITION = 0x400;

        const uint SC_RESTORE = 0xF120;

        private void Form1_Load(object sender, EventArgs e)
        {
            IntPtr menu = GetSystemMenu(this.Handle, false);

            int itemCount = GetMenuItemCount(menu);
            for (int i = 0; i < itemCount; i++)
            {
                uint id = GetMenuItemID(menu, i);
                if (id == SC_RESTORE)
                {
                    RemoveMenu(menu, (uint)i, MF_BYPOSITION); //example to remove the restore option
                    break;
                }
            }

            IntPtr myid = new IntPtr(123); //must be below 0xF000
            AppendMenu(menu, 0, myid, "test");
        }
User avatar
MrAksel
C# Coder
C# Coder
Posts: 1758
Joined: Fri Mar 26, 2010 12:27 pm

No problem, I have translated it a long time ago.
LMAOSHMSFOAIDMT
Laughing my a** of so hard my sombrero fell off and I dropped my taco lmao;


Over 30 projects with source code!
Please give reputation to helpful members!

Image
Image
5 posts Page 1 of 1
Return to “General coding help”