2012-08-05 75 views
10

我是Delphi學習者。我正在尋找解決方案,以便將Delphi MainForm最小化到系統托盤而不是任務欄。在系統托盤圖標上點擊右鍵,應該有一些菜單,如「恢復」和「關於」和「幫助」等。系統托盤圖標將從Imagelis1加載,它會動畫。在點擊「恢復」時,MainForm將被恢復,點擊「關於」「Form2」將被恢復,點擊「幫助」後將恢復「Foprm3」。我發現這麼多的解決方案,互聯網上,如:將Delphi表單最小化爲系統托盤

Solution 01

Solution 02

但每個解決方案有一些缺點。有些可以一次完成。一些在Windows7中有模糊的圖標。有人可能會說沒有人爲我編寫代碼,我必須顯示我的代碼。 Plaese原諒我的這個問候。請給我一個具體的解決方案,告訴它可以在不依賴於windows的版本的情況下實現通用。它會幫助每一個人。請幫幫我。

+2

使用Delphi提供的任務欄圖標組件。模糊圖標表示與托盤圖標關聯的圖標與系統托盤圖標大小不同(因此,Windows必須調整其大小),因此您需要提供多種尺寸的圖標,包括與系統托盤匹配的圖標圖標大小。 – Jay 2012-08-06 00:03:29

+1

使用'GetSystemMetrics(SM_CXSMICON)'來計算所需的圖標大小。如果你沒有合適的尺寸,那麼創建一個合適尺寸的32bpp位圖,用透明像素填充,然後將其放入該位圖的中間,最近的圖標比正確的尺寸小。然後將位圖轉換爲一個圖標,你是金。對於不同於100%的字體縮放,您可以獲得「SM_CXSMICON」度量標準的各種值。 – 2012-08-06 18:46:52

+0

我是學習者我不知道如何使用「GetSystemMetrics(SM_CXSMICON)」。請給一個完整的解決方案。如果我設置了表單圖標,它會在Win7和「Alt + Tab」中變得模糊。請幫幫我。 – 2012-08-07 19:43:05

回答

18

