Improvisado:
Para que una aplicación arranque desde el inicio, debes agregar una clave al registro del sistema. VB no te permite hacerlo con métodos nativos, pero con la API de windows es posible realizar dicha labor.
Windows arranca desde el inicio todas las aplicaciones que esten registradas bajo la clave "HKEY_CURRENT_USER\Software\Microsoft\Windows\Curr entVersion\Run" del registro de sistema, así que tu primer problema se reduce a registrar la ruta de tu programa allí.
En cuanto a poner un ícono en SysTray, pues tampoco es problema usando la API, el problema es poner un menú contextual u otra monerías.
Te dejo aquí un pequeño ejemplo, aunque a un nivel muy básico, pero te pueden servir como punto de partida.
Una cosa más. A mi me parece muy molesto cuando instalo una aplicación y arranca sin consultarme al inicio, o me pone un ícono en SysTray. Eso debería ser decidido por el usuario, y por lo mismo, en el ejemplo hay también una función para quitar la aplicación del arranque.
Necesitas incluir en un formulario 3 botones y un PictureBox. Se mostrará el icono del formulario en systray.
Código:
Option Explicit
'************************
'Icono en SysTray
'************************
Private Const WM_LBUTTONUP = &H202
Private Type NOTIFYICONDATA
cbSize As Long
hWnd As Long
uID As Long
uFlags As Long
uCallbackMessage As Long
hIcon As Long
szTip As String * 128
End Type
Private Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" ( _
ByVal dwMessage As Long, _
lpData As NOTIFYICONDATA) As Long
'************************
'Aplicación al inicio
'************************
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" ( _
ByVal hKey As Long, _
ByVal lpSubKey As String, _
ByVal ulOptions As Long, _
ByVal samDesired As Long, _
ByRef phkResult As Long) As Long
Private Declare Function RegCreateKeyEx Lib "advapi32.dll" Alias "RegCreateKeyExA" ( _
ByVal hKey As Long, _
ByVal lpSubKey As String, _
ByVal Reserved As Long, _
ByVal lpClass As String, _
ByVal dwOptions As Long, _
ByVal samDesired As Long, _
ByRef lpSecurityAttributes As Any, _
ByRef phkResult As Long, _
ByRef lpdwDisposition As Long) As Long
Private Declare Function RegSetValueEx Lib "advapi32.dll" Alias "RegSetValueExA" ( _
ByVal hKey As Long, _
ByVal lpValueName As String, _
ByVal Reserved As Long, _
ByVal dwType As Long, _
ByRef lpData As Any, _
ByVal cbData As Long) As Long
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
Private Declare Function RegDeleteValue Lib "advapi32.dll" Alias "RegDeleteValueA" ( _
ByVal hKey As Long, _
ByVal lpValueName As String) As Long
Private Const HKEY_CURRENT_USER As Long = &H80000001
Private Const KEY_ALL_ACCESS As Long = &HF003F 'Combinación de todos los permisos para
'trabajar con el registro
Private nfIcnDat As NOTIFYICONDATA
Private Sub RegAppToLoadOnStart()
Dim hKey As Long
Dim lAction As Long
Dim sFullPath As String
'Indicamos que deseamos abrir/crear una carpeta en el registro, en
'HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
'con el tipo de dato REG_DWORD; que se mantendrá después de reiniciar.
'Si la función se ejecuta sin error, hKey contiene el handler de la
'carpeta, y lAction contiene un indicador de la operación realizada (Abrir o crear)
RegCreateKeyEx HKEY_CURRENT_USER, _
"Software\Microsoft\Windows\CurrentVersion\Run", _
0&, "REG_DWORD", 0&, _
KEY_ALL_ACCESS, ByVal 0&, hKey, lAction
If hKey <> 0 Then
'Guardamos la ruta del programa en el registro con el handler
'obtenido en la llamada a la función anterior. La clave en el
'registro corresponde al nombre de la aplicación (puede ser otro valor),
'el tipo de dato es string terminada en null, y el dato almacenado en
'la clave es la ruta completa del programa.
sFullPath = App.Path & "\" & App.EXEName & ".exe"
RegSetValueEx hKey, App.EXEName & ".exe", 0&, 1&, ByVal sFullPath, Len(sFullPath)
'liberamos el handler
RegCloseKey hKey
End If
End Sub
Private Sub UnregAppToLoadOnStart()
Dim hKey As Long
'Abrimos el folder del registro donde están registradas las ap.
'que arrancan con el sistema.
RegOpenKeyEx HKEY_CURRENT_USER, _
"Software\Microsoft\Windows\CurrentVersion\Run", _
0&, KEY_ALL_ACCESS, hKey
If hKey <> 0 Then '¿existe la carpeta en el registro?
'Existe, entonces borramos la clave nuestra
RegDeleteValue hKey, App.EXEName & ".exe"
'liberamos el handler
RegCloseKey hKey
End If
End Sub
Private Sub Command1_Click()
RegAppToLoadOnStart
End Sub
Private Sub Command2_Click()
UnregAppToLoadOnStart
End Sub
Private Sub Command3_Click()
With nfIcnDat
.hWnd = Picture1.hWnd 'Control que recibirá las notificaciones
.uID = Me.Icon
.uFlags = 7& 'Mensajes, icono y ToolTip
'Las notificaciones seran recibidas en Picture1_MouseUp
'al soltar el botón izquierdo. En realidad Windows nos notificará
'de todos los eventos del mouse, pero este es un truco fácil para no
'definir una función subclassing. En lugar de obtener el valor de X en
'Picture1_MouseUp obtendremos el código del evento. Sólo tenemos que
'interceptar el que nos interese (ver referencia de mensajes de windows)
.uCallbackMessage = WM_LBUTTONUP
.hIcon = Me.Icon.Handle
.szTip = "Haz click para restaurar la ventana" & Chr(0)
.cbSize = Len(nfIcnDat)
End With
Shell_NotifyIcon 0&, nfIcnDat
Me.Hide
End Sub
Private Sub Form_Load()
Me.ScaleMode = vbPixels
Picture1.ScaleMode = vbPixels
Picture1.Visible = False
With Me
.Width = 3435: .Height = 1875
.Caption = "Load on Start / SysTray"
End With
With Command1
.Caption = "Registrar Clave"
.Left = 8: .Top = 8
.Width = 85: .Height = 34
End With
With Command2
.Caption = "Eliminar Clave"
.Left = 8: .Top = Command1.Top + Command1.Height + 8
.Width = 85: .Height = 34
End With
With Command3
.Caption = "Minimizar en SysTray"
.Top = 6: .Left = 135
.Width = 80: .Height = 80
End With
End Sub
Private Sub Form_Unload(Cancel As Integer)
Shell_NotifyIcon 2&, nfIcnDat
End Sub
Private Sub Picture1_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
If X = WM_LBUTTONUP Then
Me.Show
Shell_NotifyIcon 2&, nfIcnDat
End If
End Sub
Como te dije, no es muy sencillo poner menus contextuales en systray (al menos no sé hacerlo sin subclassing), pero si buscas en internet más información de la función Shell_NotifyIcon, seguramente podrás hacer una mejor aplicación.
Hasta luego.