如何将图标缩入系统托栏里面?(50分)

  • 主题发起人 主题发起人 cpilq
  • 开始时间 开始时间
C

cpilq

Unregistered / Unconfirmed
GUEST, unregistred user!
我想我的程序在最小化的时候能够缩入系统栏里面?请问各位DFW,代码需要如何写?
 
用TTrayIcon这个控件就可以了
 
这个空间好像不是delphi自带的啊!我不喜欢使用第三方控件!所以希望能直接写出代码!<br>谢谢!
 
这是一个自动关机的程序 里面有 你想要的功能!<br><br>unit AutoShut1;<br>interface<br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls, ExtCtrls, Menus,AppEvnts,shellapi;<br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Timer1: TTimer;<br>&nbsp; &nbsp; Timer2: TTimer;<br>&nbsp; &nbsp; ApplicationEvents1: TApplicationEvents;<br>&nbsp; &nbsp; PopupMenu1: TPopupMenu;<br>&nbsp; &nbsp; Edit1: TEdit;<br>&nbsp; &nbsp; Edit2: TEdit;<br>&nbsp; &nbsp; Label1: TLabel;<br>&nbsp; &nbsp; Label2: TLabel;<br>&nbsp; &nbsp; Label3: TLabel;<br>&nbsp; &nbsp; Btn_OK: TButton;<br>&nbsp; &nbsp; Btn_Abort: TButton;<br>&nbsp; &nbsp; procedure Timer1Timer(Sender: TObject);<br>&nbsp; &nbsp; procedure TrayMenu(Var Msg:TMessage); message WM_USER;<br>&nbsp; &nbsp; procedure TimeSetClick(Sender: TObject);<br>&nbsp; &nbsp; procedure ExitClick(Sender: TObject);<br>&nbsp; &nbsp; procedure Btn_OKClick(Sender: TObject);<br>&nbsp; &nbsp; procedure Btn_AbortClick(Sender: TObject);<br>&nbsp; &nbsp; procedure Timer2Timer(Sender: TObject);<br>&nbsp; &nbsp; procedure Edit2KeyPress(Sender: TObject; var Key: Char);<br>&nbsp; &nbsp; procedure WMQueryEndSession (var Msg : TWMQueryEndSession);<br>&nbsp; &nbsp; &nbsp; message WM_QueryEndSession;<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; &nbsp; procedure FormDestroy(Sender: TObject);<br>&nbsp; &nbsp; procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);<br>&nbsp; private<br>&nbsp; &nbsp; &nbsp; { Private declarations }<br>&nbsp; &nbsp; Tray:NOTIFYICONDATA;<br>&nbsp; &nbsp; procedure ShowInTray();<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br>&nbsp; P,Ti1:Pchar;<br>&nbsp; Flags:Longint;<br>&nbsp; i:integer;<br>&nbsp; {关机延迟时间}<br>&nbsp; TimeDelay:integer;<br>&nbsp; atom:integer;<br>implementation<br>{$R *.dfm}<br><br>{未到自动关机时间,系统要关闭时,截获关机消息<br>wm_queryendsession,让用户决定是否关机}<br>procedure TForm1.WMQueryEndSession (var Msg : TWMQueryEndSession);<br>begin<br>&nbsp; if MessageDlg('真的要关闭Windows吗?',mtConfirmation,[mbYes,mbNo], 0) = mrNo then<br>&nbsp; &nbsp; Msg.Result := 0<br>&nbsp; else<br>&nbsp; &nbsp; Msg.Result := 1;<br>end;<br><br>{判断时间S格式是否是有效}<br>function IsValidTime(s:string):bool;<br>begin<br>&nbsp; if &nbsp;Length(s)&lt;&gt;5 then IsValidTime:=False<br>&nbsp; else<br>&nbsp; begin<br>&nbsp; &nbsp; if (s[1]&lt;'0') or (s[1]&gt;'2') or (s[2]&lt;'0') or<br>&nbsp; &nbsp; &nbsp; &nbsp;(s[2]&gt;'9') or (s[3] &lt;&gt; ':') or<br>&nbsp; &nbsp; &nbsp; &nbsp;(s[4]&lt;'0') or (s[4]&gt;'5') or<br>&nbsp; &nbsp; &nbsp; &nbsp;(s[5]&lt;'0') or (s[5]&gt;'9')then IsValidTime:=False<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; &nbsp; IsValidTime:=True;<br>&nbsp; end;<br>end;<br><br>{判断是哪类操作系统,以确定关机方式}<br>function GetOperatingSystem: string;<br>var &nbsp;osVerInfo: TOSVersionInfo;<br>begin<br>&nbsp; Result :='';<br>&nbsp; osVerInfo.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);<br>&nbsp; if GetVersionEx(osVerInfo) then<br>&nbsp; &nbsp; case osVerInfo.dwPlatformId of<br>&nbsp; &nbsp; &nbsp; VER_PLATFORM_WIN32_NT:<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := 'Windows NT/2000/XP'<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; &nbsp; VER_PLATFORM_WIN32_WINDOWS:<br>&nbsp; &nbsp; &nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Result := 'Windows 95/98/98SE/Me';<br>&nbsp; &nbsp; &nbsp; &nbsp; end;<br>&nbsp; &nbsp; end;<br>end;<br><br>{获得计算机名}<br>function GetComputerName: string;<br>var<br>&nbsp; buffer: array[0..MAX_COMPUTERNAME_LENGTH + 1] of Char;<br>&nbsp; Size: Cardinal;<br>begin<br>&nbsp; Size := MAX_COMPUTERNAME_LENGTH + 1;<br>&nbsp; Windows.GetComputerName(@buffer, Size);<br>&nbsp; Result := strpas(buffer);<br>end;<br><br>{定时关机函数 ,各参数的意义如下:<br>Computer: 计算机名;Msg:显示的提示信息;<br>Time:时间延迟; Force:是否强制关机;<br>Reboot: 是否重启动}<br>function TimedShutDown(Computer: string; Msg: string;<br>&nbsp; Time: Word; Force: Boolean; Reboot: Boolean): Boolean;<br>var<br>&nbsp; rl: Cardinal;<br>&nbsp; hToken: Cardinal;<br>&nbsp; tkp: TOKEN_PRIVILEGES;<br>begin<br>&nbsp; {获得用户关机特权,仅对Windows NT/2000/XP}<br>&nbsp; OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);<br>&nbsp; if LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid) then<br>&nbsp; begin<br>&nbsp; &nbsp; tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;<br>&nbsp; &nbsp; tkp.PrivilegeCount := 1;<br>&nbsp; &nbsp; AdjustTokenPrivileges(hToken, False, tkp, 0, nil, rl);<br>&nbsp; end;<br>&nbsp; Result := InitiateSystemShutdown(PChar(Computer), PChar(Msg), Time, Force, Reboot)<br>end;<br><br>{窗体最小化后,显示在托盘中}<br>procedure tform1.ShowInTray;<br>Begin<br>Tray.cbSize:=sizeof(Tray);<br>Tray.Wnd:=Self.Handle;<br>Tray.uFlags:=NIF_ICON+NIF_MESSAGE+NIF_TIP;<br>Tray.uCallbackMessage:=WM_USER;<br>Tray.hIcon:=application.Icon.Handle ;<br>Tray.szTip:='定时关机';<br>Shell_NotifyIcon(NIM_ADD,@Tray);<br>End;<br><br>{右键单击托盘中的图标,显示快捷菜单}<br>procedure Tform1.TrayMenu(var Msg:TMessage);<br>var<br>X,Y:Tpoint;<br>J,K:Integer;<br>Begin<br>GetCursorPos(X);<br>GetCursorPos(Y);<br>J:=X.X;<br>K:=Y.Y;<br>if Msg.LParam=WM_RBUTTONDOWN then PopupMenu1.Popup(J,K);<br>End;<br><br>procedure TForm1.Timer1Timer(Sender: TObject);<br>begin<br>Edit1.Text:=FormatDateTime('hh:mm', Now);<br>{两个时间相等,计算机将在TimeDelay秒内强制关机}<br>if edit1.text=edit2.Text then<br>Begin<br>TimeDelay:=30;<br>timer1.Enabled:=False;<br>if &nbsp;GetOperatingSystem='Windows NT/2000/XP' then<br>&nbsp; begin<br>&nbsp; &nbsp; {调用系统的关机提示窗口,只限于Windows NT/2000/XP。}<br>&nbsp; &nbsp; TimedShutDown(getcomputername, '系统将要关机!',<br>&nbsp; &nbsp; &nbsp; TimeDelay, true, false);<br>&nbsp; &nbsp; btn_abort.Enabled :=true;<br>&nbsp; &nbsp; timer2.Enabled :=true;<br>&nbsp; end;<br>if &nbsp;GetOperatingSystem='Windows 95/98/98SE/Me' then<br>&nbsp; begin<br>&nbsp; &nbsp; timer2.Enabled :=true;<br>&nbsp; &nbsp; {在顶层显示本程序的窗口,显示时间倒记时}<br>&nbsp; &nbsp; Application.Restore;<br>&nbsp; &nbsp; SetWindowPos(Handle,HWND_TOPMOST,Left,Top,Width,Height,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SWP_NOACTIVATE);<br>&nbsp; end;<br>end;<br>end;<br><br>procedure TForm1.Timer2Timer(Sender: TObject);<br>begin<br>&nbsp; &nbsp; btn_abort.Enabled :=true;<br>&nbsp; &nbsp; label3.Caption :='离关机时间还有'+inttostr(timedelay)+'秒。';<br>&nbsp; &nbsp; if timedelay&gt;0 then timedelay:=timedelay-1<br>&nbsp; &nbsp; else<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; timer2.Enabled :=false;<br>&nbsp; &nbsp; {强制Windows 95/98/98SE/Me关机}<br>&nbsp; &nbsp; ExitWindowsEx(EWX_SHUTDOWN+EWX_FORCE,0);<br>&nbsp; &nbsp; end;<br>end;<br><br>{通过控件PopupMenu1定义的快捷菜单,包括"设置关机时间"和"退出"。<br>PopupMenu1的AutoPopup为False,下面是"设置关机时间"的代码}<br>procedure TForm1.TimeSetClick(Sender: TObject);<br>begin<br>&nbsp; {设置本程序窗口位于最顶层}<br>&nbsp; SetWindowPos(Handle,HWND_TOPMOST,Left,Top,Width,Height,<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;SWP_NOACTIVATE);<br>&nbsp; ShowWindow(Application.Handle,SW_NORMAL);<br>&nbsp; edit2.SetFocus ;<br>&nbsp; edit2.SelectAll ;<br>end;<br>{快捷菜单中"退出"的代码}<br>procedure TForm1.ExitClick(Sender: TObject);<br>begin<br>&nbsp; {如果已经开始倒记时,禁止退出,而是显示程序窗口}<br>&nbsp; if Timer2.Enabled=false then<br>&nbsp; begin<br>&nbsp; &nbsp; Application.Terminate;<br>&nbsp; end<br>&nbsp; else &nbsp;ShowWindow(Application.Handle,SW_NORMAL);<br>end;<br><br>{确定按钮}<br>procedure TForm1.Btn_OKClick(Sender: TObject);<br>begin<br>&nbsp; btn_abort.Enabled :=false;<br>&nbsp; label3.Caption :='提示:关机时间格式 HH:MM';<br>&nbsp; if timer1.Enabled =false then timer1.Enabled :=true;<br>&nbsp; {关机时间设置有效,程序将显示在托盘中,无效则提示。}<br>&nbsp; if IsValidTime(edit2.Text) then<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; ShowWindow(Application.Handle,sw_minimize);<br>&nbsp; &nbsp; &nbsp; ShowWindow(Application.Handle,sw_hide);<br>&nbsp; &nbsp; &nbsp; ShowInTray;<br>&nbsp; &nbsp; end<br>&nbsp; else<br>&nbsp; &nbsp; showmessage('提示:时间格式错误,'+chr(13)+<br>&nbsp; &nbsp; '请输入正确的关机时间 HH:MM。');<br>end;<br><br>{取消关机按钮}<br>procedure TForm1.Btn_AbortClick(Sender: TObject);<br>begin<br>&nbsp; if &nbsp;GetOperatingSystem='Windows NT/2000/XP' then<br>&nbsp; &nbsp; {对于Windows NT/2000/XP,取消关机}<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; AbortSystemShutdown(pchar(getcomputername));<br>&nbsp; &nbsp; end;<br>&nbsp; &nbsp; {停止倒记时}<br>&nbsp; if timer2.Enabled =true then timer2.Enabled :=false;<br>&nbsp; btn_abort.Enabled :=false;<br>end;<br><br>{输入关机时间后,可直接按回车}<br>procedure TForm1.Edit2KeyPress(Sender: TObject; var Key: Char);<br>begin<br>&nbsp; if (key=#13) &nbsp;then &nbsp;Btn_OK.Click;<br>end;<br><br>{搜寻系统原子表看是否程序已运行}<br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; {如果没运行则在表中增加信息 }<br>&nbsp; if GlobalFindAtom('PROGRAM_RUNNING') = 0 then<br>&nbsp; &nbsp; atom := GlobalAddAtom('PROGRAM_RUNNING')<br>&nbsp; else begin<br>&nbsp; &nbsp; {如果程序已运行则显示信息然后退出 }<br>&nbsp; &nbsp; MessageDlg('程序已经在运行!',mtWarning,[mbOK],0);<br>&nbsp; &nbsp; Halt;<br>&nbsp; end;<br>end;<br><br>procedure TForm1.FormDestroy(Sender: TObject);<br>begin<br>&nbsp; {程序退出时,从原子表中移走信息}<br>&nbsp; GlobalDeleteAtom(atom);<br>&nbsp; {删除托盘中的图标}<br>&nbsp; Shell_NotifyIcon(NIM_DELETE,@Tray);<br>end;<br><br>procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);<br>begin<br>&nbsp; {如果已经开始倒记时,禁止关闭程序窗口}<br>&nbsp; if timer2.Enabled =true then canclose:=false;<br>end;<br><br>end.
 
建议看看delphi5程序员指南第24章<br>实现系统拖盘只是调用一个api函数而已
 
接受答案了.
 
后退
顶部