转载 o*o 给 cAkk的解答:
来自:o*o
哦,D5的作法与D4完全不同,简单多了。PopupList是全局变量呀。
先将Menus.pas的TrackPopupMenu那句改了,去掉Buttons[FTrackButton]
在FORM上加一PopupMenu1,随便填几个MenuItem。
private
DefMenuProc: TFarProc;
procedure MenuWndProc(var msg: Tmessage);
{ Private declarations }
procedure TForm1.FormCreate(Sender: TObject);
begin
DefMenuProc:=Pointer(GetWindowLong(PopupList.Window,GWL_WNDPROC));
SetWindowLong(PopupList.Window,GWL_WNDPROC,LongInt(MakeObjectInstance(MenuWndProc)));
end;
var Item:Integer;
procedure TForm1.MenuWndProc(var msg:Tmessage);
var pop:HMENU; p:TPoint; s:array[0..255]of Char;
begin
case msg.Msg of
WM_MENURBUTTONUP: begin
GetCursorPos(p);
pop:=CreatePopupMenu;
GetMenuString(PopupMenu1.Handle,Item,s,255,MF_BYCOMMAND);
AppendMenu(pop,0,100,PChar('Popup From '+String(s)));
TrackPopupMenu(pop,1,p.x,p.y,0,PopupList.Window,nil);
DestroyMenu(pop);
end;
WM_MENUSELECT: Item:=LOWORD(msg.wParam);
WM_COMMAND: if LOWORD(msg.wParam)=100 then MessageBox(Handle,'','OK!',0);
end;
with msg do Result:=CallWindowProc(DefMenuProc,PopupList.Window,Msg,WParam,LParam);
end;
cAkk,让你久等了,我平常休息日是不上网的。呵呵。
1 弹出TPopupMenu还要将Menus.pas中TrackPopupMenu里的AFlags加上 or TPM_RECURSE
意思是当一个菜单正在Track时,还能够Track另一个菜单。
Borland的老师们在封装API时显然忽视了这一点。
2 MakeObjectInstance是将一个procedure(var msg: TMessage) of object方法安全地转换为指针。
@MyWndProc是什么意思?不太明白。
3 据我观察,TPopupMenu的CommandID都是从很小的值如1开始累加的,设得大一些应无问题。
当然用1中说的弹出一个经过VCL封装的PopupMenu就没问题了。
再次真情呼唤大侠们找到制作WIN98开始菜单的方法,因为它支持ContextMenu,DragDrop,Hint。
而这种普通菜单的办法实在土蹩。