Many software runs at the system tray area (which is the area of the display time in the lower right corner of the desktop), which can control the status of the application as a logo running as a program. This example gives a functionally complete tray program. We can see how to add, delete, change the tray icon with the API function shell_notify; and the example also demonstrates the method of adding the right-click menu and floating prompt for the tray icon.
Program (attached) uses the API function such as shell_notifyicon, callmessage, callwindowproc, setwindowlong, where shell_notifyicon is the main function, it is used to add, delete, change the icon of the system tray area, so let's take a look. Declaration and parameters of this function:
Before using the API function, you must declare the procedure as follows:
Declare function shell_notifyicon lib "shell32.dll" alias "shell_notifyicona" (Byval Dwmessage As Long, LPDATA AS Notifyicondata) AS Long
The significance of each of these parameters is as follows:
Parameters: DwMessage is the message setting value, which can be the following constant values: 0, 1, 2nim_add = 0 Add Icons to the system status bar NIM_MODIFY = 1 Modify the icon nim_delete = 2 in the system status bar NIM_DELETE = 2 Delete System Status Bar Icon
LPDATA is used to introduce the Notifyicondata data structure variable, which is shown below:
Type Notifyicondata CBSIZE AS Long You need to fill in the length of the Notifyicondata data structure HWND As long Set to the window UID as long for the ID value UFlags as long set up UCALLBACKMESSAGE, HICON, SZTIP is effective UCALLBACKMESSAGE AS long message number Hicon as long Display icon SZTIP AS STRING * 64 prompt message End Type on the status bar
Return value long, non-zero means success, zero expire failure
We should first define the structural type Notifyicondata before using this API function:
PUBLIC TYPE NOTIFYICONDATA CBSIZE AS Long Hwnd As Long UidbackMessage As Long Hicon As Long Sztip As String * 64 End Type
Then define a NOTINICONDATA variable thatData to log the data set up the tray icon.
Private Tiedata As Notifyicondata We can use this function to set the system tray icon, the specific method is as follows:
1, add icons
With theData .uid = 0 .hWnd = frm.hwnd 'frm.hwnd is the handle of the program master form. CBsize = len (theData). HICON = frm.icon.handle' frm.icon.handle points to the main form of the main form .Uflags = nif_icon .uscallbackMessage = TRAY_CALLBACK 'The role is allowed to return messages, which will explain in detail in the next section. .Uflags = .uflags or nif_message .cbsize = len (saidData) End with shell_notifyicon nim_add, theData 'is set to "Add Mode" based on the previous definition NIM_ADD, then add 2, delete icon
WITH THEDATA .UFLAGS = 0nd with shell_notifyicon nim_delete, theData 'is set to "Delete Mode" based on the previous definition NIM_DELETE
3, change the icon
WITH THEDATA. HICON = PIC.Handle 'PIC is a picture mad Picturebox, stored icon file .uflags = nif_iconend with shell_notifyicon nim_modify, theData' is set to "Change Mode" based on the previous definition NIM_MODIFY
4, add floating prompt for icons
WITHDATA .SZTIP = TIP & VBNULLCHAR 'TIP is a string String, stores prompt information .uflags = nif_tip' indicates setting end with shell_notifyicon nim_modify, theData ', set to "Modify Mode" based on the previous definition NIM_MODIFY
Through the above code, we can add, delete, change the system tray icon according to yourself, and add floating prompt information on the system icon. But at this time, the pallet icon is isolated, we can't use it to control the behavior of the application, what should I do? Don't worry, please see it down ...
If you download (source program download) and run this case, you will find that if we click on the right mouse button on the tray icon, a right-click menu will pop up. If you click the appropriate menu item, the program host window will change so that the behavior of the program can be controlled. And if we click on the left button on the tray icon, we will return to the original size on the pallet icon. In fact, it is not easy to implement the message mechanism of the Windows operating system. It is not easy to understand this mechanism, but we can understand it as follows.
Way the Windows operating system as a human brain, it receives, processes, and sends a variety of information to our various organs (of course, each application), that is, it is the hub of the message. Each application (even each button, label, form, etc. is collectively referred to as a window) is assigned a window process WindowProc, which is received and handled by this window process (actually exists. A message queue), usually this window process is specified by the operating system, which will automatically respond and process some Windows messages (such as form movement, maximizing, minimizing, error information, etc.). Ok, let's stop first, ask a question, can these news be handled by our write a program? The answer is affirmative, but how can I use the power of the API function? Let's take a look at the definitions and parameters of these API functions. The API function such as SendMessage, CallWindowProc, SetWindowlong, where the SendMessage function is sent to a window; the CallWindowProc function is used to send a message to a window process; and use the setWindowlong function to specify the window structure Window setting properties. Before using the API function, you must declare the procedure as follows:
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal HWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal HWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal HWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As long
The significance of each of these parameters is as follows:
CallWindowProc function
Parameter Signs LPPREVWNDFUNC Long, the original window process address hwndlong, window handle Msglong, sent message wparamlong, message type, reference wPARAM parameter table lparamlong, depending on the WPARAM parameter
Return value long, varies depending on the message sent
Setwindowlong function:
The parameter meaning hwnd long, the handle of the window of the window to obtain information, please refer to the Nindex parameter of the getWindowlong function DWNEWLONGLONG, the new value of the window information specified by NINDEX
Return value long, specify the previous value of the data
SendMessage function:
Parameter meaning hwnd long, the handle of the window of the message to receive the message WMSGLONG, the message identifier WPARAMLONG, depending on the message LParamany, depending on the message
Return value long, determined by the specific message
We have to write a program to handle the message, and must first change the properties of the window, from the original window process to process the message to handle the message. The method is to use the setWindowlong function to get the address of the default window process, and then turn to the address of the window procedure written by our own, the specific implementation method is as follows: 'GWL_WndProc gets the address of the window of the window, addressof is a home address function, NewWindowProc Is our process OldwindowProc = setWindowlong (frm.hwnd, gwl_wndproc, addressof newwindowproc)
Then writes the following code in the NewWindowProc function, you need to pay attention to the red TRAY_CALLBACK in the following code is a message from the tray area icon. To make the tray icon back message, you must specify when adding a tray icon:
Public Function NewWindowProc (Byval Hwnd As Long, Byval Msg As Long, Byval WParam As Long "If the user clicks the icon in the tray, the judgment is the left button or the right-click IF msg = tray_callback If you click Left button if lparam = wm_lbuttonup the 'and the state of the form is minimized when IF themem.WindowState = VBMINIMIMized THEEN_' Restores the form status before the minimum formation = theform.lastState theform .Setfocus exit function end if Endiff, if you click Right-click If lparam = WM_RBUTTONUP THEN ', the right-click menu Theform.popUpMenu Themeu exit function end if end if' If it is other type of message, passed to the original default window function newWindowProc = CallWindowProc (OldwindowProc, HWND, MSG, WPARAM, LPARAM) end function
In this way, we have gone and handle messages from the tray icon. Now the problem is how to control the status of the program main form after the right-click menu pop-up, then we need to use the SendMessage function to maximize the main form. Minimize, shut down, move, etc., the specific code is implemented, where hWnd is the handle of the main form, and WM_SYSCOMMAND indicates that the message sent is the system control class, SC_MOVE, SC_SIZE, SC_RESTORE is the message to send:
'When the "Move" item on the tray icon context menu is clicked Private Sub mnuTrayMove_Click () SendMessage HWnd, WM_SYSCOMMAND, SC_MOVE, 0 & End Sub' "recovery" when is clicked Private Sub mnuTrayRestore_Click () SendMessage HWnd on the tray icon context menu , Wm_sysCommand, SC_RESTORE, 0 & End Sub 'tray icon, "Exit" item on the right mole, private sub mnutraysize_click () sendMessage HWnd, WM_SYSCOMMAND, SC_SI, 0 & End Sub finally reminds you, be sure to put the window when the program exits The address of the process is restored to the default, and the tray icon is shifted.
In order to learn, the source code is provided below:
'-------------------------------------------' Using the system tray Program Demo '-------------------------------------------' Description: 'This is a comparison of program instances of the system tray, including': add a tray icon, delete the tray icon, dynamically change the tray icon, 'Add a floating prompt information for the tray icon, to implement the mouse button of the tray icon Wait for content. '------- Name --------------------------------' Form1 Main Facts' Mnufile, MnufileExit File menu, menu item 'mnutray, mnutrayclose ... tray area Right-click menu, menu item' -------------------------------------------------------------------------------------------------------------------------- -------------- Option Explicit'LastState variable The role is to indicate the main form of the original state as integer '[VB declaration]' private declare function sendMessage lib "user32" alias " SendMessagea "(Byval HWND As Long, Byval WMSG As Long, Byval WParam As Long, LPARAM AS ANY) AS Long '[Description]' calls a window function to send a message to that window. This function will not return unless the message is handled. SendMessageBynum, 'sendMessageBystring is the "Type Security" declaration form of this function' [return value] 'long, determined by the specific message' [Parameter Table] 'hwnd ---------- Long, to receive a message The window of the window 'WMSG ----------- long, message identifier' wparam --------- long, depending on the message 'lparam ------- - Any, depending on the message private declare function sendMessage LIB "User32" Alias "SendMessagea" (Byval WMSG As Long, Byval WParam As Long, LParam As Any) AS Long 'indicates that the system command private const WM_SYSCOMMAND = & H112Private const SC_MOVE = & HF010 & Private const SC_RESTORE = & HF120 & Private const SC_SIZE = & HF000 & 'when the main form is loaded Private Sub Form_Load ()' form WindowState property, return or set a value that is used to specify the operation form Visual status of the window 'VBNORMAL 0 (default) is normal.
'Vbminimized 1 Minimize (Minimize an icon)' VBMaximized 2 Maximum (expand to maximum size) if windowstate = vbminimized thenlastate = vbnormaleLselastState = WindowsTateEnd if 'Add icon to the tray function, see the explanation in the module' This is the entry from the main program to the module. In this case, the shell_notifyicon function addtotray me, the mnutRaySettRaytip "tray icon, click Right-click" End Sub 'When the main form FORM1 size changes, the right-click Men Mnutray The available property of the menu item enabledprivate sub form_resize () Select Case WindowState 'If the form minimizes, the "maximize" "recovery" "Restore" is set,' and "Move" "Size" three item set is not available. 'If you then right-click on the tray icon, you will find not undesignated grayed Case vbMinimizedmnuTrayMaximize.Enabled = TruemnuTrayMinimize.Enabled = FalsemnuTrayMove.Enabled = FalsemnuTrayRestore.Enabled = TruemnuTraySize.Enabled = False' window when the body is maximized case vbNormalmnuTrayMaximize.Enabled = TruemnuTrayMinimize.Enabled = TruemnuTrayMove.Enabled = TruemnuTrayRestore.Enabled = FalsemnuTraySize.Enabled under case vbMaximizedmnuTrayMaximize.Enabled = FalsemnuTrayMinimize.Enabled = TruemnuTrayMove.Enabled = FalsemnuTrayRestore.Enabled = TruemnuTraySize.Enabled = False 'general state of = TrueEnd Selectif WindowsTate <> VBMinimized Ten LastState = WindowsTateEnd S Ub 'guarantees that the "exit" item that removes the tray icon private subovefromtrayend sub' "File" menu when the program exits, the private sub mnufileexit_click () unload mend sub 'tray icon is right-click "Exit" "When the item is clicked, the Private Sub MnutRayclose_Click () unload mend sub 'tray icon is right-mounted to the" Maximum "item by clicks, the private sub mnutraymaximize_click () windowState = VBMaximized Sub' tray icon is right-click menu" Minimize "item when you click Private Sub mnuTrayMinimize_Click () WindowState = vbMinimizedEnd Sub 'when "move" item on the tray icon context menu is clicked Private Sub mnuTrayMove_Click () SendMessage HWnd, WM_SYSCOMMAND, _SC_MOVE, 0 & End Sub'
"Recovery" on the tray icon context menu when the item is clicked Private Sub mnuTrayRestore_Click () SendMessage HWnd, WM_SYSCOMMAND, _SC_RESTORE, 0 & End Sub ' "exit" when the item is clicked Private Sub mnuTraySize_Click () SendMessage HWnd on the tray icon context menu, WM_SYSCOMMAND , _SC_SIZE, 0 & End Sub '---------------------------------------' Code in the module: '---------------------------------------- Option Explicitpublic OldwindowProc As LongPublic TheForm As FormPublic TheMenu As Menu '[VB statement]' declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal HWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long AS long '【Description】' This function sends a message to a window process '[Return value]' long, change the message based on the message sent, '[Parameter Table]' LPPREVWNDFUNC ----- Long, the original window process address 'Hwnd -------------- Long, window handle' msg -------------- Long, send message 'wparam ------- ---- Long, message type, refer to WPARAM parameter table 'lParam ----------- long, depending on the WPARE Function CallWindowProc LIB "User32" Alias "CallWindowProca" (BYVAL LPPREVWNDFUNC AS) Long, Byval Hwnd As Long, Byval Msg As Long, Byval WParam As LONG, BYVAL LPARAM AS LO Ng) As long '[VB Declaration]' Private Declare Function SetWindowlong LIB "User32" Alias "SetWindowlonga" (Byval Nindex As Long, Byval Dwnewlong As Long) AS Long '[Description] "In the window structure Specified window setting information '[Return value]' long, specify the previous value of the data '[Parameter Table]' hwnd ---------- Long, the handle of the window that wants to get the information of the information 'NINDEX -------- Long, please refer to the NINDEX parameter of the getWindowlong function 'dwnewlong ------ long, new value for window information specified by NINDEX Declare Function SetWindowlong Lib "User32" Alias "SetWindowlonga"
(ByVal HWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long 'statement] [VB' Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long ' [Description] '[Parameter Table]' Parameter DWMessage ---- For the message setting value, it can be the following constant values: 0, 1, 2'nim_add = 0 Add Icons to the system status bar 'NIM_MODIFY = 1 Modify the icon 'nim_delete = 2 in the system status bar' NIM_DELETE = 2 Delete Icon '' ' 'CBSIZE AS Long needs to fill in the length of the Notifyicondata data structure' HWND As long Set to the window 'UID as long for the ID value of the icon' uflags as long to set the following three parameters uCallbackMessage, Hicon, Sztip is effective 'UCALLBACKMESSAGE AS Long Measured' Hicon As Long Displayed on the status bar 'SZTIP AS STRING * 64 Tips' end type' ---- in which parameters UCALLBACKMESSAGE, HICON, SZTIP should also be declared in the module as the following constant : 'Public Const NIF_MESSAGE = 1'Public Const NIF_ICON = 2'Public Const NIF_TIP = 4Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As LongPublic Const WM_USER = & H400Public Const WM_LBUTTONUP = & H2 02Public Const WM_MBUTTONUP = & H208Public Const WM_RBUTTONUP = & H205Public Const TRAY_CALLBACK = (WM_USER 1001 &) Public Const GWL_WNDPROC = (-4) Public Const GWL_USERDATA = (-21) Public Const NIF_ICON = & H2Public Const NIF_TIP = & H4Public Const NIM_ADD = & H0Public Const NIF_MESSAGE = & H1Public Const nim_modify = & h1public const nim_delete = & h2 '
Setting data recorded in the data type of tray icon NOTIFYICONDATAPublic Type NOTIFYICONDATAcbSize As LongHWnd As LongUid As LongUFlags As LongUCallbackMessage As LongHIcon As LongSzTip As String * 64End Type'TheData variable data record setting tray icon Private TheData As NOTIFYICONDATA '******* ************************************** New window procedure - SETWINDOWLONG in the main program The function changes the address of the window function, and the message is turned from newwindowproc 'hand' ********************************************** ********* PUBLIC FUNCTION NewWindowProc (Byval HWnd As Long, Byval Msg As Long, Byval WParam As Long, Byval LPARM AS Long) If the user clicks the icon in the tray, the judgment is clicked. Left button or right button if msg = tray_callback life 'If you click on left button if lparam = wm_lbuttonup the', the state of the form is minimized when the system is minimized, and the form is restored to the form before the minimum. state TheForm.WindowState = TheForm.LastStateTheForm.SetFocusExit FunctionEnd IfEnd If 'if clicked right If lParam = WM_RBUTTONUP then' right-click menu TheForm.PopupMenu TheMenuExit FunctionEnd IfEnd If the pop-up 'if another type of message is delivered to the original default window Function newWindowProc = CallWindowProc (OldwindowProc, HWND, MSG, WPARAM, LPARAM) end function '**************************************************** ************? Add the icon of the main form (the Form1.ICON attribute can be changed) to the tray '*************************************** ************** Public Sub Addtotray (FRM AS Form, MNU As Menu) Saves Current Forms and Menu Information Set Theform = frMset Themeu = Mnu'GWL_WndProc gets the window function of the window Address OldWindowProc = SetWindowlong (frm.hwnd, gwl_wndproc, addressof newwindowproc) 'Knowledge bit: hwnd property' Returns the handle of the form or control. Syntax: Object.hwnd 'Description: Microsoft Windows running environment, identify them by assigning a handle (or hWnd) to each form and control' in the application. The HWnd property is used for Windows API calls.
'Add the main form icon in the tray with theData.uid = 0' Forgot? Refer to the previous content, the UID icon is used, do animation icons useful .hWnd = frm.hwnd.cbsize = len (theData) .HICON = frm.icon.handle.uflags = nif_icon 'indicates that you want to set icons. MuCallbackMessage = TRAY_CALLBACK .Uflags = .uflags or nif_message 'Indicates to set the icon or return information to the main form, this sentence can not save .cbsize = len (theData)'? We need to add an icon while returning the information end with 'to the main form, or the means means setting up and returns the message shell_notifyicon nim_add, and theData' is set to "Add mode" end sub '* according to the previous definition NIM_ADD. ********************************************** The system tray is deleted Icon '****************************************************** PUBLIC SUB RemoveFromtray () 'icon With TheData.UFlags remove tray = 0End WithShell_NotifyIcon NIM_DELETE, theData' is as defined NIM_DELETE, set to "remove mode" 'restore the original settings SetWindowLong TheForm.HWnd, GWL_WNDPROC, OldWindowProcEnd Sub' **** **************************************** The icon in the tray is floating Tip (that is, the reminder of the mouse moves upward) '******************************************** ********* Public Sub SetTrayTip (tip as String) With TheData.SzTip = tip & vbNullChar.UFlags = NIF_TIP 'indicates to the floating prompts provided End WithShell_NotifyIcon NIM_MODIFY, theData' is as defined NIM_MODIFY, set "Modified mode" end sub '*************************************************** ** 'Set the icon of the tray (not used in this case, if you want to dynamically change the icon displayed in the tray, it is very useful)', for example: 1, display the animation icon (method you must guess, right! Use Timer Control) , Constantly call this process, pay attention to put the animation in the PIC array) '2. When the program is in different states, the different icons are displayed, the method is similar to' interested, try it.