创建托盘代码: Nid.cbSize:=sizeof(TNotifyIconData);
Nid.Wnd:=Handle;
Nid.uID:=1000;
Nid.uFlags:=NIF_MESSAGE or NIF_ICON or NIF_TIP;
Nid.uCallbackMessage:=WM_TRAYNOTIFY;
Nid.hIcon:=Application.Icon.Handle;
Nid.szTip:=‘214’;
Shell_NotifyIcon(NIM_ADD,@Nid);
Icon:= TIcon.Create;
Icon.Handle:=LoadIcon(hinstance,‘abc’);刚开始form1.bordersytle:=bsSingle;当改为bsNone时,托盘就消失了。这是为什么,应该怎么做?
Nid.Wnd:=Handle;
Nid.uID:=1000;
Nid.uFlags:=NIF_MESSAGE or NIF_ICON or NIF_TIP;
Nid.uCallbackMessage:=WM_TRAYNOTIFY;
Nid.hIcon:=Application.Icon.Handle;
Nid.szTip:=‘214’;
Shell_NotifyIcon(NIM_ADD,@Nid);
Icon:= TIcon.Create;
Icon.Handle:=LoadIcon(hinstance,‘abc’);刚开始form1.bordersytle:=bsSingle;当改为bsNone时,托盘就消失了。这是为什么,应该怎么做?
解决方案 »
- 如何安装DSPack控件?
- 有个难题要问这儿的专家一下?
- DLL的声明很着急
- 挑战!!!!!!
- 问一个简单又头疼的问题:Canvas的Pen.Width不为1时,如何画出虚线来?解决后即送100分!
- 调用vc的dll的一个问题 请各位帮我看看 200分
- Delphi连接数据库服务器时,是明码传输的吗?登录密码是明文发送的吗?浏览网页时的登录密码是明文发送的吗?
- 重新啟動機器後怎麽连接不上IBLOCAL数据库?
- Help ME 特急!我发现2k的宋体空格占了2个字节,9x的宋体只有1个字节!
- 好心的大哥大姐,小弟有个简单的问题请教!在Delphi中怎么使用VB开发的类库啊!(ActiveX DLL)
- 电脑网络正常,程序里面却无法连接,怎么回事?
- 我编写了一个继承TPanel的控件,但是有好多问题,请指点谢谢
bsNone:
begin
if (Parent = nil) and (ParentWindow = 0) then
Style := Style or WS_POPUP;
Icons := [];
end;所以没有了ICON
begin
...
if MyMessage.Msg = FWM_TASKBARCREATED then //托盘栏防崩溃处理
begin
TrayIcon.NotifyDelete(Self.Handle);
TrayIcon.NotifyAdd(Self.Handle, Self.Showing);
end
else
//调用父类的WndProc方法处理其它消息
inherited;
第一句放在程序初始化的地方,因为这个消息值是靠系统生成的,每次启动系统不一样。第二句放在你修改窗体风格为bsNone之后,等于你谎报军情,告诉当前窗体“资源管理器崩溃了”。
例如:如果你想将窗口改为无边框,则执行:procedure TForm1.Button1Click(Sender: TObject);
begin
SetWindowLong(Handle,GWL_STYLE,GetWindowLong(Handle,GWL_STYLE) and (not WS_CAPTION));
end;
{*******************************************************}
{ }
{ 托盘栏图标类单元 }
{ }
{ 版权所有 (C) 2006 高亚男 }
{ }
{ 2006-9-7 }
{ }
{*******************************************************}unit ClsTrayIcon;interface
uses
Windows, {Menus, }Messages, Graphics, Classes;
type
TTrayIcon = class(TComponent)
private
// FPopupMenu: TPopupMenu;
FActiveIcon: TIcon;
FDeActiveIcon: TIcon;
FParent: TComponent;
function TrayMessage(hDlg: THandle; dwMessage: DWORD; uID: UINT; hIcon: HICON): boolean;
public
property ActiveIcon: TIcon read FActiveIcon Write FActiveIcon;
property DeActiveIcon: TIcon read FDeActiveIcon write FDeActiveIcon;
// property PopupMenu: TPopupMenu read FPopupMenu write FPopupMenu;
constructor Create(AOwner:TComponent); override;
destructor Destroy; override;
procedure NotifyAdd(hDlg: HWND; State: Boolean);
procedure StateChange(hDlg: HWND; State: Boolean);
procedure NotifyDelete(hDlg: HWND);
end;
const
MYWM_NOTIFYICON = WM_USER + 100; //托盘栏图标消息
var
TrayIcon: TTrayIcon;
implementation
uses
ShellApi;const
IDS_TrayIconTip: WideString = '看好你的鴨子!';
const
TrayIconID = 2052;function TTrayIcon.TrayMessage(hDlg: THandle; dwMessage: DWORD; uID: UINT; hIcon: HICON): boolean;
var
tnd: NOTIFYICONDATAW;
begin
tnd.cbSize := SizeOf(tnd);
tnd.Wnd := hDlg;
tnd.uID := uID; tnd.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
tnd.uCallbackMessage := MYWM_NOTIFYICON;
tnd.hIcon := hIcon;
lstrcpynW(tnd.szTip, PWideChar(IDS_TrayIconTip), SizeOf(tnd.szTip) div SizeOf(tnd.szTip[0]));
Result := Shell_NotifyIconW(dwMessage, @tnd); if hIcon = 0 then
DestroyIcon(hIcon);
end;procedure TTrayIcon.StateChange(hDlg: HWND; State: Boolean);
var
MyIcon: HICON;
begin
if State then
MyIcon := ActiveIcon.Handle
else
MyIcon := DeActiveIcon.Handle; TrayMessage(hDlg, NIM_MODIFY, TrayIconID, MyIcon);
end;procedure TTrayIcon.NotifyDelete(hDlg: HWND);
begin
TrayMessage(hDlg, NIM_DELETE, TrayIconID, 0);
end;procedure TTrayIcon.NotifyAdd(hDlg: HWND; State: Boolean);
var
MyIcon: HICON;
begin
if State then
MyIcon := ActiveIcon.Handle
else
MyIcon := DeActiveIcon.Handle;
TrayMessage(hDlg, NIM_ADD, TrayIconID, MyIcon);
end;constructor TTrayIcon.Create(AOwner: TComponent);
begin
inherited;
FParent := AOwner;
FActiveIcon := TIcon.Create;
FDeActiveIcon := TIcon.Create;
end;destructor TTrayIcon.Destroy;
begin
FActiveIcon.Free;
FDeActiveIcon.Free;
inherited;
end;initialization
finalization
end.
我的主窗体默认是不关闭的,点击那个右上方的x仅仅是缩小到托盘栏,双击图标可以打开主窗口。
想要关闭程序,需要单独用一个菜单写一个close。
不好意思,这里用的都是Tnt组件库,自己替换成相应的类。
SetForegroundWindow指令是必须的,否则当你呼叫出菜单后,却没有理会他,那个菜单会让你很无奈,这是MSDN上写的,MS的程序员发现了这个BUG,却没有去修复。 TfMain = class(TfEditorTemplate)
pmTrayIcon: TTntPopupMenu;
miOpenMainForm: TTntMenuItem;
miExit: TTntMenuItem;
procedure miOpenMainFormClick(Sender: TObject);
procedure miExitClick(Sender: TObject);
private
FWM_TASKBARCREATED: LongWord; //防崩溃消息
protected
procedure WndProc(var MyMessage: TMessage); override;
public
{ Public declarations }
end;procedure TfMain.miExitClick(Sender: TObject);
// 关闭程序
begin
inherited;
Close;
end;procedure TfMain.miOpenMainFormClick(Sender: TObject);
// 显示主窗体
begin
inherited;
Self.Show;
Application.Restore;
SetForegroundWindow(Self.Handle);
end;procedure TfMain.WndProc(var MyMessage: TMessage);
var
pt: TPoint;
begin
case MyMessage.Msg of
WM_CREATE: // 注册消息,防止系统崩溃
FWM_TASKBARCREATED := RegisterWindowMessageW('TaskbarCreated');
WM_CLOSE: // 关闭事件
PostMessageW(Self.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
WM_SYSCOMMAND: begin
case MyMessage.WParam of
SC_MINIMIZE: // 窗体最小化
begin
Application.Minimize;
Self.Hide;
end
else
inherited;
end;
end;
MYWM_NOTIFYICON:
case MyMessage.lParam of
WM_LBUTTONDBLCLK: //鼠标左键双击
begin
if Self.Showing then
PostMessageW(Self.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0)
else
Self.miOpenMainForm.Click;
end;
WM_RBUTTONDOWN: //鼠标右键被按下
begin
GetCursorPos(pt);
SetForegroundWindow(Self.Handle);
pmTrayIcon.Popup(pt.x,pt.y);
end
else
//调用父类的WndProc方法处理其它消息
inherited;
end;
else
if MyMessage.Msg = FWM_TASKBARCREATED then //托盘栏防崩溃处理
begin
TrayIcon.NotifyDelete(Self.Handle);
TrayIcon.NotifyAdd(Self.Handle, Self.Showing);
end
else
//调用父类的WndProc方法处理其它消息
inherited;
end;
end;
procedure TCustomForm.SetBorderStyle(Value: TFormBorderStyle);
begin
if FBorderStyle <> Value then
begin
FBorderStyle := Value;
AutoScroll := FBorderStyle in [bsSizeable, bsSizeToolWin];
if not (csDesigning in ComponentState) then RecreateWnd;
end;
end;procedure TWinControl.RecreateWnd;
begin
if FHandle <> 0 then Perform(CM_RECREATEWND, 0, 0);// <===引发CM_RECREATEWND消息,执行CMRecreateWnd处理过程
end;procedure TWinControl.CMRecreateWnd(var Message: TMessage);
var
WasFocused: Boolean;
begin
WasFocused := Focused;
DestroyHandle; // <=== 这里是关键,句柄被销毁了。
UpdateControlState;
if WasFocused and (FHandle <> 0) then Windows.SetFocus(FHandle);
end;