2005. november 10., csütörtök
Show the system menu of a window at the current mouse cursor position
Problem/Question/Abstract:
How can I show the system menu of a window at the position of the mouse cursor and not at the window's title bar?
Answer:
Solve 1:
The problem is that the system menu sends WM_SYSCOMMAND messages to the window identified by Handle, and you are probably looking for WM_COMMAND messages.
r := integer(TrackPopupMenuEx(GetSystemMenu(handle, false), TPM_LEFTALIGN or
TPM_RETURNCMD or TPM_RIGHTBUTTON or TPM_HORIZONTAL or
TPM_VERTICAL, x, y, handle, nil));
SendMessage(handle, WM_SYSCOMMAND, r, 0);
Solve 2:
Well, you can pop the system menu up where you want using code like the one below:
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
h: HMENU;
begin
h := GetSystemMenu(handle, false);
TrackPopupMenu(h, TPM_LEFTALIGN or TPM_LEFTBUTTON, speedbutton1.Left +
clientorigin.X, speedbutton1.Top + speedbutton1.Height + clientorigin.y, 0,
handle, nil);
end;
The problem is that the menu will not work this way. If you use TrackPopupMenu to show the menu its items will send WM_COMMAND messages to the form when clicked by the user. But the form expects WM_SYSCOMMAND messages from the system menu. So you have to trap the WM_COMMAND messages, figure out which of them come from the menu (there will be lots of others, from buttons and the like) and translate them into WM_SYSCOMMAND.
{ ... }
private
{ Private declarations }
procedure WMCommand(var msg: TWMCommand); message WM_COMMAND;
{ ... }
procedure TForm1.WMCommand(var msg: TWMCommand);
begin
if msg.NotifyCode = 0 then {message comes from a menu}
if msg.ItemID >= SC_SIZE then
begin {looks like system menu item}
PostMessage(handle, WM_SYSCOMMAND, TMessage(msg).WParam,
TMessage(msg).LParam);
Exit;
end;
inherited;
end;
Solve 3:
There is an undocumented Windows message (Message ID:$313) that can do it:
procedure TForm1.Button1Click(Sender: TObject);
const
WM_POPUPSYSTEMMENU = $313;
begin
SendMessage(Handle, WM_POPUPSYSTEMMENU, 0,
MakeLong(Mouse.CursorPos.X, Mouse.CursorPos.Y));
end;
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése