Interacting with user with user using icons on the taskbar
Author: Ben Lee
We sometimes need to prepare some programs that are only monitored in the background, in order not to interfere with the running interface of the foreground program and the unnecessary window, it should be invisible. At the same time, the user should know that the program is running and reaches the purpose of interacting with the user. Displaying an icon in a static notlation area in the right end of the taskbar and responds to the user's mouse action is the current very popular way, which reflects the Windows 95-friendly interface style. The following is an example of a SDI (single document interface) program to describe the main steps of developing such programs using Microsoft Visual C 5.0.
First, to make the program's main window is invisible, and do not appear on the taskbar, do these two points, you need to set the style and extended style of the main Border window, respectively:
Bool CMAINFRAME :: PrecreateWindow (CreateStruct & Cs)
{
cs.style = ws_popup; // Make the main window
cs.dwexstyle | = WS_EX_TOOLWINDOW; / / Do not display the task button
Return CFrameWnd :: PrecreateWindow (CS);
}
Second, use the system function shell_notifyicon to display an icon in the notification area of the taskbar. The prototype of this function is:
Winshellapi Bool WinApi Shell_notifyicon
DWORD DWMESSAGE,
PNOTIFYICONDATA PNID
);
The next example is displayed is an icon of the main border window, which can actually display any icons:
INT CMAINFRAME :: OnCreate (lpcreatestruct lpcreatestruct)
{
...
Notifyicondata TND;
Tnd.cbsize = sizeof (notifyicondata);
Tnd.hwnd = this-> m_hwnd;
TND.UID = IDR_MAINFRAME;
Tnd.uflags = nif_message | NIF_ICON | NIF_TIP;
TND.UCALLBACKMESSAGE = WM_Liben;
Tnd.hicon = loading (AFXGETITISTANCEHANDE (), makeintResource (iDR_mainframe);
STRCPY (TND.SZTIP, "Tip Information");
Shell_Notifyicon (NIM_ADD, & TND);
...
}
Before calling this function, you need to determine the value of its parameters, one of which is a structure with a NOTIFYICONDATA type. Its prototype is:
Typedef struct _notifyicondata {// NID
DWORD CBSIZE;
Hwnd hwnd;
UINT UID;
UINT UFLAGS;
Uint ucallbackmessage;
Hicon Hicon;
Charsztip [64];
Notifyicondata, * pNOTIFYICONDATA;
In a member of this structure, CBSIZE is the number of bytes of this structure, and hWnd is a handle of the window that accepts the message issued by the icon. The UID is the ID of the displayed icon, and UFLAGS indicates several members of the rest (Hicon, " The value of uCallbackMessage and Sztip is valid, uCallbackMessage is a custom message, and when the user acts on the icon, the message is sent to the window specified in the HWND member, which can define the message to be WM_USER 100. Hicon is a handle that is displayed, SZTIP is a character array, and when the mouse is on the icon, the content is displayed in the floating prompt information box. Another parameter of the shell_notifyicon function is a predefined message that can take one of the following: NIM_ADD, NIM_DELETE, or NIM_MODIFY, indicate the add icon, delete icon, or modify icon. Finally, interact with the user, that is, when the user is clicked or double-click the left mouse button or right-click, at least the willingness to respond to the will to terminate the program. It has been mentioned that when the user performs a mouse action on the icon, a custom message will be issued to the window specified in the HWND member, which is specified by the UcallbackMessage member (WM_Liben in the previous example, with a value of WM_USER 100) . Therefore, our task is to respond to custom messages in the HWND window:
Void CMAINFRAME :: ONLIBEN (WPARAM WPARAM, LPARAM LPARAM)
{
UINT UID; / / Issue ID of the icon of the message
Uint umousemsg; // mouse action
Point Pt;
UID = (uint) wparam;
Umousemsg = (uint) LPARAM;
IF (umousemsg == wm_rbuttondown) // If you are right-click
{
Switch (UID)
{
CASE IDR_MAINFRAME: // If it is our icon
GetCursorpos (& PT); // Get the mouse position
... // Perform the corresponding operation
Break;
...
DEFAULT:
...
}
}
Return;
}
It should be noted that the first type of prototype of the message mapping function must be given in the header file of the window class:
AFX_MSG Void Onliben (WPARAM WPARAM, LPARAM LPARAM);
And to add the corresponding entry in the message map in the CPP file, be careful to add {{AFX_MSG_MAP (CMAINFRAME) and //}} AFX_MSG_MAP:
Begin_MESSAGE_MAP (CMAINFRAME, CFRAMEWND)
// {{AFX_MSG_MAP (CMAINFRAME)
ON_WM_CREATE ()
ON_COMMAND (ID_APP_EXIT, ONAPPEXIT)
//}} AFX_MSG_MAP
ON_MESSAGE (WM_LIBEN, ONLIBEN)
END_MESSAGE_MAP ()
When the program ends, you need to delete the icon in the notification area. At this time, the shell_notifyicon function should also be called, but the first parameter is Nim_Delete that deletes the icon:
Void CMAINFRAME :: onappexit ()
{
// Todo: add your command handler code here
Notifyicondata TNID;
Tnid.cbsize = sizeof (notifyicondata);
TNID.hwnd = this-> m_hwnd;
TNID.UID = idR_mainframe; // Guaranteed to delete our icon shell_notifyicon (Nim_Delete, & TnID);
AfxPostQuitMessage (0);
}
Through similar steps, the reader can respond to other messages, complete more advanced interaction, and will not be described here. The above is the experience of the author, and it is definitely nothing, welcome to correct.