2012-08-05 6 views
10

Sono uno studente Delphi. Sto cercando soluzioni in modo che Delphi MainForm debba essere ridotto a icona sulla barra delle applicazioni invece che sulla barra delle applicazioni. Facendo clic con il pulsante destro del mouse sull'icona dell'icona di sistema, alcuni menu come "Ripristina" e "Informazioni" e "Guida" ecc. Le icone del vassoio di sistema verranno caricate da Imagelis1 e verranno animate. Cliccando su "Restore" il MainForm verrà ripristinato, cliccando su "About" "Form2" sarà ripristinato e cliccando su "Help" "Foprm3" verrà ripristinato. Ho trovato così tante soluzioni su internet come:Riduci a icona il modulo Delphi nel vassoio di sistema

Solution 01

Solution 02

ma ogni soluzioni presentano alcuni inconvenienti. Alcuni possono essere fatti una volta sola. Alcuni hanno l'icona sfocata in Windows7. Qualcuno potrebbe dire che non c'è nessuno per scrivere i codici per me e devo mostrare i miei codici. Plaese, perdonami per questo. Per favore, dammi una soluzione concreta perché può essere implementata universalmente senza la dipendenza dalla versione di Windows. Aiuterà tutti. Mi aiuti per favore.

+2

utilizzare il componente TrayIcon fornito da Delphi. L'icona sfocata indica che l'icona associata all'icona del vassoio non ha le stesse dimensioni dell'icona della barra delle applicazioni (quindi, Windows deve ridimensionarla), quindi è necessario fornire l'icona in più dimensioni, inclusa quella corrispondente al vassoio di sistema dimensione dell'icona. – Jay

+1

Utilizzare 'GetSystemMetrics (SM_CXSMICON)' per calcolare la dimensione richiesta dell'icona. Se non ne hai la giusta dimensione, crea una bitmap a 32 bit di dimensioni corrette, riempila con pixel trasparenti e quindi inserisci nel mezzo di questa bitmap, l'icona più vicina piccola della giusta dimensione. Quindi converti la bitmap in un'icona e sei d'oro. Per il ridimensionamento dei caratteri diverso dal 100% è possibile ottenere una varietà di valori per la metrica 'SM_CXSMICON'. –

+0

Sono uno studente non so come usare "GetSystemMetrics (SM_CXSMICON)". Si prega di dare una soluzione completa. Se imposto l'icona modulo, viene visualizzato in Win7 e in "Alt + Tab". Mi aiuti per favore. –

risposta

18

Questo dovrebbe farti andare. Lascia un TTrayIcon e un TApplicationEvents sul modulo. Il seguente codice è dallo TTrayIcon - Delphi Example dello docwiki. Utilizzare il menu principale IDE e scegliere Project->View Source e la riga che legge Application.ShowMainFormOnTaskbar := True; in `Application.ShowMainFormOnTaskbar: = False; ' per mantenere il pulsante dell'applicazione da apparire nella barra delle applicazioni di Windows.

Questo esempio utilizza un'icona di barra e un componente di eventi di applicazione in un modulo. Quando l'applicazione viene eseguita, carica l'icona del vassoio, le icone visualizzate quando è animata e imposta anche un fumetto di suggerimento. Quando si riduce a icona la finestra, il modulo viene nascosto, viene visualizzato un fumetto di suggerimento e l'icona del vassoio viene visualizzata e animata. Fare doppio clic sull'icona della barra delle applicazioni per ripristinare la finestra.

// 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; 

Per il menu che si ottiene sul tasto destro del mouse, aggiungere un TPopupMenu al form, aggiungere gli elementi che si desidera su di esso, scrivere i gestori di eventi per gli elementi come al solito, e quindi assegnare il PopupMenu a la proprietà TrayIcon.PopupMenu.

Le "icone sfocate" sono causate dal fatto che non si utilizzano le dimensioni appropriate dell'icona e Windows viene forzato a ridimensionarle (allungarle). Utilizzare un editor di icone per creare immagini di dimensioni multiple per ciascuna icona (possono esserci più formati in un unico file di icone).

+0

Grazie mille. La tua soluzione sta funzionando bene con un piccolo problema per me. Nel mio progetto, sto usando "Timer" per "FormMinimizing" "FormShowing" "FormHiding" e "FormRestoring". Puoi trovare il mio progetto nel seguente link. [** Il mio progetto **] (http://stackoverflow.com/questions/11699277/delphi-form-switching-using -timer/11705857#11705857) Dopo aver ridotto a icona il modulo, passa a "SystemTray" ma è disponibile anche in "barra delle applicazioni". Quindi ho provato la soluzione trovata in [** Soluzione **] (http://stackoverflow.com/questions/681621/hide-the-main-form-in-a-delphi-2009-application) quindi il modulo è ammissibile . –

+1

Vedere la mia modifica nel primo paragrafo su 'Application.ShowMainFormOnTaskbar'. :-) –

+0

Eccellente esempio, grazie! – TheSteven

1

Ho implementato i seguenti codici. Qui va tutto bene tranne uno. Dopo minimizzando il modulo, si va a "SystemTray", ma disponibile anche in "barra delle applicazioni. Per la mia applicazione, il 'AlphaBlend' di proprietà di 'Form001' è vero e '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. 

Se faccio il seguente

Application.MainFormOnTaskbar := false; 

la forma è totalmente invissible. Penso che ci dovrebbe essere un bug. Ma io sono in grado di trovarlo.

4

mi cade un TrayIcon sul myForm, poi aggiungo questo semplice codice:

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; 

Questo crea un TrayIcon allways visibile, e quando si fa clic su di esso:

  • Se l'applicazione è visibile , sarà la barra delle applicazioni del modulo Nascosto e dalla schermata
  • Se l'applicazione è nascosta, verrà visualizzata la barra delle attività del modulo e dalla schermata

In altre parole, facendo clic su TrayIcon l'applicazione cambierà la sua visibilità; come minimizzare la barra di TrayIcon.

+0

Questo è bello, ma non si cura di 2 cose: quando si fa clic sull'icona del vassoio, l'app non è focalizzata. Rimane minimizzato. E quando si fa clic su "X", l'app si chiude invece di essere ridotta a icona. Qualche soluzione per questi 2 problemi? – bashan

2

... E in Delphi 6, in cui non esiste TTrayIcon, è possibile utilizzare questo semplice codice:

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.