Taskbar is a special desktop toolbar introduced in Windows 95 in Windows 95, which provides a great convenience of quickly accessing computer resources, and the status bar (hereinafter, the notification bar) is undoubtedly on the taskbar. More special windows. Programmaker can call the API function shell_notifyicon Send a message to the notification bar to add, delete, or modify the icon. When the mouse or keyboard event occurs on the icon, the system will send a pre-defined message to the application, the notification bar processes the callback function. Will be automatically adjusted to make corresponding processing. Relevant articles to achieve the above functions are ponding, and details are not described herein. This article discusses several more in-depth problems in the notification bar program and its implementation methods in Delphi.
l New version of Windows operating system introduced cartoon style bubble tips and related event notifications
l Case Explorer.exe crashes and restarts the automatic recovery of the bar icon
l Select the appropriate pop-up time for the notification bar icon shortcut menu
l Mouse Double-click the event to avoid the avoidance
1 Realization of Balloon Tooltips
1.1 Show bubble tips
We know, the shell_notifyicon function needs to pass a pointer to a particular structure, and the system is determined to add, delete or modify the icon to the notification bar based on the information included in this structure. The conventional definition of this structure is as follows:
_Notifyicondataa = Record
CBSIZE: DWORD;
// The size of this structure
Wnd: hwnd;
/ / Receive the window handle of the notification message
Uid: uint;
// icon logo (you can add multiple icons)
Uflags: uint;
/ / Indicate which fields in this structure are valid
UcallbackMessage: uint;
// Receive notification of the program defined
Hicon: Hicon;
// icon handle
Sztip: array [0..63] of ansichar;
/ / The prompt information displayed when the mouse is icon
END;
Balloon Tooltips (Figure 1) is a new behavior of the notification bar icon included in the operating system (Windows Me / 2000 / XP, excluding Windows 9x), which is equipped with the Internet Explorer 5 and the above version browser. The new version of the Notifyicondata structure is defined to support bubble tips. This article named TNOTIFYICONDATA50 in this article, its object pascal definition and related field meanings are shown below:
TNotifyicondata 50 = Record
The first seven field definition is basically the same as _Notifyicondataa
Uflags: uint;
// uflags field adds a constant definition
Nif_State: DWSTATE, DWSTATEMASK field is valid
NIF_INFO: SZINFO, Utimeout, Szinfotitle,
Dwinfoflags field is valid
Nif_gUID: Reserved value
DWState: DWORD;
// icon status
NIS_HIDDEN: Icon is hidden
NIS_SHAREDICON: Icon is shared
DwStatemask: DWORD;
/ / Indicate which bits of DWState can be read
Such as: set to NIS_HIDEN, indicating that the icon hidden state can be read
Szinfo: array [0..255] of
Ansichar;
/ / Save the bubble prompt string
Utimeout: uint;
// Bubble Tip Display Duration
System default settings for the shortest 10 seconds, up to 30 seconds
Szinfotitle: array [0..63] of ansichar;
/ / Save the bubble prompt title
DWINFOFLAGS: DWORD;
/ / Indicate whether the icon is displayed on the bubble prompt
Niif_ERROR: "Error" icon
Niif_info: "Information" icon
Niif_none: No icon
Niif_Warning: "Warning" icon
Niif_icon_mask: reserved value
Niif_nosound: Do not play sound
END;
The following code demonstrates how to implement bubble tips in Delphi.
// {----------------- constant statement ----------------------
Const
Niif_none = $ 00000000;
Niif_info = $ 00000001;
Niif_Warning = $ 00000002;
Niif_ERROR = $ 00000003;
/ / -------------------------------------------------------------------------------------------- --------------------------}
// {------------------ Type declaration --------------------
Type
TBalloontimeout = 10..30; // Bubble Tip Duration, unit is second
TBalloonicondYpe = (// Bubble Tips Information icon Control
Bitnone, // does not display icon
Bitinfo, // "Information" icon (blue)
BitWarning, // "Warning" icon (yellow)
BitError); // "Error" icon (red)
......
END;
// -----------------------------------------------}
// {--------- Fill in the common structure ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Procedure teocsystray.filldataStructure;
Begin
With ficondata do
Begin
CBSIZE: = Sizeof (Tnotifyicondata 50);
Wnd: = fwindowhandle;
Uid: = 0;
Uflags: = nif_message or nif_icon or nif_tip;
// uCallbackMessage, Hicon, SZTIP three fields are valid
Hicon: = ficon.handle;
Strpcopy (sztip, fhang);
UcallbackMessage: = WM_SYSTRAY;
END;
End; // end of procedure FillDataStructure
/ / -------------------------------------------------------------------------------------------- -}
// {--------- Show bubble prompt information ----------------------
Function teocsystray.balloon (title, text: string)
IconType: TBalloonicondype; Timeout: TBalloontimeout: Boolean;
Const
ABALLOONICONTYPES: Array [TBalloonicondype] of byte =
(Niif_none, Niif_info, Niif_Warning, Niif_ERROR); Begin
If FACTIVE THEN / / If the notification bar icon is displayed
Begin // Delete the original bubble tips
FillDataStructure;
With ficondata do
Begin
Uflags: = uflags or nif_info; // Setting the field related to the bubble prompt valid
Strpcopy (szinfo, ''); // Setting the prompt information is empty, delete the bubble prompt
END;
Shell_notifyicon (Nim_Modify, @ficondata);
// The following shows the new bubble tips
FillDataStructure;
With ficondata do
Begin
UFLAGS: = uflags or nif_info;
Strpcopy (SZINFO, TEX);
Utimeout: = timeout;
Strpcopy (Szinfotitle, Title);
Dwinfoflags: = ABALLOONICONTYPES [ICONTYPE];
End {with};
Result: = shell_notifyicon (nim_modify, @ficondata)
end
Else
RESULT: = TRUE;
End; // end of procedure balloon
/ / -------------------------------------------------------------------------------------------- ---}
1.2 Incident notice of bubble tips
Due to the introduction of the new style, the notification bar icon has also increased accordingly. If the notification bar icon implements a bubble tip, the Windows shell will send the WINDOWS shell to the notification bar application when the user moves the mouse pointer to the notification bar icon. One or more of the four messages.
Nin_balloonshow
When the bubble prompt shows the post-shell send this message
NIN_Balloontimeout
When the bubble prompt disappears when the overtime disappears, the housing sends this message.
NIN_Balloonhide
When the bubble prompt disappears (for example, the notification bar icon is deleted) The housing sends this message, but the bubble prompt disappears will not produce this message due to timeout.
NIN_BalloonUserClick
When the user clicks on the mouse (click on the bubble prompt and notification bar icon) housing to send this message
With the support of Delphi's powerful message package, the above four messages can be easily enabled for the use of four events for developers. Simply, the four messages are received during a hidden window in the control (creating a hidden window.) The four messages are received during the window message processing of the relevant article. The exemplary code is mapped to the four events. The demonstration code is as follows:
Procedure Teocsystray.WndProc (var Msg: tMessage);
Begin
......
Case msg.lparam of
WM_LBUTTONDOWN:
......
WM_RBUTTONDBLCLK:
......
Else if msg.lparam = nin_balloonshow life // bubble prompt
Begin
IF assigned (fonballoonshow)
FonballoonShow (Self)
end
Else if msg.lparam = nin_balloonhide the // Bubble Tip Disappeared due to timeout
Begin
IF Assigned (Fonballoonhide) THEN
Fonballoonhide (Self)
end
Else if msg.lparam = nin_balloontimeout the // Bubble tips disappear Begin
IF assigned (fonballoontimeout) THEN
Fonballoontimeout (Self)
end
Else if msg.lparam = nin_balloonuserclick dam // User Click on the mouse
Begin
IF assigned (fonballoonclick)
Fonballoonclick (Self)
end
Else
Msg.Result: = DefWindowProc (FwindowHandle, Msg.msg, Msg.wParam, Msg.lparam);
END;
End; // end of procedure WndProc
2 WINDOWS error results in reconstruction of icons when the enclosure Explorer restarts
I believe many of the Windows users have encountered this situation: an unexpected error occurs when running a program, causing the shell Explorer.exe crashes to restart (ie, Explorer.exe is re-running after being turned off), the taskbar is also disappearing after disappearing Generate, but the application disappears in the notification bar, although these programs are still running, but they will never interact with users through the notification bar icon. In order to avoid this, Windows provides the corresponding mechanism.
In the Windows operating system installed in Internet Explorer 4.0 and above, when the taskbar is established, the housing will send a notification message to all top applications, which is the case where the housing is registered to the system with a string "taskbarcreated" as the parameter. The notification bar icon should be re-added after receiving the message after receiving the message.
The implementation process in Delphi is as follows:
Initialization
MsgtaskBarrestart: = registerWindowMessage ('taskbarcreated');
1. The message processing process of the main window, the blocking taskbar rebates the message, and the operation of re-add icons.
Procedure TMAINFORM.WNDPROC (Var Message: tMessage);
Begin
......
IF message.msg = msgtaskbarrest atten
Begin
TRAYICON.ACTIVE: = false; // Delete Notification Bar Icon
TRAYICON.ACTIVE: = true; // Add notification bar icon
END;
......
Inherited WNDPROC (Message);
End; // end of wndproc
It is worth mentioning that if the automatic recovery is packaged as a control, it will bring convenience in future development. However, since the outer casing only sent a notification to all top-level applications, it is difficult to encapsulate. Because the callback function of the notification bar icon can only receive a limited number of messages such as WM_XBUTTONDOWN, WM_XBUTTONUP, and all window messages cannot be received.
The solution is to use the setwindowlong function. By passing to it into the GWL_WndProc parameter, you can change the window process of one window. Simply save the window process pointer of the application window when you create a control, and point to a new window processing in the control, you can respond to all window messages in the control (including the taskbar reconstruction message) When the control is destroyed, the saved original window process pointer will be restored, and details will not be described here.
3 Timer with shortcut menu with the notification bar icon
This section discusses a problem that should be noted when writing notification bar applications, that is, the timing problem pops up in the shortcut menu. Windows provides several mouse messages (events) for the notification bar icon, then we should write the code that pops up the shortcut menu is written in which event? Don't rush to answer "in the mousedown event", in fact, this seemingly simple problem, but there is a small amount. Many software (some even known as professional software) also or less ignore this problem. First, you need to clarify the general principles in a software design, namely: a chance to be given to confirm whether he selects his choice. This has many examples in software design. Big aspects, most common, such as users choose to delete files, should be confirmed. Small aspects, such as the routine processing of the mouse in Windows, there is also a confirmation action. In general, the procedures in Windows are the response of the mouse event: After the user releases the mouse, he considers him to confirm the click operation. Take the Button as an example. For Windows standard buttons, users can move the mouse to the button area before pressing the mouse before the mouse is not released. Then, the pop-up of the window system menu in Windows, when the user presses the mouse button on the window title bar, release the mouse to the title bar, so that the system menu will not pop up, ie, equivalent to the user cancellation This time.
Follow this principle, the pop-up of the notification bar shortcut menu should obviously happen when the user releases the mouse button, that is, the WM_XBUTTONUP message will happen to ensure that the user can cancel it before release the mouse, and should not simply put the pop-up menu. The code is placed in the message response of WM_XBUTTONDOWN. Throughout the procedure included with the Windows operating system, it is true.
4 Mouse Double-click the event to avoid the avoidance
Friends who write a notification bar app probably have encountered this situation: If you write a response mouse click (WM_XBUTTONUP) and double-click (WM_XBUTTONDBLCLK), then click the event when the user doubles the mouse. In practical applications, you typically want to click and double-clicking the two operations independently, and they should not affect each other. For this problem, some software uses "ostrich tactics", not responding to the event (ie, the WM_XBUTTONUP message is not responding), only responds to the double-clicking event, this is not a solution, but wasting the incident, countless . With the following analysis, we will see a more satisfactory solution.
4.1 Principle Analysis
In Windows, no messages that represent the mouse click, click the event to be defined as the mouse in the visual programming language such as Delphi, so clicking the event is typically triggering in WM_XButtonup. And double-click the event, it has a clear definition in Windows. When the user doubles any mouse button, it actually sends four messages in Windows: WM_XButtondown, WM_XBUTTONUP, WM_XBUTTONUP. Obviously, if you respond to the WM_XBUTTONUP message, you will inevitably trigger a click when you respond to the WM_XBUTTONUP message.
Our goal is to handle the double-click event separately, just introduce a delay mechanism. Let the timer start timing when WM_XBUTTONDOWN occurs, check if the WM_XBUTTONDBLCLK has happened after the timeout, and if you have happen, you have triggered a double-clicking event, otherwise, click the event. The key is how long is it right? There is no meaning, and it may happen when it may take time when it is timeout. Obviously, at least the time interval between two clicks in two clicks, this time can be available at the system API function getDoubleclicktime. 4.2 Solution
According to the following steps, the code to the notification bar icon control can be modified (Note "X" in the message such as WM_XButtonUp can be "L", "M", "B", indicating the left mouse button, the middle button, right button ).
A. Define two variables fmousedblclicked and fmouseup, which are used to indicate whether double-clicking and mouse loosening have occurred, all initialized to False.
B. Add a TTIMER class member variable ftimer to the TeoctrayIn control, and initialize it in the OnCreate event:
Constructor teocsystray.create (Aowner: Tcomponent);
Begin
......
FMOUSEDBLCLICKED: = false;
FMOUSEUP: = false;
Ftimer: = TTIMER.CREATE (Self);
With ftimer do
Begin
Enabled: = false;
Interval: = getDoubleClicktime; // The time interval between the clock is assigned to double-click.
Ontimer: = onbuttontimer; // Set the clock timeout response process.
END;
......
End; // end of create
C. The state of the above two variables is set in response to different messages during the hidden window message processing of the aforementioned overload.
Procedure Teocsystray.WndProc (var Msg: tMessage);
Begin
......
Case msg.lparam of
WM_XBUTTONDOWN:
Begin
......
FMOUSEDBLCLICKED: = false; // Double-click has not happened
FMouseUp: = false; // mouse is not loose
Ftimer.enabled: = false; // End the last delay
Ftimer.enabled: = true; // Start Delay
END;
WM_XBUTTONUP:
FMouseUp: = true; // Set the mouse has been released, easy Timer check
WM_XBUTTONDBLCLK:
Begin
FMOUSEDBLCLICKED: = true; // Setup Double-click the flag already
Trigger double-click event;
END;
Else
Msg.Result: = DefWindowProc (FwindowHandle, Msg.msg, Msg.wParam, Msg.lparam);
END;
End; // end of wndproc
D. Judging the mouse state in the delay handler, trigger a click event.
Procedure teocsystray.onbuttontimer (sender: TOBJECT);
Begin
Ftimer.enabled: = false;
IF (not fmousedblclicked) and fmouseup kilovers have not happen and the mouse has been released
Begin
Trigger click event;
Trigger the mouseup event;
END;
End; // end of procedure ONBUTTONTIMER, in this way, click the event to behave as WM_XBUTTONDOWN, Click, WM_XButtonup, and double-click the incident as WM_XBUTTONDOWN, WM_XBUTTONDBLCLK (filtered two MW_XBUTTONUP messages), thereby avoiding double-click incident Trigger a click event.
5 summary
There are still many topics about the programming of the notification bar icon, such as dynamic switching icons, responding to MouseLeave and MouseEnter events, etc., in practice, it is difficult to face.
6 reference address
Windows Notification Bar Icon Advanced Programming Overview