[Migration posts] VC System Tray programming guide

Source: Internet
Author: User

Currently, popular software displays an icon on the system tray. You can click the icon to display or hide the main interface of the software to save space on the taskbar. Right-click the icon to display a menu, display some common functions. So how is this implemented? It's actually very easy. You only need an API function. Let's take a look at it with me ~
First, let's look at a struct:
Typedef struct _ policyicondata {
DWORD cbsize;
Hwnd;
Uint uid;
Uint uflags;
Uint ucallbackmessage;
Hicon;
Tchar sztip [64];
DWORD dwstate; // version 5.0
DWORD dwstatemask; // version 5.0
Tchar szinfo [256]; // version 5.0
Union {
Uint utimeout; // version 5.0
Uint uversion; // version 5.0
} Dummyunionname;
Tchar szinfotitle [64]; // version 5.0
DWORD dwinfoflags; // version 5.0
} Notifyicondata, * ppolicyicondata;
Use this structure to specify information about the tray icon. Version 5.0 indicates the version number of shell DLL. You can use dllgetversion to obtain the dll version of the current system. This part is rarely used for compatibility purposes.
Cbsize: the size of the policyicondata structure, sizeof (policyicondata)
Hwnd: handle for receiving tray notifications
UID: ID of the tray icon. This ID and hwnd uniquely identify a tray icon. Therefore, the ID cannot be repeated. Generally, the ID of the menu associated with the icon is used.
Uflags: a combination of the following values
Nif_icon: indicates that hicon in the structure is valid.
Nif_message: indicates that the ucallbackmessage in the structure is valid.
Nif_tip: indicates that the sztip in the structure is valid.
Nif_state: indicates that the dwstate and dwstatemask values in the structure are valid.
Nif_info: replace the traditional box-type tray prompts with balloon-type tray prompts. The szinfo, utimeout, szinfotitle, and dwinfoflags in the structure are valid.
Ucallbackmessage: A tray message. When a mouse event (such as a move or click) is generated in the tray area, the message is sent to the receiving window for processing.
Hicon: tray icon handle
Sztip: tray prompt character

Well, we will introduce this much. The following receives the shell_policyicon API:
Bool shell_policyicon (
DWORD dwmessage,
Pnotifyicondata pnid
);
Dwmessage: One of the following values
Nim_add: Add tray icon
Nim_delete: Delete the image disk icon
Nim_modify: Modify the tray icon
Nim_setfocus: Version 5.0
Nim_setversion: Version 5.0
Pnid: pointer of policyicondata Structure

Now, let's get down to the point and start programming ~
We will analyze the data in the following steps:
Initialization
Add/modify/remove icons
Add tray message Response Function
Add menu Message Processing Function
(1) initialization
First, declare a policyicondata member variable:
Notifyicondata m_nid;
Then, add a menu resource idr_traymenu and an icon resource idi_red in the resource panel.
Since we want to process the mouse message, first define a user-defined message:
# Define um _ traynotification (wm_user + 100)
Then initialize the members of the structure:
Void inittray ()
{
// Initialize m_nid
M_nid.cbsize = sizeof (policyicondata );
M_nid.hwnd = This-> m_hwnd;
M_nid.uid = idr_traymenu;
M_nid.uflags = nif_icon | nif_tip | nif_message;
M_nid.hicon = afxgetapp ()-> loadicon (idi_red );
Strcpy (m_nid.sztip, "My pallets listen to me ");
M_nid.ucallbackmessage = um_traynotification;
}
The aboveProgram I won't talk much about it. I believe everyone can understand it.
(2) Add/modify/remove icons
This is simpler. Simply call the shell_policyicon function:
// Add an icon to the tray
Void addtray ()
{
Shell_policyicon (nim_add, & m_nid );
}
// Remove the tray icon. Remember to call it when the program exits. Otherwise, the icon will remain on the tray.
Void removetray ()
{
Shell_policyicon (nim_delete, & m_nid );
}
// Modify the icon. I don't need to teach you the dynamic effect on the tray during QQ login.
Void modifytray (uint UID) // The parameter is the ID of the icon to be displayed
{
M_nid.hicon = afxgetapp ()-> loadicon (UID );
Shell_policyicon (nim_modify, & m_nid );
}
(3) Add a tray message Response Function
This is actually a response to custom messages. Forgot? Okay. Let's review it together ~
First, define the message identifier (defined in step 1 ):
# Define um _ traynotification (wm_user + 100)
Then, define the message response function before declare_message_map () in the header file:
Afx_msg lresult ontraynotification (wparam WID, lparam Levent );
The two parameters are the icon ID and mouse event respectively.
Finally, implement this function in the CPP file:
Lresult cxxxdlg: ontraynotification (wparam WID, lparam Levent)
{
If (WID! = M_nid.uid
| (Levent! = Wm_lbuttonup & Levent! = Wm_rbuttonup ))
Return 0;

// load menu
cmenu menu;
If (! Menu. loadmenu (WID)
return 0;
// obtain the pop-up menu
cmenu * psubmenu = menu. getsubmenu (0);
If (! Psubmenu)
return 0;

If (Levent = wm_rbuttonup)
{
// Set the default menu item
: Setmenudefaultitem (psubmenu-> m_hmenu, 0, true );

// Obtain the mouse position
Cpoint mouse;
Getcursorpos (& mouse );

// Set the shortcut menu
: Setforegroundwindow (m_nid.hwnd );
: Trackpopupmenu (psubmenu-> m_hmenu, 0, mouse. X, mouse. Y, 0, m_nid.hwnd, null );
}
Else
{
: Sendmessage (m_nid.hwnd, wm_command, psubmenu-> getmenuitemid (0), 0 );
}

Return 1;
}
The above section is explained one by one. Code :
First, determine whether the ID of the icon that sent the message is equal to the idnumber in m_nid, and then determine whether the received mouse message is left-click the message wm_lbuttonup or right-click the message wm_rbuttonup, if not, the message is not responded.
Load the menu and right-click it to display it. First load the top-level menu with loadmenu (), and then use getsubmenu () to obtain the first-level sub-menu.
When the mouse event is right-clicked, the menu is displayed. Otherwise, use: sendmessage () to send a command message to the receiving window for corresponding processing. : Setmenudefaultitem () is used to set the default menu options, which are displayed in bold. Finally, right-click the trackpopupmenu () function to display the menu. The menu may not disappear immediately as usual, because the window for receiving messages from the pop-up menu must be a foreground window. Call the: setforegroundwindow () function to correct this error.
(4) add menu message processing functions
After selecting an item from the context menu, the Command Message wm_command will be sent, and the message processing function of wm_command will be added to classwizard:
Bool czyjreportdlg: oncommand (wparam, lparam)
{
// Todo: add your specialized code here and/or call the base class
Switch (loword (wparam ))
{
Case id_showhide:
Showwindow (m_bshow? Sw_hide: sw_show );
M_bshow =! M_bshow;
Break;
Case id_exit:
Removetray ();
Postquitmessage (0 );
Break;
Case id_about:
Caboutdlg about;
About. domodal ();
Break;
}

Return cdialog: oncommand (wparam, lparam );
}
The low-byte loword (wparam) of the first parameter wparam identifies the ID of the selected sub-menu and executes the corresponding program according to the selected menu item.
OK. The complete process of writing the pallets is described above. Is it very easy? Of course, the content of tray programming is far more than that. For example, the part of version 5.0 can also add a lot of beautiful effects. You are welcome to discuss it with me!

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.