here is a way to use Alex's NotifyIcon class in your VB app. Instead of translating the whole thing to VB, I kept his NotifyIcon class in a seperate class, not changing anything, and kept it in c#. Create a class using vs.net, then build this DLL. You will add this DLL as a reference in your VB.net project.
Here is the class:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace NotifyClient
{
public class NotifyIcon
{
//Declare click event
public event System.EventHandler Click;
private WindowSink windowSink;
private int uID = 5000;
//Constructor
public NotifyIcon()
{
//Create instance of the MessageWindow subclass
windowSink = new WindowSink(this);
windowSink.uID = uID;
}
//Destructor
~NotifyIcon()
{
Remove();
}
public void Add(IntPtr hIcon)
{
TrayMessage(windowSink.Hwnd, NIM_ADD, (uint)uID, hIcon);
}
public void Remove()
{
TrayMessage(windowSink.Hwnd, NIM_DELETE, (uint)uID, IntPtr.Zero);
}
public void Modify(IntPtr hIcon)
{
TrayMessage(windowSink.Hwnd, NIM_MODIFY, (uint)uID, hIcon);
}
private void TrayMessage(IntPtr hwnd, int dwMessage, uint uID, IntPtr hIcon)
{
NOTIFYICONDATA notdata = new NOTIFYICONDATA();
notdata.cbSize = 152;
notdata.hIcon = hIcon;
notdata.hWnd = hwnd;
notdata.uCallbackMessage = WM_NOTIFY_TRAY;
notdata.uFlags = NIF_MESSAGE | NIF_ICON;
notdata.uID = uID;
int ret = Shell_NotifyIcon(dwMessage, ref notdata);
}
#region API Declarations
internal const int WM_LBUTTONDOWN = 0x0201;
//User defined message
internal const int WM_NOTIFY_TRAY = 0x0400 + 2001;
internal const int NIM_ADD = 0x00000000;
internal const int NIM_MODIFY = 0x00000001;
internal const int NIM_DELETE = 0x00000002;
const int NIF_MESSAGE = 0x00000001;
const int NIF_ICON = 0x00000002;
internal struct NOTIFYICONDATA
{
internal int cbSize;
internal IntPtr hWnd;
internal uint uID;
internal uint uFlags;
internal uint uCallbackMessage;
internal IntPtr hIcon;
//internal char[] szTip = new char[64];
//internal IntPtr szTip;
}
[DllImport("coredll.dll")]
internal static extern int Shell_NotifyIcon(
int dwMessage,ref NOTIFYICONDATA pnid);
[DllImport("coredll.dll")]
internal static extern int SetForegroundWindow(IntPtr hWnd);
[DllImport("coredll.dll")]
internal static extern int ShowWindow(
IntPtr hWnd,
int nCmdShow);
[DllImport("coredll.dll")]
internal static extern IntPtr GetFocus();
#endregion
#region WindowSink
internal class WindowSink : Microsoft.WindowsCE.Forms.MessageWindow
{
//Private members
private int m_uID = 0;
private NotifyIcon notifyIcon;
//Constructor
public WindowSink(NotifyIcon notIcon)
{
notifyIcon = notIcon;
}
public int uID
{
set
{
m_uID = value;
}
}
protected override void WndProc(ref Microsoft.WindowsCE.Forms.Message msg)
{
if (msg.Msg == WM_NOTIFY_TRAY)
{
if((int)msg.LParam == WM_LBUTTONDOWN)
{
if ((int)msg.WParam == m_uID)
{
//If somebody hooked, raise the event
if (notifyIcon.Click != null)
notifyIcon.Click(notifyIcon, null);
}
}
}
}
}
#endregion
}
}
Now take the DLL created from the above code and add it to your VB.net project as a reference.
Here is an example of using the DLL in VB.net:
'Icon must be registered with Project>Properties
'and MUST be 16x16
Imports System
Imports System.Drawing
Imports System.Collections
Imports System.Windows.Forms
Imports System.Data
Imports System.Runtime.InteropServices
Public Class Form1
Inherits System.Windows.Forms.Form
Friend WithEvents MainMenu1 As System.Windows.Forms.MainMenu
#Region " Windows Form Designer generated code "
#End Region
Dim WithEvents NotifyIcon As New NotifyClient.NotifyIcon
<DllImport("coredll.dll")> _
Private Shared Function LoadIcon(ByVal hInst As IntPtr, ByVal IconName As String) As IntPtr
End Function
<DllImport("coredll.dll")> _
Private Shared Function GetModuleHandle(ByVal lpModuleName As String) As IntPtr
End Function
Shared Sub main()
Application.Run(New Form1)
End Sub
Public Sub EHandler(ByVal sender As System.Object, ByVal e As System.EventArgs)
MessageBox.Show("Tray Icon clicked! ")
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
AddHandler NotifyIcon.Click, AddressOf EHandler
Dim hIcon As IntPtr
hIcon = LoadIcon(GetModuleHandle(Nothing), "#32512")
NotifyIcon.Add(hIcon)
End Sub
Private Sub Form1_Closing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.Closing
NotifyIcon.Remove()
End Sub
End Class
I still havent figured out how to register a 32x32 Icon for the windows/programs screen, and still get a handle on the 16x16 icon for the tray. My .ICO file includes both.