程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 創建具有托盤的服務程序

創建具有托盤的服務程序

編輯:Delphi
 Windows 2000/XP和2003等支持一種叫做"服務程序"的東西.程序作為服務啟動有以下幾個好處:
  
      (1)不用登陸進系統即可運行.
      (2)具有SYSTEM特權.所以你在進程管理器裡面是無法結束它的.
  
      筆者在2003年為一公司開發機頂盒項目的時候,曾經寫過課件上傳和媒體服務,下面就介紹一下如何用Delphi7創建一個Service程序.
      運行Delphi7,選擇菜單File-->New-->Other--->Service Application.將生成一個服務程序的框架.將工程保存為ServiceDemo.dpr和Unit_Main.pas,然後回到主框架.我們注意到,Service有幾個屬性.其中以下幾個是我們比較常用的:
  
      (1)DisplayName:服務的顯示名稱
      (2)Name:服務名稱.
  
      我們在這裡將DisplayName的值改為"Delphi服務演示程序",Name改為"DelphiService".編譯這個項目,將得到ServiceDemo.exe.這已經是一個服務程序了!進入CMD模式,切換致工程所在目錄,運行命令"ServiceDemo.exe /install",將提示服務安裝成功!然後"net start DelphiService"將啟動這個服務.進入控制面版-->管理工具-->服務,將顯示這個服務和當前狀態.不過這個服務現在什麼也干不了,因為我們還沒有寫代碼:)先"net stop DelphiService"停止再"ServiceDemo.exe /uninstall"刪除這個服務.回到Delphi7的IDE.
  
      我們的計劃是為這個服務添加一個主窗口,運行後任務欄顯示程序的圖標,雙擊圖標將顯示主窗口,上面有一個按鈕,點擊該按鈕將實現Ctrl+Alt+Del功能.
  
      實際上,服務程序莫認是工作於Winlogon桌面的,可以打開控制面板,查看我們剛才那個服務的屬性-->登陸,其中"允許服務與桌面交互"是不打鉤的.怎麼辦?呵呵,回到IDE,注意那個布爾屬性:Interactive,當這個屬性為True的時候,該服務程序就可以與桌面交互了.
  
      File-->New-->Form為服務添加窗口FrmMain,單元保存為Unit_FrmMain,並且把這個窗口設置為手工創建.完成後的代碼如下:
  
  
  


  unit Unit_Main;
  
  interface
  
  uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, SvcMgr, Dialogs, Unit_FrmMain;
  
  type
  TDelphiService = class(TService)
  procedure ServiceContinue(Sender: TService; var Continued: Boolean);
  procedure ServiceExecute(Sender: TService);
  procedure ServicePause(Sender: TService; var Paused: Boolean);
  procedure ServiceShutdown(Sender: TService);
  procedure ServiceStart(Sender: TService; var Started: Boolean);
  procedure ServiceStop(Sender: TService; var Stopped: Boolean);
  private
  { Private declarations }
  public
  function GetServiceController: TServiceController; override;
  { Public declarations }
  end;
  
  var
  DelphiService: TDelphiService;
  FrmMain: TFrmMain;
  implementation
  
  {$R *.DFM}
  
  procedure ServiceController(CtrlCode: DWord); stdcall;
  begin
    DelphiService.Controller(CtrlCode);
  end;
  
  function TDelphiService.GetServiceController: TServiceController;
  begin
    Result := ServiceController;
  end;
  
  procedure TDelphiService.ServiceContinue(Sender: TService;
  var Continued: Boolean);
  begin
    while not Terminated do
    begin
      Sleep(10);
      ServiceThread.ProcessRequests(False);
    end;
  end;
  
  procedure TDelphiService.ServiceExecute(Sender: TService);
  begin
    while not Terminated do
    begin
      Sleep(10);
      ServiceThread.ProcessRequests(False);
    end;
  end;
  
  procedure TDelphiService.ServicePause(Sender: TService;
  var Paused: Boolean);
  begin
    Paused := True;
  end;
  
  procedure TDelphiService.ServiceShutdown(Sender: TService);
  begin
    gbCanClose := true;
    FrmMain.Free;
    Status := CSStopped;
    ReportStatus();
  end;
  
  procedure TDelphiService.ServiceStart(Sender: TService;
  var Started: Boolean);
  begin
    Started := True;
    Svcmgr.Application.CreateForm(TFrmMain, FrmMain);
    gbCanClose := False;
    FrmMain.Hide;
  end;
  
  procedure TDelphiService.ServiceStop(Sender: TService;
  var Stopped: Boolean);
  begin
    Stopped := True;
    gbCanClose := True;
    FrmMain.Free;
  end;
  
  end.
  


  
  主窗口單元如下:
  
  


  unit Unit_FrmMain;
  
  interface
  
  uses
  Windows, Messages, SysUtils, Variants, Classes, ShellApi, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;
  
  const
  WM_TrayIcon = WM_USER + 1234;
  type
  TFrmMain = class(TForm)
  Timer1: TTimer;
  Button1: TButton;
  procedure FormCreate(Sender: TObject);
  procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  procedure FormDestroy(Sender: TObject);
  procedure Timer1Timer(Sender: TObject);
  procedure Button1Click(Sender: TObject);
  private
  { Private declarations }
  IconData: TNotifyIconData;
  procedure AddIconToTray;
  procedure DelIconFromTray;
  procedure TrayIconMessage(var Msg: TMessage); message WM_TrayIcon;
  procedure SysButtonMsg(var Msg: TMessage); message WM_SYSCOMMAND;
  public
  { Public declarations }
  end;
  
  var
  FrmMain: TFrmMain;
  gbCanClose: Boolean;
  implementation
  
  {$R *.dfm}
  
  procedure TFrmMain.FormCreate(Sender: TObject);
  begin
    FormStyle := fsStayOnTop; {窗口最前}
    SetWindowLong(Application.Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW); {不在任務欄顯示}
    gbCanClose := False;
    Timer1.Interval := 1000;
    Timer1.Enabled := True;
  end;
  
  procedure TFrmMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  begin
    CanClose := gbCanClose;
    if not CanClose then
    begin
      Hide;
    end;
  end;
  
  procedure TFrmMain.FormDestroy(Sender: TObject);
  begin
    Timer1.Enabled := False;
    DelIconFromTray;
  end;
  
  procedure TFrmMain.AddIconToTray;
  begin
    ZeroMemory(@IconData, SizeOf(TNotifyIconData));
    IconData.cbSize := SizeOf(TNotifyIconData);
    IconData.Wnd := Handle;
    IconData.uID := 1;
    IconData.uFlags := NIF_MESSAGE or NIF_ICON or NIF_TIP;
    IconData.uCallbackMessage := WM_TrayIcon;
    IconData.hIcon := Application.Icon.Handle;
    IconData.szTip := 'Delphi服務演示程序';
    Shell_NotifyIcon(NIM_ADD, @IconData);
  end;
  
  procedure TFrmMain.DelIconFromTray;
  begin
    Shell_NotifyIcon(NIM_DELETE, @IconData);
  end;
  
  procedure TFrmMain.SysButtonMsg(var Msg: TMessage);
  begin
    if (Msg.wParam = SC_CLOSE) or
    (Msg.wParam = SC_MINIMIZE) then Hide
    else inherited; // 執行默認動作
  
