首页  编辑  

象IE收藏夹一样在菜单上弹出菜单

Tags: /超级猛料/VCL/Menu.菜单/   Date Created:
下面是o*o以前关于该问题所做的回答,如果还有不明白的地方,请参照下面两个贴子:
http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=206834
http://www.delphibbs.com/delphibbs/DispQ.asp?LID=209455
**********************************************************
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。
而这种普通菜单的办法实在土蹩。
想简单, 找个第三方控件.
想自己做: 截取PopupList.Window指向HWND的wndproc. 在那里可以接受
鼠标消息. PopupList是个全局变量(D5, uses Menus后)
eyes: 如果用popuplist,我应该在哪个事件里setwindowlong,
     在哪个事件里恢复OldWndPorc ?
--------------------------------------------------------------------------------
来自:cAkk 时间:00-3-31 15:10:55 ID:209165  
现在好像wndproc设置成功了,但是为什么截获wm_RButtonUp不行?
应该截获哪个消息?
来自:cAkk 时间:00-3-31 15:56:22 ID:209182  
好像popuplist.window根本不接受鼠标消息???
------------------------------------
来自:o*o 时间:00-3-31 16:18:43 ID:209194  
cAkk,你怎么在自言自语呀?:-)
popuplist.window当然能接受鼠标消息。WM_RBUTTONDOWN可以。
最好是用WM_MENURBUTTONUP,这个消息连MSDN上也没有介绍。
-----------------------------------
来自:cAkk 时间:00-3-31 16:21:26 ID:209196  
o*o: 麻烦你写出完整代码出来,我的总是不行,多谢!
BTW: WM_MENURBUTTONUP 在message.pas里面就有
哦,忘了告诉你,要将menus.pas中的这句
 TrackPopupMenu(FItems.Handle,              
   Flags[UseRightToLeftAlignment, FAlignment] or Buttons[FTrackButton],
改为下面的才有效。
 TrackPopupMenu(FItems.Handle,              
   Flags[UseRightToLeftAlignment, FAlignment],//or Buttons[FTrackButton],
你再试试。这是DELPHI擅作主张的地方
怎么不行?
改过TrackPopupMenu一句后,在TPopupList.WndProc下面加上
WM_MENURBUTTONUP:
  messagebox(0,'右键消息','',1);
我就改了这两个地方呀。
我用的是D4。你是不是要把LIB中的Menus.dcu替换掉。
cAkk兄,抱歉,刚才出去喝酒去了,5瓶呀,晕得糊的。
D4中TPopupList不是全局变量,也用不着SetWindowLong。
还是讨论一下WIN98的开始菜单吧,它是在窗口上放一CoolBar,
再放一PageControl,再放一ToolBar,那些MenuItem其实就是
一个个ToolButton。
WIN98SE又加了一个DesktopMenu,也是这样。
这种用ToolBar作的"多功能菜单"(区别与普通菜单)表明了
菜单发展的新趋向。而普通菜单加右键过时了吧。
这种菜单自己作起来比较麻烦,我一直试图找到一个API或COM接口,未遂。