Windows Notification Bar Icon Advanced Programming Overview

xiaoxiao2021-03-06  222

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

转载请注明原文地址:https://www.9cbs.com/read-128894.html

New Post(0)