【发布时间】:2016-08-03 09:34:58
【问题描述】:
我的应用程序中有一个 PopupMenu,当用户右键单击我的应用程序的通知区域图标时,它会弹出。
当我右键单击此图标,弹出菜单,并且什么也不做时,我的应用程序的行为就像恢复它的工作一样,因为它看起来正在等待,直到我点击一个菜单项。
我想删除此行为。当用户没有响应并且鼠标指针离开 PopupMenu 时,我尝试通过添加自动关闭过程来修复 PopupMenu。
我还尝试添加一个TTimer,它会在指定时间后关闭我的TPopUpMenu,但它会在我指定的时间后关闭,而无需查看鼠标指针是在 PopupMenu 内部还是外部。
我想要实现的两个场景是:
我希望
TPopUpMenu在用户将鼠标指针移出超过两三秒时关闭。当用户在其中移动鼠标指针时,
TPopupMenu应在五分钟后关闭,因为任何用户都应在五分钟内响应 PopupMenu。
我尝试将带有TTimer 的以下代码添加到我的应用程序的事件处理程序中,当用户右键单击托盘图标时,它会打开 PopupMenu,但 PopupMenu 总是在两秒后关闭:
procedure TMainForm_1.SysTrayIconMessageHandler(var Msg: TMessage);
var
SysTrayTimer: TTimer;
PT: TPoint;
begin
case Msg.LParam of
WM_.....:;
WM_RBUTTONDOWN:
begin
GetCursorPos(PT);
SysTrayTimer.Enabled := True;
SysTrayTimer.Interval := 2500;
SystemTrayPopUpMenu.PopUp(PT.X, PT.Y);
SystemTrayPopUpMenu.AutoLineReduction := maAutomatic;
end;
end;
end;
procedure TMainForm_1.OnSysTrayTimer(Sender: TObject);
begin
SysTrayTimer.Enabled := False;
SendMessage(PopupList.Window, WM_CANCELMODE, 0, 0);
end;
我也读过this,但是在我添加代码之后,什么都没有改变。
至少,我必须能够做到这一点:在用户通过右键单击打开 PopupMenu 并将鼠标指针移到其中之后关闭它。
这就是我添加新代码以实现此目的的方式:
unit MainForm_1;
interface
uses
Windows, SysUtils, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, ExtCtrls, Menus, ImgList;
type
TMainForm_1 = class(TForm);
SystemTrayPopUpMenu: TPopUpMenu;
ExitTheProgram: TMenuItem;
RestoreFromSystemTray: TMenuItem;
ReadTheInstructions: TMenuItem;
Separator1: TMenuItem;
TrackSysTrayMenuTimer: TTimer;
CloseSysTrayMenuTimer: TTimer;
procedure OnTrackSysTrayMenuTimer(Sender: TObject);
procedure OnCloseSysTrayMenuTimer(Sender: TObject);
procedure SysTrayPopUpMenuPopUp(Sender: TObject);
private
MouseInSysTrayPopUpMenu: Boolean;
IconData: TNotifyIconData;
procedure SysTrayIconMsgHandler(var Msg: TMessage); message TRAY_CALLBACK;
procedure AddSysTrayIcon;
procedure DisplayBalloonTips;
procedure ApplySystemTrayIcon;
procedure DeleteSysTrayIcon;
public
IsSystemTrayIconShown: Boolean;
end;
var
MainForm_1: TMainForm_1;
implementation
uses
ShlObj, MMSystem, ShellAPI, SHFolder,.....;
procedure TMainForm_1.SysTrayIconMsgHandler(var Msg: TMessage);
var
PT: TPoint;
begin
case Msg.LParam of
WM_MOUSEMOVE:;
WM_LBUTTONUP:;
WM_LBUTTONDBLCLK:;
WM_RBUTTONUP:;
WM_RBUTTONDBLCLK:;
WM_LBUTTONDOWN:;
NIN_BALLOONSHOW:;
NIN_BALLOONHIDE:;
NIN_BALLOONTIMEOUT:;
NIN_BALLOONUSERCLICK:;
WM_RBUTTONDOWN:
begin
GetCursorPos(PT);
SetForegroundWindow(Handle);
SystemTrayPopUpMenu.OnPopup := SysTrayPopUpMenuPopUp;
SystemTrayPopUpMenu.PopUp(Pt.X, Pt.Y);
PostMessage(Handle, WM_NULL, 0, 0);
TrackSysTrayMenuTimer.Enabled := False;
CloseSysTrayMenuTimer.Enabled := False;
end;
end;
end;
procedure TMainForm_1.SysTrayPopUpMenuPopup(Sender: TObject);
begin
MouseInSysTrayMenu := True;
TrackSysTrayMenuTimer.Interval := 100;
TrackSysTrayMenuTimer.OnTimer := OnTrackSysTrayMenuTimer;
TrackSysTrayMenuTimer.Enabled := True;
CloseSysTrayMenuTimer.Interval := 300000;
CloseSysTrayMenuTimer.OnTimer := OnCloseSysTrayMenuTimer;
CloseSysTrayMenuTimer.Enabled := True;
end;
procedure TMainForm_1.OnTrackSysTrayMenuTimer(Sender: TObject);
var
hPopupWnd: HWND;
R: TRect;
PT: TPoint;
begin
hPopupWnd := FindWindow('#32768', nil);
if hPopupWnd = 0 then Exit;
GetWindowRect(hPopupWnd, R);
GetCursorPos(Pt);
if PtInRect(R, Pt) then begin
if not MouseInSysTrayMenu then begin
MouseInSysTrayMenu := True;
CloseSysTrayMenuTimer.Interval := 300000;
end;
end else begin
if MouseInSysTrayMenu then begin
MouseInSysTrayMenu := False;
CloseSysTrayMenuTimer.Interval := 2500;
end;
end;
end;
procedure TMainForm_1.OnCloseSysTrayMenuTimer(Sender: TObject);
begin
CloseSysTrayMenuTimer.Enabled := False;
SendMessage(PopupList.Window, WM_CANCELMODE, 0, 0);
end;
两个TTimers如何在App的MainForm中使用:
我如何分配TrackSysTrayMenuTimer 的属性值.....
我如何分配CloseSysTrayMenuTimer 的属性值.....
我也收到了这样的异常消息.....
这是我这样写的一条消息,用于检查代码中的失败之处.....因此,我可以确定 FindWindow 是否失败......
...
hPopupWnd := FindWindow('#32768', nil);
if hPopupWnd = 0 then
begin
TrackSysTrayMenuTimer.Enabled := False;
if ShowErrors = True and TestingMode = True then
Application.MessageBox('The PopUp Menu "SystemTrayPopUpMenu" could not be found.' +
' FindWindow will abort.', ' Exception Message', MB_ICONSTOP or MB_OK);
exit;
我收到的最后一个错误是:
提前致谢。
【问题讨论】:
-
您的程序与其他程序的行为方式不同,这不会让用户感到困惑吗?
-
是的............这是我的错......我会尽快解决这个问题,因为这也让我感到困惑。
标签: delphi hide delphi-2009 popupmenu