Controlbox menu in custom form

  • Thread starter Thread starter Glenn Nilsson
  • Start date Start date
G

Glenn Nilsson

I have a custom drawn form with FormWindowBorder.None, and I would like
to be able to show the standard menu when the user clicks the control
box in the upper left corner of the form. Is this possible without
creating the menu by myself? The Move item feels a bit complicated :)

I haven't found a way to get hold of the menu in .NET but I found
GetSystemMenu in User32.dll, but I don't know what to do with the result
of that function.

Thank you all for existing :)
 
* Glenn Nilsson said:
I have a custom drawn form with FormWindowBorder.None, and I would
like to be able to show the standard menu when the user clicks the
control box in the upper left corner of the form. Is this possible
without creating the menu by myself? The Move item feels a bit
complicated :)

You will have to use p/invoke, a VB6 sample can be found here:

<http://groups.google.com/groups?selm=01bca546$a4635bc0$0202a8c0@bapi>
 
Thanks for that!

But, I'm sorry to say, I don't get it to work :/

Problem 1: hMenu only gets a non-zero value if I have a controlbox
visible, and that I don't want, since I have a custom drawn form.
Problem 2: lRet never gets any other value than 0.

Can you or anyone else understand why this is?

code follows:


Win32.POINT p = new Win32.POINT(e.X, e.Y);
IntPtr hMenu = new IntPtr(Win32.GetSystemMenu(this.Handle, 0));
int lRet = Win32.TrackPopupMenu(hMenu, Win32.TPM_LEFTALIGN |
Win32.TPM_LEFTBUTTON | Win32.TPM_NONOTIFY | Win32.TPM_RETURNCMD, p.X,
p.Y, 0, this.Handle, 0);
if (lRet > 0)
{
Win32.SendMessage(this.Handle, Win32.WM_SYSCOMMAND, lRet, IntPtr.Zero);
}
-------

public class Win32
{
[DllImport("user32")] public static extern int SendMessage(HWND hwnd,
int wMsg, int wParam, IntPtr lParam);
[DllImport("user32")] public static extern int TrackPopupMenu(HANDLE
hMenu, int wFlags, int x, int y, int nReserved, HWND hwnd, int lprc);
[DllImport("user32")] public static extern int GetSystemMenu(HWND hwnd,
int bRevert);

public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public struct POINT
{
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
public int X;
public int Y;
}

public const int TPM_CENTERALIGN = 0x4;
public const int TPM_LEFTALIGN = 0x0;
public const int TPM_LEFTBUTTON = 0x0;
public const int TPM_RIGHTALIGN = 0x8;
public const int TPM_RIGHTBUTTON = 0x2;
public const int TPM_NONOTIFY = 0x80;
public const int TPM_RETURNCMD = 0x100;
public const int WM_SYSCOMMAND = 0x112;
}

at 2003-12-11 17:07, Herfried K. Wagner [MVP] mumbled something like:
 
Hi Glenn,

You may also try this way,
implement your own context menu , then post WM_SYSCOMMAND messages to your
main form like this:

<code>
private void button1_Click(object sender, System.EventArgs e)
{
const int WM_SYSCOMMAND = 0x0112;
const int SC_MAXIMIZE = 0xF030;
const int SC_MINIMIZE = 0xF020;
const int SC_MOVE = 0xF010;
const int SC_CLOSE = 0xF060;//from winuser.h
PostMessage(this.Handle,WM_SYSCOMMAND,SC_MINIMIZE,0);
}

[
DllImport("user32.dll")
]
private static extern IntPtr PostMessage(IntPtr hWnd,
int Msg,int wParam,int lParam);
</code>

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, "online" should be removed before
sending.
 
Back
Top