How to display menu by NotifyIcon without displaying the form in Taskbar

Mansour_Dalir 2,016 Reputation points
2024-08-10T19:15:01.1466667+00:00

I have a form with a NotifyIcon and a ContextMenuStrip and I want to display the menu by clicking on the notification, but unfortunately it is displayed in the taskbar. Why? I tried setting the ShowInTaskbar property to false, but it didn't work.Tip Only with Mouse Left Click. Here is my code:

Public Class frmNotificaction
    Public WithEvents MyNotify As New NotifyIcon With {.Icon = My.Resources.Icon1}
    Dim MyMenu As New ContextMenuStrip
    Private Sub frmNotificaction_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        MyMenu.Items.Add("Item1")
        MyMenu.Items.Add("Item2")
        MyNotify.Visible = True
    End Sub
    Private Sub MyNotify_MouseClick(sender As Object, e As MouseEventArgs) Handles MyNotify.MouseClick
        If e.Button = MouseButtons.Left Then
            Me.ShowInTaskbar = False
            MyMenu.Show(Cursor.Position)
        End If
    End Sub
End Class
Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,921 questions
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,729 questions
VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,778 questions
0 comments No comments
{count} votes

Accepted answer
  1. KOZ6.0 6,580 Reputation points
    2024-08-27T20:08:05.86+00:00

    After you show the window, you can set the owner for the window.

    Private Sub MyNotify_MouseClick(sender As Object, e As MouseEventArgs) Handles MyNotify.MouseClick
        If e.Button = MouseButtons.Left Then
            Me.ShowInTaskbar = False
            MyMenu.Show(Cursor.Position)
            SetWindowLongPtr(MyMenu.Handle, GWL_HWNDPARENT, Handle)
        End If
    End Sub
    
    Private Const GWL_HWNDPARENT As Integer = -8
    
    <DllImport("user32.dll", EntryPoint:="SetWindowLongPtr", SetLastError:=True)>
    Private Shared Function SetWindowLongPtr64(hWnd As IntPtr, nIndex As Integer, dwNewLong As IntPtr) As IntPtr
    End Function
    
    <DllImport("user32.dll", EntryPoint:="SetWindowLong", SetLastError:=True)>
    Private Shared Function SetWindowLong32(hWnd As IntPtr, nIndex As Integer, dwNewLong As Integer) As Integer
    End Function
    
    Private Shared Function SetWindowLongPtr(hWnd As IntPtr, nIndex As Integer, dwNewLong As IntPtr) As IntPtr
        If IntPtr.Size = 8 Then
            Return SetWindowLongPtr64(hWnd, nIndex, dwNewLong)
        Else
            Return New IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()))
        End If
    End Function
    
    1 person found this answer helpful.

3 additional answers

Sort by: Most helpful
  1. Michael Taylor 56,856 Reputation points
    2024-08-11T03:10:22.72+00:00

    Not sure I fully follow your situation but it sounds like you want to "minimize your app" to the system tray and then allow the user to restore the window when the tray icon is shown. To implement that you don't need to muck with the taskbar setting. When the user minimizes your window then instead just hide the main window. It will disappear from the taskbar but the tray icon should still be visible. When the user clicks the tray icon (or a menu inside it) then show your window again.

    Note that many apps provide the option to show a tray icon only when minimized so in that case you should handle the minimize request on the window by hiding it but show the tray icon. When the window is restored then hide the tray icon and show the window again.

    You can google for how to do this as there are lots of examples of how to get it working.

    0 comments No comments

  2. Jiachen Li-MSFT 33,446 Reputation points Microsoft Vendor
    2024-08-12T09:17:56.4033333+00:00

    Hi @Mansour_Dalir ,

    You need to explicitly set the position where the ContextMenuStrip should appear.

        Private Sub MyNotify_MouseClick(sender As Object, e As MouseEventArgs) Handles MyNotify.MouseClick
            If e.Button = MouseButtons.Left Then
                Me.ShowInTaskbar = False
                MyMenu.Show(Cursor.Position)
            End If
        End Sub
    
    

    Best Regards.

    Jiachen Li


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment". Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  3. Stephan Berger 0 Reputation points
    2025-02-06T10:38:05.2+00:00

    Finally found a simple, working solution!

    ContextMenuStrip from a left click on a Notify Icon

    I just wonder why this wasn't mentioned here, on a microsoft page?

    In short: the default right-click p/invokes SetForegroundWindow before showing the menu.

    So, if You add this to Your left-click event, the menu behaves as usual when opening with a right-click:

    [DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
    public static extern bool SetForegroundWindow(HandleRef hWnd);
    private void notifyIcon1_MouseClick(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            SetForegroundWindow(new HandleRef(this, this.Handle));
            this.contextMenuStrip1.Show(this, this.PointToClient(Cursor.Position));
        }
    }
    

    Cheers, Stephan

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.