end;
  
  procedure TFrmMain.TrayIconMessage(var Msg: TMessage);
  begin
    if (Msg.LParam = WM_LBUTTONDBLCLK) then Show();
  end;
  
  procedure TFrmMain.Timer1Timer(Sender: TObject);
  begin
    AddIconToTray;
  end;
  
  procedure SendHokKey;stdcall;
  var
  HDesk_WL: HDESK;
  begin
    HDesk_WL := OpenDesktop ('Winlogon', 0, False, DESKTOP_JOURNALPLAYBACK);
    if (HDesk_WL <> 0) then
    if (SetThreadDesktop (HDesk_WL) = True) then
    PostMessage(HWND_BROADCAST, WM_HOTKEY, 0, MAKELONG (MOD_ALT or MOD_CONTROL, VK_DELETE));
  end;
  
  procedure TFrmMain.Button1Click(Sender: TObject);
  var
  dwThreadID : DWord;
  begin
    CreateThread(nil, 0, @SendHokKey, nil, 0, dwThreadID);
  end;
  
  end.
  
  program ServiceDemo;
  
  uses
  SvcMgr,
  Unit_Main in 'Unit_Main.pas' {DelphiService: TService},
  Unit_frmMain in 'Unit_frmMain.pas' {frmMain};
  
  {$R *.RES}
  
  begin
    Application.Initialize;
    Application.CreateForm(TDelphiService, DelphiService);
    Application.Run;
  end.
  


  
  
  窗體代碼如下:
  


  object DelphiService: TDelphiService
  OldCreateOrder = False
  DisplayName = 'Delphi服務演示程序'
  Interactive = True
  OnContinue = ServiceContinue
  OnExecute = ServiceExecute
  OnPause = ServicePause
  OnShutdown = ServiceShutdown
  OnStart = ServiceStart
  OnStop = ServiceStop
  Left = 261
  Top = 177
  Height = 150
  Width = 215
  end
  
  object frmMain: TfrmMain
  Left = 192
  Top = 107
  Width = 696
  Height = 480
  Caption = '我的服務測試程序'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnCloseQuery = FormCloseQuery
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  PixelsPerInch = 96
  TextHeight = 13
  object Button1: TButton
  Left = 296
  Top = 264
  Width = 75
  Height = 25
  Caption = 'Button1'
  TabOrder = 0
  OnClick = Button1Click
  end
  object Timer1: TTimer
  OnTimer = Timer1Timer
  Left = 120
  Top = 192
  end
  end
  


  
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved