Develop the program with VB

Source: Internet
Author: User
A small icon appears in the system tray area (that is, the time area in the lower right corner of the desktop) when many software are running. It serves as a sign for program running, you can use the menu popped up by the small icon to control the application status. In this example, we provide a complete pallet program. We can see how to use the shell_policyicon API function to add, delete, and change the pallet icon; in addition, this example shows how to add a right-click menu and floating prompt for the tray icon.

The Program (attached) uses shell_policyicon, SendMessage, CallWindowProc, SetWindowLong, and other API functions. shell_policyicon is the main function used to add, delete, and change the system tray area (taskbar status area) so let's take a look at the Declaration and parameters of this function:

Before using the API function, you must declare the following in the program:

Declare Function shell_policyicon Lib "shell32.dll" Alias "shell_policyicona" (ByVal dwMessage As Long, lpData As policyicondata) As Long

  
The meanings of parameters are as follows:

Parameter: Meaning
DwMessage is the message setting value. It can be the following common values: 0, 1, 2
NIM_ADD = 0 add icon to system status bar
NIM_MODIFY = 1 modify the icon in the system status bar
NIM_DELETE = 2 Delete the icon in the system status bar

LpData is used to input the policyicondata data Data Structure Variable. Its structure is as follows:

Type policyicondata

CbSize As Long is the length of the policyicondata data structure.
HWnd As Long is set As a window handle
Uid As Long is the ID value set by the icon
UFlags As Long sets whether uCallbackMessage, hIcon, and szTip are valid
UCallbackMessage As Long message number
HIcon As Long icon displayed on the status bar
SzTip As String * 64 prompt message
End Type

The return value is Long. A value of non-zero indicates success, and a value of zero indicates failure.

Before using this API function, we should first define the structure type policyicondata:

Public Type policyicondata
CbSize As Long HWnd As Long
Uid As Long UFlags As Long
UCallbackMessage As Long
HIcon As Long
SzTip As String * 64
End Type

Define the NOTIFYICONDATA variable TheData to record the data for setting the tray icon.

Private TheData As policyicondata

Then we can use this function to set the system tray icon. The specific method is as follows:

1. Add an icon

With TheData
. Uid = 0
. HWnd = frm. HWnd 'frm. HWnd is the handle of the main form of the program.
. CbSize = Len (TheData)
. HIcon = frm. Icon. Handle 'frm. Icon. Handle points to the main form Icon
. UFlags = NIF_ICON
. UCallbackMessage = TRAY_CALLBACK
'The function is to allow the returned message, which will be explained in detail in the next section.
. UFlags =. UFlags Or NIF_MESSAGE
. CbSize = Len (TheData)
End
Shell_policyicon NIM_ADD, TheData
'According to the previous definition of NIM_ADD, set it to "add mode", and then add
   

2. Delete the icon

With TheData
. UFlags = 0
End
Shell_policyicon NIM_DELETE, TheData
'According to the previous definition of NIM_DELETE, set it to "delete mode"
   
3. Change the icon

With TheData
. HIcon = pic. Handle
'Pic is an image crazy PictureBox that stores Icon files
. UFlags = NIF_ICON
End
Shell_policyicon NIM_MODIFY, TheData
'According to the previous definition of NIM_MODIFY, set it to "change mode"
   
4. Add floating prompt information for the icon

With TheData
. SzTip = tip & vbNullChar
'Tip is a string that stores the prompt information.
. UFlags = NIF_TIP
'Specifies that you want to set the floating prompt
End
Shell_policyicon NIM_MODIFY, TheData
'According to the previous definition of NIM_MODIFY, set it to "Modify mode"
   

With the above code, we can add, delete, and change the system tray icon as needed, and add floating prompt information on the System icon. But the tray icon is isolated at this time, and we cannot use it to control the behavior of the application. What should we do? Don't worry. Please read down ......

If you download (source program download) and run this sample program, you will find that if we right-click the tray icon, a right-click menu will pop up. If you click the corresponding menu item, the main program form will change accordingly, so that you can control the program's behavior. If the main form is minimized, we click the left button on the tray icon to restore the form to its original size. In fact, the implementation of the above functions depends on the message mechanism of the WINDOWS operating system. It is not easy to fully understand this mechanism, but we can understand it in the following words.

Think of WINDOWS as a human brain. It receives, processes, and sends a variety of information to our various organs (of course, it is a metaphor for various applications ), that is to say, it is the hub of the message. Every application (even every button, Tag, form, and so on) will be allocated a window process WINDOWPROC at runtime, the window process is used to receive and process messages sent from the operating system (there is actually a Message Queue). Generally, this window process is specified by the operating system, it automatically responds to and processes some WINDOWS messages (such as moving forms, maximizing, minimizing, and error messages ). Well, let's stop and ask a question. Can we write a program to process these messages? The answer is yes, but I still need to use the power of API functions. How can I use it? Let's take a look at the definitions and parameters of these API functions first.

The program uses SendMessage, CallWindowProc, SetWindowLong, and other API functions. The SendMessage function sends a message to a window. The CallWindowProc function sends the message to a window; the SetWindowLong function is used to set properties for the specified window in the window structure. Before using the API function, you must declare the following in the program:

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 meanings of parameters are as follows:

CallWindowProc Function

Parameter meaning
LpPrevWndFunc Long, the original window process address
HWnd Long, window handle
Msg Long, sent message
WParam Long, message type. For details, refer to the wParam parameter table.
LParam Long, which varies with the wParam Parameter
The return value is Long, which varies according to the sent message.

SetWindowLong function:

Parameter TD> meaning
Hwnd Long, the handle of the window for which information is obtained
NIndex Long, please refer to the nIndex parameter descriptions of the GetWindowLong Function
DwNewLong Long, the new value of the window information specified by nIndex

Return Value: Long, the previous value of the specified data.

SendMessage function:

Parameter meaning
Hwnd Long, handle of the window to receive the message
WMsg Long, message identifier
WParam Long, depending on the message
LParam Any, depending on the message

The return value is Long, determined by the specific message.

To write a program to process a message, we must first change the window attribute, from the original default window process to the Message Processing Process written by ourselves. The method is to use the SetWindowLong function to obtain the address of the default window process, and then switch to the address of the window process written for ourselves. The specific implementation method is as follows:

'Gwl _ WNDPROC: Obtain the address of the Window Process in the window. AddressOf is the address function, and NewWindowProc is the process we write.
OldWindowProc = SetWindowLong (frm. HWnd, GWL_WNDPROC, AddressOf
NewWindowProc)
 
Then write the following code in the NewWindowProc function. Note that the red TRAY_CALLBACK in the following code is a message sent from the tray icon. You need to let the tray icon send back the message, you must specify the following when adding a tray icon:

Public Function NewWindowProc (ByVal HWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
'If the user clicks the icon in the tray, it determines whether the left button is clicked or right-click
If Msg = TRAY_CALLBACK Then
'If you left click
If lParam = WM_LBUTTONUP Then
'At this time, the form state is minimized.
If TheForm. WindowState = vbMinimized Then _
'Restore to the form state before Minimization
TheForm. WindowState = TheForm. LastState
TheForm. SetFocus
Exit Function
End If
End If
'If you right-click
If lParam = WM_RBUTTONUP Then
', Right-click the menu
TheForm. PopupMenu TheMenu
Exit Function
End If
End If
'If messages of other types are passed to the original default Window Function
NewWindowProc = CallWindowProc (OldWindowProc, HWnd, Msg, wParam, lParam)
End Function

In this way, the message from the tray icon is obtained and processed. The problem now is how to control the status of the main form of the program after the right-click menu pops up, at this time, we need to use the SendMessage function to send messages to the main form, such as maximization, minimization, close, and movement. The specific code implementation is as follows, where HWnd is the handle of the main form, WM_SYSCOMMAND indicates that the system control message is sent. SC _MOVE, SC _SIZE, and SC _RESTORE are the messages to be sent:

'When the "move" item on the right-click Tray Icon menu is clicked
Private Sub mnuTrayMove_Click ()
SendMessage HWnd, WM_SYSCOMMAND, SC _MOVE, 0 &
End Sub
'When the "Restore" item on the right-click menu of the tray icon is clicked
Private Sub mnuTrayRestore_Click ()
SendMessage HWnd, WM_SYSCOMMAND, SC _RESTORE, 0 &
End Sub
'When the "exit" item on the right-click menu of the tray icon is clicked
Private Sub mnuTraySize_Click ()
SendMessage HWnd, WM_SYSCOMMAND, SC _SIZE, 0 &
End Sub

Finally, we should remind you that the address of the window process must be restored to the default value when the program exits, and the tray icon should be removed.

The source code is provided as follows:

'---------------------------------------------
'Demonstration using the system tray Program
'---------------------------------------------
'Program description:
'This is a complete program instance that uses the system tray, including
Now: add the tray icon, delete the tray icon, and dynamically change the tray icon,
'Add floating prompt information for the tray icon, right-click the tray icon
'Menu and other content.
'------- Name ------------------- function ------------
'Form1 main form
'Mnufile, mnuFileExit file menu, menu item
'Mnutray, mnuTrayClose... right-click the tray area menu and choose menu items
'---------------------------------------------

Option Explicit

The 'laststate variable indicates the original status of the main form.
Public LastState 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]
'Call the window function of a window and send a message to that window. This function will not return unless the message is processed. SendMessageBynum,
'Sendmessagebystring is the "type security" Declaration Form of the function.

'[Return value]
'Long, determined by the specific message

'[Parameter table]
'Hwnd ----------- Long, the handle of the window to receive the message

'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 HWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

'Indicates that the system command is sent.
Private Const WM_SYSCOMMAND = & H112
Private Const SC _MOVE = & HF010 &
Private Const SC _RESTORE = & HF120 &
Private Const SC _SIZE = & HF000 &

'When the main form is loaded
Private Sub Form_Load ()

'Windowstate attribute of the form. A value is returned or set to specify the visual status of the form window during runtime.
'Vbnormal 0 (default value) is normal.
'Vbminimized 1 is minimized as an icon)
'Vbmaximized 2 maximized (expanded to the maximum size)
If WindowState = vbMinimized Then
LastState = vbNormal

Else
LastState = WindowState
End If

'Add the icon to the pallet function. See the description in the module.
'Note that this is the entry from the main program to the module. In this example, the shell_policyicon function is not directly called.
AddToTray Me, mnuTray

SetTrayTip "tray icon demonstration, right-click the pop-up menu"
End Sub

'When the Form1 size of the main form changes, the available attribute Enabled of the menu item in the right-click menu mnuTray is changed accordingly.
Private Sub Form_Resize ()
Select Case WindowState

'If the form is minimized, set the menu item "maximize" and "Restore" to available,
And set "minimal", "move", and "size" to unavailable.
'If you right-click the tray icon, you will find that the unavailable items become gray.
Case vbMinimized
MnuTrayMaximize. Enabled = True
MnuTrayMinimize. Enabled = False
MnuTrayMove. Enabled = False
MnuTrayRestore. Enabled = True
MnuTraySize. Enabled = False

'Form Maximization
Case vbMaximized
MnuTrayMaximize. Enabled = False
MnuTrayMinimize. Enabled = True
MnuTrayMove. Enabled = False
MnuTrayRestore. Enabled = True
MnuTraySize. Enabled = False

'Normal status
Case vbNormal
MnuTrayMaximize. Enabled = True
MnuTrayMinimize. Enabled = True
MnuTrayMove. Enabled = True
MnuTrayRestore. Enabled = False
MnuTraySize. Enabled = True
End Select

If WindowState <> vbMinimized Then LastState = WindowState
End Sub

'Ensure that the tray icon is deleted when the program exits.
Private Sub Form_Unload (Cancel As Integer)
RemoveFromTray
End Sub

When the "exit" item in the "file" menu is clicked
Private Sub mnuFileExit_Click ()
Unload Me
End Sub

'When the "exit" item on the right-click menu of the tray icon is clicked
Private Sub mnuTrayClose_Click ()
Unload Me
End Sub

'When the maximize option on the right-click Tray Icon menu is clicked
Private Sub mnuTrayMaximize_Click ()
WindowState = vbMaximized
End Sub

'When the "minimize" item on the right-click Tray Icon menu is clicked
Private Sub mnuTrayMinimize_Click ()
WindowState = vbMinimized
End Sub

'When the "move" item on the right-click Tray Icon menu is clicked
Private Sub mnuTrayMove_Click ()
SendMessage HWnd, WM_SYSCOMMAND ,_
SC _MOVE, 0 &
End Sub

'When the "Restore" item on the right-click menu of the tray icon is clicked
Private Sub mnuTrayRestore_Click ()
SendMessage HWnd, WM_SYSCOMMAND ,_
SC _RESTORE, 0 &
End Sub

'When the "exit" item on the right-click menu of the tray icon is clicked
Private Sub mnuTraySize_Click ()
SendMessage HWnd, WM_SYSCOMMAND ,_
SC _SIZE, 0 &
End Sub
'-----------------------------------------
'Code in the module is as follows:
'-----------------------------------------
Option Explicit

Public OldWindowProc As Long
Public TheForm As Form
Public TheMenu As Menu
'[VB Declaration]
'Destare 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]
'The process of sending a message to a window using this function

'[Return value]
'Long, varies based on the sent message

'[Parameter table]
'Lpprevwndfunc ----- Long, the original window process address

'Hwnd ------------ Long, window handle

'Msg ------------ Long, sent message

'Wparam ----------- Long, message type. For details, refer to the wParam parameter table.

'Lparam ----------- Long, which varies with the wParam Parameter

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

'[VB Declaration]
'Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

'[Description]
'Set the information for the specified window in the window structure

'[Return value]
'Long, the previous value of the specified data

'[Parameter table]
'Hwnd ----------- Long, the handle of the window for which you want to obtain information

'Nindex --------- Long, please refer to the description of the nIndex parameter of the GetWindowLong Function

'Dwnewlong ------ Long, the new value of the 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

'[VB Declaration]
'Destare Function shell_policyicon Lib "shell32.dll" Alias "shell_policyicona" (ByVal dwMessage As Long, lpData As same yicondata) As Long

'[Description]

'[Parameter table]
'Parameter dwMessage ---- set the message value. It can be the following common values: 0, 1, and 2.

'Nim _ ADD = 0 ADD the icon to the system status bar
'Nim _ MODIFY = 1. MODIFY the icon in the system status bar.
'Nim _ DELETE = 2 DELETE the icon in the system status bar

The 'lpdata-parameter is used to input the policyicondata data Data Structure Variable. We also need to define its structure in the "module" as follows:

'Type policyicondata
'Cbsize As Long 'must be filled with the length of the policyicondata data Data Structure
'Hwnd As Long is set As the window handle
'Uid As Long is the ID value set by the icon
'Uflags As Long is used to set the following three parameters: uCallbackMessage, hIcon, and szTip.
'Ucallbackmessage As Long message No.
'Hicon As Long 'icon displayed on the status bar
'Sztip As String * 64 prompt information
'End Type

'---- The uCallbackMessage, hIcon, and szTip parameters should also be declared as the following constants in the module:
'Public Const NIF_MESSAGE = 1
'Public Const NIF_ICON = 2
'Public Const NIF_TIP = 4

Declare Function shell_policyicon Lib "shell32.dll" Alias "shell_policyicona" (ByVal dwMessage As Long, lpData As policyicondata) As Long

Public Const WM_USER = & H400
Public Const WM_LBUTTONUP = & H202
Public Const WM_MBUTTONUP = & H208
Public Const WM_RBUTTONUP = & H205
Public Const TRAY_CALLBACK = (wm_user+ 1001 &)
Public Const GWL_WNDPROC = (-4)
Public Const GWL_USERDATA = (-21)
Public Const NIF_ICON = & H2
Public Const NIF_TIP = & H4
Public Const NIM_ADD = & H0
Public Const NIF_MESSAGE = & H1
Public Const NIM_MODIFY = & H1
Public Const NIM_DELETE = & H2

'Record the Data Type of the data set Tray Icon policyicondata
Public Type policyicondata
CbSize As Long
HWnd As Long
Uid As Long
UFlags As Long
UCallbackMessage As Long
HIcon As Long
SzTip As String * 64
End Type

'Thedata variable record set Tray Icon data
Private TheData As policyicondata
'*************************************** ******
'New window procedure -- the address of the window function is changed using the SetWindowLong function in the main program, and the message is switched to NewWindowProc for processing.
'*************************************** ******
Public Function NewWindowProc (ByVal HWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

'If the user clicks the icon in the tray, it determines whether the left button is clicked or right-click
If Msg = TRAY_CALLBACK Then
'If you left click
If lParam = WM_LBUTTONUP Then
'At this time, the form state is minimized.
If TheForm. WindowState = vbMinimized Then _
'Restore to the form state before Minimization
TheForm. WindowState = TheForm. LastState
TheForm. SetFocus
Exit Function
End If
End If
'If you right-click
If lParam = WM_RBUTTONUP Then
', Right-click the menu
TheForm. PopupMenu TheMenu
Exit Function
End If
End If

'If messages of other types are passed 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)

'Save the current form and menu Information
Set TheForm = frm
Set TheMenu = mnu

'Gwl _ WNDPROC: Obtain the window function address of the window.
OldWindowProc = SetWindowLong (frm. HWnd, GWL_WNDPROC, AddressOf NewWindowProc)

'Knowledge bit by bit: HWnd attribute
'Return the form or control handle. Syntax: object. HWnd
'Note: in the Microsoft Windows operating environment, each form and control in the application is provided.
'Assign a handle (or hWnd) to identify them. The hWnd attribute is used for Windows API calls.

'Add the main form icon to the tray
With TheData
. Uid = 0' forgot? Refer to the previous content, Uid icon serial number, which is useful for animation icons.
. HWnd = frm. HWnd
. CbSize = Len (TheData)
. HIcon = frm. Icon. Handle
. UFlags = NIF_ICON 'indicates the icon to be set.
. UCallbackMessage = TRAY_CALLBACK
. UFlags =. UFlags Or NIF_MESSAGE 'indicates to set the icon Or return information to the main form. This sentence cannot be omitted.
. CbSize = Len (TheData) 'Why? When adding an icon, we need to make it return information
End With 'to the main form. Or means setting and returning messages at the same time.
Shell_policyicon NIM_ADD, TheData 'according to the previous definition of NIM_ADD, set to "add mode"
End Sub
'*************************************** ******
'Delete the icon in the system tray
'*************************************** ******
Public Sub RemoveFromTray ()
'Delete the icons in the tray
With TheData
. UFlags = 0
End
Shell_policyicon NIM_DELETE, TheData 'according to the previous definition of NIM_DELETE, set to "delete mode"

'Restore the original settings
SetWindowLong TheForm. HWnd, GWL_WNDPROC, OldWindowProc
End Sub
'*************************************** ******
'Add a floating prompt to the icon in the tray (that is, the prompt note that appears when the mouse moves up)
'*************************************** ******
Public Sub SetTrayTip (tip As String)
With TheData
. SzTip = tip & vbNullChar
. UFlags = NIF_TIP 'indicates that you want to set the floating prompt
End
Shell_policyicon NIM_MODIFY, TheData 'according to the previous definition of NIM_MODIFY, set to "Modify mode"
End Sub
'*************************************** ******
'Set the tray icon (not used in this example. It is very useful if you want to dynamically change the icon displayed in the tray)
'Example: 1. display the animation icon. (You must have guessed it! Use the Timer control to continuously call this process. Place the animation in the pic array)
'2. Different icons are displayed when the program is in different States. The method is similar.
'Try it if you are interested.
'*************************************** ******
Public Sub SetTrayIcon (pic As Picture)
'Determine if the image is saved as an icon
If pic. Type <> vbPicTypeIcon Then Exit Sub

'Change the icon to the icon stored in the pic.
With TheData
. HIcon = pic. Handle
. UFlags = NIF_ICON
End
Shell_policyicon NIM_MODIFY, TheData
End Sub

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.