2

I have non-rectangular transparent window with custom style.

<Window x:Class="TestWindow" x:Name="Window" Width="350" Height="450" AllowsTransparency="True" WindowStyle="None" WindowStartupLocation="CenterScreen" FontSize="14 px" FontFamily="Fonts/#Tahoma" Background="Transparent"> 

I have a grid for title and system buttons and want to show application menu by right click on it. Currently app menu showing only by pressing ALT+Spacebar. How can i solve this problem?

2 Answers 2

4

So, after a two hours spent in Google I finally found a solution.

Step1: define RECT structure like this:

 [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; public int Top; public int Right; public int Bottom; } 

Step2: import two user32.dll functions:

[DllImport("user32.dll")] private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert); [DllImport("user32.dll")] public static extern int TrackPopupMenu(int hMenu, int wFlags, int x, int y, int nReserved, int hwnd, ref RECT lprc); 

Step3: add 'right mouse button click on header' event handler:

private void headerArea_PreviewMouseDown(object sender, MouseButtonEventArgs e) { switch (e.ChangedButton) { case MouseButton.Right: { // need to get handle of window WindowInteropHelper _helper = new WindowInteropHelper(this); //translate mouse cursor porition to screen coordinates Point p = PointToScreen(e.GetPosition(this)); //get handler of system menu IntPtr systemMenuHandle = GetSystemMenu(_helper.Handle, false); RECT rect = new RECT(); // and calling application menu at mouse position. int menuItem = TrackPopupMenu(systemMenuHandle.ToInt32(), 1,(int)p.X, (int) p.Y, 0, _helper.Handle.ToInt32(), ref rect); break; } } } 
Sign up to request clarification or add additional context in comments.

Comments

0

I had to change Raeno's code as follows to get the menu items to work...

//Get the hWnd, because I need to re-use it... int hWnd = helper.Handle.ToInt32(); //Change the wFlags from 1 to TPM_RIGHTBUTTON | TPM_RETURNCMD... int menuItem = TrackPopupMenu(systemMenuHandle.ToInt32(), TPM_RIGHTBUTTON | TPM_RETURNCMD, (int)point.X, (int)point.Y, 0, hWnd, ref rect); // The return value from TrackPopupMenu now need posting... if (menuItem != 0) { PostMessage(hWnd, WM_SYSCOMMAND, menuItem, 0); } 

This required the following declarations...

private const int WM_SYSCOMMAND = 0x0112; private const int TPM_RIGHTBUTTON = 0x0002; private const int TPM_RETURNCMD = 0x0100; [DllImport("User32.dll")] public static extern int PostMessage(int hWnd, int Msg, int wParam, int lParam); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.