Popup Menu in Taskbar Button

CsFreak

Newcomer
Joined
Jan 18, 2008
Hi Community, :D

Is there a way to have a standard popup menu displayed for an application's taskbar button -- even if the FormBorderStyle of the main window is set to "None"?

(This setting of the form boder style does also remove the popup menu of the taskbar button. The value TRUE for the ControlBox property is obviously ignored)

I have written a little application which draws its own very specific border. That is why I have disabled the standard form borders. However, I want to be allow some standard functions still to be selectable from the task bar button, e.g. Alt-F4 or Minimize/Maximize.

Even a link for further reading is welcome. Maybe I was looking for the wrong tags so far.
 

techmanbd

Junior Contributor
Joined
Sep 10, 2003
Location
Burbank, CA
You may want to look into the Contextmenu from you toolbox. I have messed with it a little a while back, but I feel that is what you are looking for.
 

CsFreak

Newcomer
Joined
Jan 18, 2008
Sure I want to. But -- How do I get access to the Context Menu (or other menu type) of the Taskbar button?
 

techmanbd

Junior Contributor
Joined
Sep 10, 2003
Location
Burbank, CA
Hope this will help you get on your way. Here is what I have done so far. I am using it for the status bar panels.

In the status bar properties, the contextmenu item is set to conMenu, the name I gave to my context menu tool.

This is the context menu routine
Visual Basic:
 Private Sub conMenu_Popup(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles conMenu.Popup
        If conMenu.SourceControl Is statBar Then
            conMenu.MenuItems.Clear()
            conMenu.MenuItems.Add(strDevMenu(1))
            conMenu.MenuItems.Add(strDevMenu(2))
        End If
        'MessageBox.Show("Keeps Going")
    End Sub

When I click on the status bar
Visual Basic:
Private Sub statBar_PanelClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.StatusBarPanelClickEventArgs) Handles statBar.PanelClick
        If e.Button = MouseButtons.Right Then
            Dim strStat As String = e.StatusBarPanel.Text
            strStat = strStat.Substring(0, strStat.IndexOf(":")).ToLower
            strDevMenu(1) = strStat & " connect"
            strDevMenu(2) = strStat & " disconnect"
        End If

Here is where I stopped working on it and moved on as I didn't have alot of time and this wasn't an important feature I was making. But what you need to do is when someone selects something in the context menu, to capture what they selected and make a sub to do what you want it to do.
 

techmanbd

Junior Contributor
Joined
Sep 10, 2003
Location
Burbank, CA
Update:
I have worked with my application and have made progress. Here is what I have done. In order to select a menu item, I had to make an event handlers. Here is what my code looks like as far as the popup menu and event handler sub.
my statBar code is the same as above

revised context menu routine
Visual Basic:
    Private Sub conMenu_Select(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles conMenu.Popup
        If conMenu.SourceControl Is statBar Then
            conMenu.MenuItems.Clear()
            conMenu.MenuItems.Add(strDevMenu(1), New System.EventHandler(AddressOf handleConMenuStatBar)).Checked = boolDevConnected
            conMenu.MenuItems.Add(strDevMenu(2), New System.EventHandler(AddressOf handleConMenuStatBar)).Checked = Not boolDevConnected
        End If
    
    End Sub

Here is my sub for handling the event.
Visual Basic:
    Private Sub handleConMenuStatBar(ByVal sender As System.Object, ByVal e As System.EventArgs)
'Put whatever code you need here after selecting a menu item.
        MessageBox.Show("GOT TO EVENT")
    End Sub
 

CsFreak

Newcomer
Joined
Jan 18, 2008
Dear techmanbd,

thank you very much for your extensive answer. But -- do we have a confusion here? I have no problems with doing a status bar in my window nor with adding any elements to such container.

I am trying to mess around with the button of my application which appears in the TASKBAR when the main window of the application becomes active. What I see there if I do a right mouseclick on that button is a standard system (?) menu with the items Close (F4), Maximize, Minimize,... (see attached image)

My problem is that this popup disappears if I choose to have my main window without frame.

Do you have an idea how I get this popup of the taskbar button for a main window which does not have any frame?

I am currently trying something else: I have the window configured with a standard frame, so I get the popup menu and the events from that menu. But I overwrite a few events which are responsible for the behaviour of the nonclient area of the window. I thing I can get that working but I wished there was a simpler way.....
 

Attachments

  • TaskbarSnap.bmp
    22.3 KB · Views: 19

techmanbd

Junior Contributor
Joined
Sep 10, 2003
Location
Burbank, CA
Yes, sorry there was a misunderstanding on my part. I will look into what you are talking about. For some reason, when I saw taskbar my brain was thinking of the bar at the top of the page of the form.
 

CsFreak

Newcomer
Joined
Jan 18, 2008
Thank you -- this one did it very well! Jocker's solution did not permit to maximize, so I extended his solution a little to allow maximizing of the window. But that would also hide the taskbar.

Meanwhile, I had kept playing and messing around with the window procedure. I think I found an alternative solution which has the same effects as Jocker's solution but also maximizes my window without hiding the taskbar. My trick is to cheat the system and have it believe that the main application window is a standard window with a standard frame and a standard system menu. But I am overriding a few nonclient messages and do my own thing:


private const int HTCLIENT = 1;

private const int WM_NCACTIVATE = 0x86;
private const int WM_NCHITTEST = 0x84;
private const int WM_NCLBUTTONDOWN = 0xA1;
private const int WM_NCCALCSIZE = 0x83;
private const int WM_NCPAINT = 0x85;

protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
// The platform SDK requires that the WM_NCACTIVATE event with a FALSE in wParam is responded to with
// result code TRUE; no result is expected upon WM_NCACTIVATE with a TRUE in wParam.
case WM_NCACTIVATE:
if ((int)m.WParam == 0) m.Result = (IntPtr)1;
break;

// Since there is no nonclient region, any hit is a hit in the client region .....
case WM_NCHITTEST:
m.Result = (IntPtr)HTCLIENT;
break;

// Events WM_NCCALCSIZE, WM_NCLBUTTONDOWN, WM_NCPAINT:
// These events are captured here and not passed to the standard WindowProc. Result 0 is returned to
// the system to indicate normal completion (refer to Platform SDK help)
case WM_NCLBUTTONDOWN:
case WM_NCCALCSIZE:
case WM_NCPAINT:
m.Result = (IntPtr)0;
break;

// All other events are passed to the standard WindowProc and completely handled there
default:
base.WndProc(ref m);
break;​
}
}


Jocker's solution is more elegant (shorter) but......
 

CsFreak

Newcomer
Joined
Jan 18, 2008
Update (2008-01-24) -- I had to learn that my solution has a severe problem:

A roundtrip with minimizing and subsequent return to normal display changes the dimensions of my window. I am trying to figure out why .....
 
Top Bottom