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 will discuss two more in-depth problems and their implementation in Delphi. 1. Windows Errors cause the case where the enclosure Explorer.exe is restarted to be automatically restored 2, and the auto-recovery feature is packaged in the control in other programs.
Keywords: notification bar, window process
1 Reclass EXPLORER Restart When the notification bar icon automatically recovers I believe that many Windows users have encountered this situation: an unexpected error occurs when running a program, causing the shell Explorer.exe to restart (ie, Explorer.exe is turned off) Run), the taskbar is also regenerated after disappearing, but the application disappears in the notification bar, although these programs are still running, but they can noify to 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: 1). Define a constant variable MsgTaskBarrestart to save the message reconstructed by the taskbar. 2). In the INITIALIALIZATION section of the main program or in "taskbarcreated" in the OnCreate event (That is, as a message "taskbarcreated" is the same, because the same parameter registration will get the same message, "Taskbarcreated" is already registered by the shell when Windows is started).
Initialization MsgtaskBarrestart: = RegisterWindowMessage ('taskbarcreated');
3). The message processing process of the main window, the blocking taskbar reconstruction message, and the operation of re-add icons.
procedure TMainForm.WndProc (var Message: TMessage); begin ...... if Message.Msg = MsgTaskbarRestart then begin TrayIcon.Active: = False; // delete the notification area icon TrayIcon.Active: = True; // add a notification bar icon end; ... inherited WndProc (Message); end; // end of wndproc
2 Auto Recovery Function package Since the shell is only sent to all top-level applications, this has brought certain difficulties to pack automatic recovery. 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 method described in this section will enable the window message to be received in the control, thereby implementing the package of automatic recovery. The key to solving the problem is that the setWindowlong function, incoming the GWL_WndProc parameter to it, can change the window process of a 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 raw window process pointer will be restored. Implementation code is as follows (where "..." is slightly easier to implement, delete the notification bar icon and other functions and procedures): teocsystray = class (tcomponent) private ... Factive: boolean; fparentWindow: TwinControl; // Parent window FNewWndProc : Pointer; // New Parent Window Process Pointer FPREVWNDPROC: POINTER; / / The original parent window process pointer ftaskbarcreated: tnotifyevent; // taskbar rebuild event ... procedure setActive (value: boolean); // Setup controls work procedure HookParentForm; // replace the parent window's window procedure procedure UnHookParentForm; // restore the parent window's window procedure procedure HookWndProc (var AMsg: TMessage); // new parent window procedure protected procedure DoTaskBarCreated; dynamic; // trigger the taskbar reconstruction event public constructor Create (AOwner: TComponent); override; destructor Destroy; override; property Active: boolean read fActive write SetActive; property OnTaskBarCreated: TNotifyEvent read FTaskBarCreated write FTaskBarCreated;
IMPLEMENTATION
Type THACK = Class (TWINCONTROL); // to access the default window processing in the parent window protected domain
Var msgtaskbarcreated: integer; // Rebuild messages by the system registration
constructor TEoCSysTray.Create (AOwner: TComponent); begin inherited Create (AOwner); ...... FActive: = false; FNewWndProc: = MakeObjectInstance (HookWndProc); // Create a new window procedure pointer FPrevWndProc: = nil; if (AOwner <> NIL) and (aowner is tform) THEN / / Gets Father Window FParentWindow: = TwinControl (Aowner) Else FparentWindow: = Application.mainform; ... End; // end of contructor
destructor TEoCSysTray.Destroy; begin ...... FDestroying: = True; FParentWindow: = nil; FreeObjectInstance (FNewWndProc); FNewWndProc: = nil; ...... inherited Destroy; end; // end of destructorprocedure TEoCSysTray.SetActive (Value: boolean); begin IF value <> factive; if not (csdesigning in componentstate) Then // control is not in design status Case value of true: begin ... hookparentform; // Replace the window process of the father window ... End; false : Begin ... unhookparentform; // Restore the window process of the parent window ... end; end; end; end; // end of procedure setAntive
procedure TEoCSysTray.HookParentForm; // replace the window procedure of the parent window var P: Pointer; begin if Assigned (FParentWindow) and not ((csDesigning in FParentWindow.ComponentState) or (csDestroying in FParentWindow.ComponentState) or FDestroying) then begin FParentWindow.HandleNeeded ; P: = Pointer (GetWindowLong (FParentWindow.Handle, GWL_WNDPROC)); if (P <> FNewWndProc) then begin FPrevWndProc: = P; SetWindowLong (FParentWindow.Handle, GWL_WNDPROC, LongInt (FNewWndProc)); // replace the parent window Window process End; end; end; // end of procedure hookparentform
procedure TEoCSysTray.UnHookParentForm; // restore the window procedure of the parent window begin if Assigned (FParentWindow) then begin if Assigned (FPrevWndProc) and FParentWindow.HandleAllocated and (Pointer (GetWindowLong (FParentWindow.Handle, GWL_WNDPROC)) = FNewWndProc) then SetWindowLong (FParentWindow .Handle, GWL_WNDPROC, LONGINT (FPREVWndProc); / / Restoring the window process end of the parent window; fprevwndproc: = nil; end; // end of procedure unhookparentform
procedure TEoCSysTray.HookWndProc (var AMsg: TMessage); begin if Assigned (FParentWindow) then begin with AMsg do begin if Msg = MsgTaskbarCreated then // received taskbar re-establishment message DoTaskBarCreated; // trigger event reconstruction task bar if Assigned (FPrevWndProc) the window procedure then // call the original window Result: = CallWindowProc (FPrevWndProc, FParentWindow.Handle, Msg, WParam, LParam) else Result: = CallWindowProc (THack (FParentWindow) .DefWndProc, FParentWindow.Handle, Msg, WParam, LParam); if Msg = WM_DESTROY then // window is being destroyed UnHookParentForm; // restore the window procedure of the parent window end; end; end; // end of procedure HookWndProcprocedure TEoCSysTray.DoTaskBarCreated; begin ...... // here to re-add the notification area icon if Assigned (ftaskbarcreated) Then ftaskbarcreated (self); end; // end of procedure dotaskbarcreated
Initialization // Register the message to ask the task bar reconstructed message msgtaskbarcreated: = registerWindowMessage ('taskbarcreated');
End.
Quote Address: Notification Bar Icon Control with Automatic Recovery