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;
interface
uses
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;
implementation
const
WM_TASKBAR_MENU = $0313; // magic!
WM_POPUP_MENU = WM_USER + 1; //custom message
var
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