這應該讓你去。在表單上放置TTrayIconTApplicationEvents。以下代碼來自docwikiTTrayIcon - Delphi Example。使用IDE主菜單,並選擇Project->View Source,並將Application.ShowMainFormOnTaskbar := True;的行寫入`Application.ShowMainFormOnTaskbar:= False;'讓應用程序的按鈕不會出現在Windows任務欄上。

本示例在窗體上使用托盤圖標和應用程序事件組件。當應用程序運行時,它會加載托盤圖標,動畫時顯示的圖標以及設置提示氣球。當您最小化窗口時,窗體將隱藏,顯示一個提示氣球,並顯示托盤圖標並生成動畫。雙擊系統托盤圖標恢復窗口。

// Add this to the `TApplicationEvents.OnMinimize` event handler 
procedure TForm1.ApplicationEvents1Minimize(Sender: TObject); 
begin 
    { Hide the window and set its state variable to wsMinimized. } 
    Hide(); 
    WindowState := wsMinimized; 

    { Show the animated tray icon and also a hint balloon. } 
    TrayIcon1.Visible := True; 
    TrayIcon1.Animate := True; 
    TrayIcon1.ShowBalloonHint; 
end; 

// Add this to the `TForm.OnCreate` event handler 
procedure TForm1.FormCreate(Sender: TObject); 
var 
    MyIcon : TIcon; 
begin 
    { Load the tray icons. } 
    TrayIcon1.Icons := TImageList.Create(Self); 
    MyIcon := TIcon.Create; 
    MyIcon.LoadFromFile('icons/earth1.ico'); 
    TrayIcon1.Icon.Assign(MyIcon); 
    TrayIcon1.Icons.AddIcon(MyIcon); 

    MyIcon.LoadFromFile('icons/earth2.ico'); 
    TrayIcon1.Icons.AddIcon(MyIcon); 
    MyIcon.LoadFromFile('icons/earth3.ico'); 
    TrayIcon1.Icons.AddIcon(MyIcon); 
    MyIcon.LoadFromFile('icons/earth4.ico'); 
    TrayIcon1.Icons.AddIcon(MyIcon); 

    { Set up a hint message and the animation interval. } 
    TrayIcon1.Hint := 'Hello World!'; 
    TrayIcon1.AnimateInterval := 200; 

    { Set up a hint balloon. } 
    TrayIcon1.BalloonTitle := 'Restoring the window.'; 
    TrayIcon1.BalloonHint := 
    'Double click the system tray icon to restore the window.'; 
    TrayIcon1.BalloonFlags := bfInfo; 
end; 

// Add this to the `TTrayIcon.OnDoubleClick` event handler 
procedure TForm1.TrayIcon1DblClick(Sender: TObject); 
begin 
    { Hide the tray icon and show the window, 
    setting its state property to wsNormal. } 
    TrayIcon1.Visible := False; 
    Show(); 
    WindowState := wsNormal; 
    Application.BringToFront(); 
end; 

你所得到的菜單上單擊鼠標右鍵,添加TPopupMenu到窗體中,添加要上的項目,寫這些項目照常事件處理程序,然後分配PopupMenuTrayIcon.PopupMenu屬性。

「模糊圖標」是由於您沒有使用正確的圖標大小而導致Windows被迫縮放(拉伸)它們。使用圖標編輯器爲每個圖標創建多個尺寸的圖像(在一個圖標文件中可以有多種尺寸)。

+0

非常感謝。你的解決方案對我來說是一個小問題。在我的項目中,我使用「定時器」作爲「FormMinimizing」,「FormShowing」,「FormHiding」和「FormRestoring」。您可以在以下鏈接中找到我的項目。 [**我的項目**](http://stackoverflow.com/questions/11699277/delphi-form-switching-using-timer/11705857#11705857)在最小化窗體後,它將轉到「SystemTray」,但也可用於「任務欄」。所以我已經嘗試了[**解決方案**]中找到的解決方案(http://stackoverflow.com/questions/681621/hide-the-main-form-in-a-delphi-2009-application)然後窗體是無敵的。 – 2012-08-07 19:54:48

+1

請參閱我在關於'Application.ShowMainFormOnTaskbar'的第一段中的編輯。 :-) – 2012-08-07 20:56:01

+0

很好的例子,謝謝! – TheSteven 2012-11-24 20:09:32

1

我已經實施了以下代碼。這裏一切都很好,除了一個。減少後的形式,它進入「的SystemTray」,但在「任務欄。我的應用程序中,‘Form001的AlphaBlend’財產‘’是真實的,‘AlphaBlendValue也可’爲‘0’。

unit KoushikHalder001; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls, Vcl.Imaging.pngimage, 
    Vcl.AppEvnts, Vcl.ImgList, Vcl.Menus; 

type 
    TForm001 = class(TForm) 
    Edit001: TEdit; 
    Background: TImage; 
    BitBtn001: TBitBtn; 
    BitBtn002: TBitBtn; 
    FadeInTimer: TTimer; 
    FadeOutTimer: TTimer; 
    FormMinimizeTimer: TTimer; 
    FormRestoreTimer: TTimer; 
    TrayIcon: TTrayIcon; 
    PopupMenu: TPopupMenu; 
    ImageList: TImageList; 
    ApplicationEvents: TApplicationEvents; 
    Form001Close: TMenuItem; 
    Form001Hide: TMenuItem; 
    Form001Show: TMenuItem; 
    Form002Close: TMenuItem; 
    Form002Hide: TMenuItem; 
    Form002Show: TMenuItem; 
    N01: TMenuItem; 
    N02: TMenuItem; 
    N03: TMenuItem; 
    N04: TMenuItem; 
    N05: TMenuItem; 
    N06: TMenuItem; 
    N07: TMenuItem; 
    N08: TMenuItem; 
    N09: TMenuItem; 
    N10: TMenuItem; 
    procedure FormClose(Sender: TObject; var Action: TCloseAction); 
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); 
    procedure FormCreate(Sender: TObject); 
    procedure FormHide(Sender: TObject); 
    procedure FormShow(Sender: TObject); 
    procedure BitBtn001Click(Sender: TObject); 
    procedure BitBtn002Click(Sender: TObject); 
    procedure FadeInTimerTimer(Sender: TObject); 
    procedure FadeOutTimerTimer(Sender: TObject); 
    procedure FormMinimizeTimerTimer(Sender: TObject); 
    procedure FormRestoreTimerTimer(Sender: TObject); 
    procedure ApplicationEventsMinimize(Sender: TObject); 
    procedure TrayIconDblClick(Sender: TObject); 
    procedure Form001CloseClick(Sender: TObject); 
    procedure Form001HideClick(Sender: TObject); 
    procedure Form001ShowClick(Sender: TObject); 
    procedure Form002CloseClick(Sender: TObject); 
    procedure Form002HideClick(Sender: TObject); 
    procedure Form002ShowClick(Sender: TObject); 
    private 
    { Private declarations } 
    CrossButtonClick: Boolean; 
    procedure WMNCHitTest(var Msg: TWMNCHitTest) ; message WM_NCHitTest; 
    procedure WMSysCommand(var Msg: TWMSysCommand) ; message WM_SysCommand; 
    public 
    { Public declarations } 
    end; 

var 
    Form001: TForm001; 

implementation 

{$R *.dfm} 

uses KoushikHalder002; 


procedure TForm001.WMNCHitTest(var Msg: TWMNCHitTest); 
begin 
    inherited; 
    if ControlAtPos(ScreenToClient(Msg.Pos), True, True, True)= nil 
    then 
     begin 
     if Msg.Result=htClient then Msg.Result := htCaption; 
     end; 
end; 

procedure TForm001.WMSysCommand(var Msg: TWMSysCommand); 
begin 
    case Msg.CmdType of 
    SC_MINIMIZE: 
     begin 
     if Form001.AlphaBlendValue > 0 then 
      begin 
      Form001.FormMinimizeTimer.Enabled := true; 
      Exit; 
      end; 
     end; 
    SC_RESTORE: 
     begin 
     if Form001.AlphaBlendValue < 220 then 
      begin 
      Form001.FormRestoreTimer.Enabled := True; 
      end; 
     end; 
    end; 
    inherited; 
end; 

procedure TForm001.ApplicationEventsMinimize(Sender: TObject); 
begin 
    Form001.FormMinimizeTimer.Enabled := true; 
    TrayIcon.Visible := True; 
    TrayIcon.Animate := True; 
    TrayIcon.ShowBalloonHint; 
end; 

procedure TForm001.BitBtn001Click(Sender: TObject); 
begin 
    if Form002.WindowState = wsMinimized then 
    begin 
     Form002.Perform(WM_SYSCOMMAND, SC_RESTORE, 0); 
    end 
    else 
    Form002.show; 
end; 

procedure TForm001.BitBtn002Click(Sender: TObject); 
begin 
    Form002.FadeOutTimer.Enabled := true; 
    Form001.FadeOutTimer.Enabled := true; 
end; 

procedure TForm001.Form001CloseClick(Sender: TObject); 
begin 
    Form002.FadeOutTimer.Enabled := true; 
    Form001.FadeOutTimer.Enabled := true; 
end; 

procedure TForm001.Form001HideClick(Sender: TObject); 
begin 
Form001.FormMinimizeTimer.Enabled := true; 
end; 

procedure TForm001.Form001ShowClick(Sender: TObject); 
begin 
    if Form001.WindowState = wsMinimized then 
    begin 
     Form001.Perform(WM_SYSCOMMAND, SC_RESTORE, 0); 
    end 
    else 
    Form001.show; 
end; 

procedure TForm001.Form002CloseClick(Sender: TObject); 
begin 
Form002.FadeOutTimer.Enabled := true; 
end; 

procedure TForm001.Form002HideClick(Sender: TObject); 
begin 
Form002.FormMinimizeTimer.Enabled := true; 
end; 

procedure TForm001.Form002ShowClick(Sender: TObject); 
begin 
    if Form002.WindowState = wsMinimized then 
    begin 
     Form002.Perform(WM_SYSCOMMAND, SC_RESTORE, 0); 
    end 
    else 
    Form002.show; 
end; 

procedure TForm001.FormClose(Sender: TObject; var Action: TCloseAction); 
begin 
    Form001.FadeOutTimer.Enabled := true; 
end; 

procedure TForm001.FormCloseQuery(Sender: TObject; var CanClose: Boolean); 
begin 
    if CrossButtonClick = true 
    then 
     begin 
     CanClose := true; 
     Exit; 
     end; 
    CanClose := false; 
    Form001.FadeOutTimer.Enabled := true; 
end; 

procedure TForm001.FormCreate(Sender: TObject); 
begin 
    Form001.FadeInTimer.Enabled := true; 
end; 

procedure TForm001.FormHide(Sender: TObject); 
begin 
    Form001.FadeOutTimer.Enabled := true; 
end; 

procedure TForm001.FormShow(Sender: TObject); 
begin 
    Form001.FadeInTimer.Enabled := true; 
end; 
procedure TForm001.TrayIconDblClick(Sender: TObject); 
begin 
    Form001.FormRestoreTimer.Enabled := true; 
    TrayIcon.Visible := False; 
    WindowState := wsNormal; 
    Application.BringToFront(); 
end; 

procedure TForm001.FadeInTimerTimer(Sender: TObject); 
begin 
    if Form001.AlphaBlendValue >= 220 
    then 
     begin 
     Form001.FadeInTimer.Enabled := false; 
     end 
    else 
     begin 
     Form001.AlphaBlendValue := Form001.AlphaBlendValue + 10; 
     CrossButtonClick := false; 
     end; 
end; 

procedure TForm001.FadeOutTimerTimer(Sender: TObject); 
begin 
    if Form001.AlphaBlendValue <= 0 
    then 
     begin 
     Form001.FadeOutTimer.Enabled := false; 
     CrossButtonClick := true; 
     Self.Close; 
     end 
    else 
     begin 
     Form001.AlphaBlendValue := Form001.AlphaBlendValue - 10; 
     CrossButtonClick := true; 
     end; 
end; 

procedure TForm001.FormMinimizeTimerTimer(Sender: TObject); 
begin 
    if Form001.AlphaBlendValue > 0 then 
    begin 
     Form001.AlphaBlendValue := Form001.AlphaBlendValue - 10; 
    end 
    else 
    begin 
     Form001.FormMinimizeTimer.Enabled := false; 
     Perform(WM_SYSCOMMAND, SC_MINIMIZE, 0); 
    end; 
end; 

procedure TForm001.FormRestoreTimerTimer(Sender: TObject); 
begin 
    if Form001.AlphaBlendValue < 220 then 
    begin 
     Form001.AlphaBlendValue := Form001.AlphaBlendValue + 10; 
    end 
    else 
    begin 
     Form001.FormRestoreTimer.Enabled := false; 
    end; 
end; 

end. 

如果我做了以下

Application.MainFormOnTaskbar := false; 

形式是完全invissible。我覺得應該有一個錯誤,但是我無法找到它。

4

我滴個任務欄圖標到myForm的,然後我加入這個簡單的代碼:

type 
    TmyForm = class(TForm) 
    ... 
    TrayIcon: TTrayIcon; 
    procedure FormCreate(Sender: TObject); 
    ... 
    procedure TrayIconClick(Sender: TObject); 
    ... 
    private 
    { Private declarations } 
    procedure OnMinimize(Sender:TObject); 
    public 
    { Public declarations } 
    end; 

procedure TmyForm.FormCreate(Sender: TObject); 
begin // When form is created 
    Application.OnMinimize:=OnMinimize; // Set the event handler for application minimize 
end; 

procedure TmyForm.OnMinimize(Sender:TObject); 
begin // When application is minimized by user and/or by code 
    Hide; // This is to hide it from taskbar 
end; 

procedure TmyForm.TrayIconClick(Sender: TObject); 
begin // When clicking on TrayIcon 
    if Visible 
    then begin // Application is visible, so minimize it to TrayIcon 
       Application.Minimize; // This is to minimize the whole application 
      end 
    else begin // Application is not visible, so show it 
       Show; // This is to show it from taskbar 
       Application.Restore; // This is to restore the whole application 
      end; 
end; 

這將創建一個任務欄圖標八方通可見,當你點擊它:

  • 如果應用程序是可見,它將隱藏在任務欄和屏幕上
  • 如果應用程序是隱藏的,它將顯示爲任務欄並從屏幕上顯示

換句話說,點擊TrayIcon應用程序將改變其可見性;就像將其最小化到TrayIcon酒吧一樣。

+0

這很好,但它沒有處理2件事:當點擊托盤圖標時,應用程序不專注。它保持最小化。當點擊「X」時,應用程序關閉,而不是最小化到托盤。這兩個問題的任何解決方案? – bashan 2015-11-14 09:28:28

2

...在Delphi 6中,在沒有TTrayIcon存在,你可以使用這個簡單的代碼:

unit MainUnit; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, ShellAPI, StdCtrls, Menus; 

const WM_ICONTRAY = WM_USER+1; 

type 
    TForm1 = class(TForm) 
    PopupMenu1: TPopupMenu; 
    ShowForm1: TMenuItem; 
    HideForm1: TMenuItem; 
    Exit1: TMenuItem; 
    procedure TrayMessage(var Msg: TMessage); message WM_ICONTRAY; 
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure ShowForm1Click(Sender: TObject); 
    procedure HideForm1Click(Sender: TObject); 
    procedure Exit1Click(Sender: TObject); 
    procedure FormClose(Sender: TObject; var Action: TCloseAction); 
    private 
    TrayIconData: TNotifyIconData; 
    end; 

var 
    Form1: TForm1; 
    MustExit:boolean; 

implementation 

{$R *.dfm} 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    MustExit:=false; 
    TrayIconData.cbSize:=SizeOf(TrayIconData); 
    TrayIconData.Wnd:=Handle; 
    TrayIconData.uID:=0; 
    TrayIconData.uFlags:=NIF_MESSAGE + NIF_ICON + NIF_TIP; 
    TrayIconData.uCallbackMessage:=WM_ICONTRAY; 
    TrayIconData.hIcon:=Application.Icon.Handle; 
    StrPCopy(TrayIconData.szTip,Application.Title); 
    Shell_NotifyIcon(NIM_ADD, @TrayIconData); 
end; 

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
    Shell_NotifyIcon(NIM_DELETE, @TrayIconData); 
end; 

procedure TForm1.TrayMessage(var Msg: TMessage); 
var p:TPoint; 
begin 
    case Msg.lParam of 
    WM_LBUTTONDOWN: begin 
        Form1.Show; 
        Application.Restore; 
        end; 
    WM_RBUTTONDOWN: begin 
        GetCursorPos(p); 
        PopUpMenu1.Popup(p.x,p.y); 
        end; 
    end; 
end; 

// Popup "Form Show" menu item OnClick 
procedure TForm1.ShowForm1Click(Sender: TObject); 
begin 
Form1.Show; 
end; 

// Popup "Form Hide" menu item OnClick  
procedure TForm1.HideForm1Click(Sender: TObject); 
begin 
Form1.Hide; 
end; 

// Popup "Exit" menu item OnClick 
procedure TForm1.Exit1Click(Sender: TObject); 
begin 
MustExit:=true; 
Close; 
end; 

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); 
begin 
if MustExit then exit; 
Form1.Hide; 
Action:=caNone; 
end; 

end. 
相關問題