[]难者不会,会者不难,的小问题!!!

何鲁青 2006-01-18 10:23:20
作了一个小程序,实现了最小化到“任务栏”的功能,而且能够响应任务栏图标的消息并弹出PopMunu来了,但是我不知道怎么样去捕获PopUpMenu的菜单某项被点下的消息。
我的关键代码如下:
const WM_BARICON: Cardinal = WM_USER+100;//自定义的消息响应任务栏的操作
1、捕获最小化的程序
procedure WMSysCommand(var Message: TMessage); message WM_SYSCOMMAND;//声明在TForm
//////////////////
procedure TFrmMain.WMSysCommand(var Message: TMessage);//这里是实现
var
lpData:PNotifyIconData;
begin
if Message.WParam = SC_ICON then
begin
lpData := new(PNotifyIconDataA);
lpData.cbSize := 88;
lpData.Wnd := Handle;
// lpData.hIcon := Icon.Handle;
// lpData.hIcon := LoadIcon(0, IDI_QUESTION);
lpData.hIcon := Application.Icon.Handle;
lpData.uCallbackMessage := WM_BARICON;
lpData.uID :=0;
lpData.szTip := '家庭财富小管家';
lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
Shell_NotifyIcon(NIM_ADD,lpData);
dispose(lpData);
Visible := False;
end
else
inherited;
end;
2、处理任务栏消息的程序
procedure TFrmMain.FrmMainWndProc(var Message: TMessage);
var lpData: PNotifyIconData;
CurPoint: TPoint;
begin
if Message.Msg = WM_BARICON then
begin
if (Message.LParam = WM_LBUTTONDOWN) then
begin
//如果用户点击任务栏图标则将图标删除并恢复窗口。
lpData := new(PNotifyIconDataA);
lpData.cbSize := 88;
lpData.Wnd := Handle;
lpData.hIcon := Application.Icon.Handle;
lpData.uCallbackMessage := WM_BARICON;
lpData.uID :=0;
lpData.szTip := '家庭财富小管家';
lpData.uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
Shell_NotifyIcon(NIM_DELETE,lpData);
dispose(lpData);
Visible := True;
end
else if (Message.LParam = WM_RBUTTONUP) then
begin
GetCursorPos(CurPoint);
SetForegroundWindow(handle);
TrackPopupMenu(PopTree.Handle, TPM_RIGHTALIGN + TPM_LEFTBUTTON,
CurPoint.X, CurPoint.Y, 0, Handle, nil);
end;
end
else
begin
WndProc(Message);
end;
end;
----------------------------------------------------------------------
看到别人的实现这种功能的时候,是通过API函数自动创建的MENU但是小弟比较懒。
于是就用了一个delphi中的一个PopUpMenu的控件((PopTree)。然后调用TrackPopupMenu将他弹出。
但是,当我在PopTree的菜单OnClick事件当中写代码的时候,发现这些代码根本就没有被执行,后来
我捕获一下发向窗口的消息,发现根本就没有菜单被按下的消息被投递。
不知道是怎么回事了,还望各位大虾多多指教。
...全文
446 28 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
reborter 2006-02-04
  • 打赏
  • 举报
回复
顶,学习!
DemonLoveLizzy 2006-02-04
  • 打赏
  • 举报
回复
PNotifyIconData是什么?里面有没有一个MESSAGECALLBACK,或是类似的项.把那里设为你窗体任何控件的任何消息,消息就会映射到你设的消息那里了.你直接从设定的消息那里控制就好了.最好是MOUSE-MOVE或UP\DN.因为它直接分了X\Y,当X=7740(也可能是Y,我是凭记忆的)时就是那里的消息了.如果我说的不行你也别笑,不是我说的不对,也许是我记的不对.提供的方法就是这样的.
jilu_sun 2006-01-26
  • 打赏
  • 举报
回复
学习!顺便接分!
快乐老猫 2006-01-20
  • 打赏
  • 举报
回复
解决就给分吧,我们等着呢。
altans 2006-01-20
  • 打赏
  • 举报
回复
抓紧时间抢分 !
ZJQ100 2006-01-19
  • 打赏
  • 举报
回复
Delghi,不懂,知道一定告诉你。
不信,你给我点分,我一定查阅资料,认真学习,把解决方法教给你^o^
何鲁青 2006-01-19
  • 打赏
  • 举报
回复
感谢glhf(寂寞的鸭子)的提示。


还有快乐老猫(无米下炊) 的提醒……
何鲁青 2006-01-19
  • 打赏
  • 举报
回复
在程序中将TrackPopupMenu(PopTree.Handle, TPM_RIGHTALIGN + TPM_LEFTBUTTON,
CurPoint.X, CurPoint.Y, 0, Handle, nil);
去掉了,改用了delphi给的popup函数,竟然可以了,所以我怀疑还是自己水平太臭,调用
TrackPopupMenu的时候参数写的不对造成的。看了看源代码,确实不想我想象的那么简单的。
贴出来供大家讨论区别和优劣:
procedure TPopupMenu.Popup(X, Y: Integer);
const
Flags: array[Boolean, TPopupAlignment] of Word =
((TPM_LEFTALIGN, TPM_RIGHTALIGN, TPM_CENTERALIGN),
(TPM_RIGHTALIGN, TPM_LEFTALIGN, TPM_CENTERALIGN));
Buttons: array[TTrackButton] of Word = (TPM_RIGHTBUTTON, TPM_LEFTBUTTON);
var
AFlags: Integer;
begin
FPopupPoint := Point(X, Y);
SetBiDiModeFromPopupControl;
DoPopup(Self);
FItems.InternalRethinkHotkeys(False);
FItems.InternalRethinkLines(False);
FItems.RebuildHandle;
AdjustBiDiBehavior;
AFlags := Flags[UseRightToLeftAlignment, FAlignment] or Buttons[FTrackButton] or
(Byte(FMenuAnimation) shl 10);
TrackPopupMenu(FItems.Handle, AFlags, X, Y, 0 { reserved }, PopupList.Window, nil);
end;
kongguangming 2006-01-19
  • 打赏
  • 举报
回复
那你就在窗体中加入处理菜单点击的消息处理就行了。
kongguangming 2006-01-18
  • 打赏
  • 举报
回复
TrackPopupMenu是原始api而popup是delphi里popupmemu的方法,直接用api破怀了其内部处理消息的链,所以错了,或者TrackPopupMenu里处理过程的句柄要给对。
daidai_____DD 2006-01-18
  • 打赏
  • 举报
回复
漏点分给我
何鲁青 2006-01-18
  • 打赏
  • 举报
回复
我再回去好好看看吧,有空就来把帖子结了.来着有份,呵呵^_^
何鲁青 2006-01-18
  • 打赏
  • 举报
回复
难道大家的代码写到OnClick里面都能够执行吗?
为什么我在菜单OnClick事件写的代码不执行那?
RPWT??????????????????????????????????????
//////////////////////////////////////////////////
Re:hellolongbin(一个人[年长资深少男])
呵呵,老大你现在都是两个星星了,恭喜恭喜!!!
我是很久没有来转悠了,你老人家一向可好?
glhf 2006-01-18
  • 打赏
  • 举报
回复
没看懂你的代码,我改了一下,在WinXp+delphi7下运行过没问题:
const WM_BARICON: Cardinal = WM_USER+100;//自定义的消息响应任务栏的操作

Procedure WMBarICon(var msg : TMessage); message WM_BARICON;;//声明在TForm

procedure TForm1.WMBarICon(var msg: TMessage);//实现部分
var
CurPoint : TPoint;
begin
if (msg.LParam = WM_RBUTTONDOWN) then
begin
GetCursorPos(CurPoint);
//SetForegroundWindow(handle);
PopupMenu1.Popup(CurPoint.X, CurPoint.Y);//弹出菜单,菜单的事件处理写在菜单OnClick事件里面
end;
end;
kongguangming 2006-01-18
  • 打赏
  • 举报
回复
把菜单弹出换成
PopTree.Popup(CurPoint.x,CurPoint.y);试试。
快乐老猫 2006-01-18
  • 打赏
  • 举报
回复
procedure TFrmMain.FrmMain.WndProc(var Message: TMessage);
var lpData: PNotifyIconData;
CurPoint: TPoint;
begin
case Message.Msg do
WM_CREATE:
begin
// 注册WINDOWS消息,防止系统崩溃丢失托盘图标
WM_TASKBARCREATED := RegisterWindowMessage('TaskbarCreated');
end;
WM_BARICON:
begin
case Message.LParam do
WM_LBUTTONDOWN:
begin
//如果用户点击任务栏图标则将图标删除并恢复窗口。
//....
end
WM_RBUTTONUP:
begin
GetCursorPos(CurPoint);
SetForegroundWindow(handle);
PopTree.Popup(CurPoint.x,CurPoint.y);
end;
else
//调用父类的WndProc方法处理其它消息
inherited;
end;
end
else
if MyMessage.Msg = WM_TASKBARCREATED then //托盘栏防崩溃处理
begin
//这里加入托盘图标的删除和增加代码,建议把托盘图标处理代码函数化或者类化。
end
else
//调用父类的WndProc方法处理其它消息
inherited;
end;
end;
hellolongbin 2006-01-18
  • 打赏
  • 举报
回复
把我以前的一个程序改了改

PopupMenu1上有两个按钮,一个是a1,一个是close,直接放一个PopupMenu在窗体上设置好这两个MenuItem,关联好事件运行就可以了,不知道是不是你想要的效果


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Menus, ShellApi;
const
WM_MIDASICON = WM_USER + 1;
type
TForm1 = class(TForm)
PopupMenu1: TPopupMenu;
a1: TMenuItem;
close1: TMenuItem;
procedure close1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
procedure a1Click(Sender: TObject);
private
fclose:boolean;
FIconData: TNotifyIconData;

procedure WMMIDASIcon(var Message: TMessage); message WM_MIDASICON;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.close1Click(Sender: TObject);
begin
FClose := True;
close;
end;

procedure TForm1.WMMIDASIcon(var Message: TMessage);
var
pt: TPoint;
begin
case Message.LParam of
WM_RBUTTONUP:
begin
if not Visible then
begin
SetForegroundWindow(Handle);
GetCursorPos(pt);
PopupMenu1.Popup(pt.x, pt.y);
end
else
SetForegroundWindow(Handle);
end;
WM_LBUTTONDBLCLK:
if Visible then
SetForegroundWindow(Handle)
else
a1.Click;
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
FClose := False;
with FIconData do
begin
cbSize := sizeof(FIconData);
Wnd := Self.Handle;
uID := $DEDB;
uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
hIcon := Forms.Application.Icon.Handle;
uCallbackMessage := WM_MIDASICON;
StrCopy(szTip, PChar(Caption));
end;
Shell_NotifyIcon(NIM_Add, @FIconData);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Shell_NotifyIcon(NIM_DELETE, @FIconData);
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
if FClose then CanClose := True
else
begin
CanClose := False;
Hide;
end;
end;

procedure TForm1.a1Click(Sender: TObject);
begin
Form1.Show;
end;

end.
kongguangming 2006-01-18
  • 打赏
  • 举报
回复
WndProc(Message);

好像是这句的问题,消息未传递出去,换成DefWindowProc来处理试试。
aiirii 2006-01-18
  • 打赏
  • 举报
回复
>>但是我不知道怎么样去捕获PopUpMenu的菜单某项被点下的消息。

不知道是否是我听不明白,不就是在 popupMenu的子菜单的事件中处理吗?
Ciny_Cou 2006-01-18
  • 打赏
  • 举报
回复
up 学习
加载更多回复(8)

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