When you right-click on a taskbar button, Windows sends an undocumented message ($0313) to the corresponding application window. The WPARAM is unused (zero) and the LPARAM contains the mouse position in screen coordinates, in the usual format. By default, WindowProc
handles this message by popping up the system menu at the given coordinates.Apparently you can use it to pop up your own custom menu, but before doing that I would use e.g. Spy++ to check whether possibly it generates documented messages that can be processed
instead.
unit TaskBarMenu;interfaceuses SysUtils, Classes, Menus, Messages, Windows, Forms, Controls;type TTaskBarMenu = class(TPopupMenu) private hookHandle : THandle; oldWndProc: Pointer; newWndProc: Pointer; protected procedure Hook; procedure UnHook; procedure AppWndProc(var Msg: TMessage) ; public constructor Create(AOwner: TComponent) ; override; destructor Destroy; override; end;procedure Register;implementationconst WM_TASKBAR_MENU = $0313; // magic! WM_POPUP_MENU = WM_USER + 1; //custom messagevar thisOnce : TTaskBarMenu = nil;procedure Register;begin RegisterComponents('delphi.about.com', [TTaskBarMenu]) ;end;{ TTaskBarMenu }procedure TTaskBarMenu.AppWndProc(var Msg: TMessage) ;begin case Msg.Msg of WM_TASKBAR_MENU: PostMessage(hookHandle, WM_POPUP_MENU, 0, 0) ; WM_POPUP_MENU: Popup(Mouse.CursorPos.X, Mouse.CursorPos.Y) ; else Msg.Result := CallWindowProc(oldWndProc, hookHandle, Msg.Msg, Msg.wParam, Msg.lParam) ; end;end; (*AppWndProc*)constructor TTaskBarMenu.Create(AOwner: TComponent) ;begin if Assigned(thisOnce) then begin raise Exception.Create('Only one instance of this component can be used per application!') ; end else begin inherited; thisOnce := self; hookHandle := Application.Handle; Hook; end;end; (*Create*)destructor TTaskBarMenu.Destroy;begin thisOnce := nil; UnHook; inherited;end; (*Destroy*)procedure TTaskBarMenu.Hook;begin oldWndProc := Pointer(GetWindowLong(hookHandle, GWL_WNDPROC)) ; newWndProc := Classes.MakeObjectInstance(AppWndProc) ; if not (csDesigning in ComponentState) then SetWindowLong(hookHandle, GWL_WNDPROC, longint(newWndProc)) ;end; (*Hook*)procedure TTaskBarMenu.UnHook;begin SetWindowLong(hookHandle, GWL_WNDPROC, longint(oldWndProc)) ; if Assigned(newWndProc) then Classes.FreeObjectInstance(newWndProc) ; NewWndProc := nil;end; (*UnHook*)end.
備忘:本文參考自:
1、http://stackoverflow.com/questions/10430377/winapi-undocumented-windows-message-0x0313-stable
2、http://delphi.about.com/od/vclwriteenhance/a/ttaskbarmenu.htm