Entwickler-Ecke

Windows API - Hilfe mit Systray


robin86 - Sa 05.06.04 10:09
Titel: Hilfe mit Systray
Ich habe eine kleine Uhr geschreiben, die mich immer zu einer bestimmenten zeit alarmieren soll. Das Problem ist jetzt, das Fenster beim minimieren statt in die taskleiste in des systray zu packen. ich habe dafür ein paar progschnipsel runtergeladen, aber leider funzt es nich ganz. Kann mir bitte jemand sagen, was ich verändern muss:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
unit clockmain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls, mmsystem, FileCtrl, ShellApi, AppEvnts;

  const
  IC_CLICK = WM_APP + 201;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Timer1: TTimer;
    Button2: TButton;
    Label5: TLabel;
    Label6: TLabel;
    Label7: TLabel;
    ApplicationEvents1: TApplicationEvents;

    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure ApplicationEvents1Minimize(Sender: TObject);
  private
    { Private-Deklarationen }
    procedure Systray(var sMsg: TMessage); message IC_CLICK;
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;
  ziel: TDateTime;
  minute, stunde, zeit: string;
  NIM : TNotifyIconData;

implementation



{$R *.dfm}





procedure TForm1.Button1Click(Sender: TObject);

begin
Stunde:=Edit1.Text;
Minute:=Edit2.Text;
zeit:=Stunde + ':' + Minute;
ziel:=strtotime(zeit);
Label1.caption:=timetostr(ziel);

end;



procedure TForm1.Timer1Timer(Sender: TObject);
  var i: integer;
    platz: PAnsiChar;
begin

Label4.Caption:=timetostr(time);
if label1.caption=label4.caption then



begin
if DirectoryExists('c:\windows'then
platz:='c:\windows\media\ringin.wav'
else if DirectoryExists('d:\windows'then
platz:='d:\windows\media\ringin.wav'
else if DirectoryExists('e:\windows'then
platz:='e:\windows\media\ringin.wav'
else if DirectoryExists('f:\windows'then
platz:='f:\windows\media\ringin.wav'
else if DirectoryExists('g:\windows'then
platz:='g:\windows\media\ringin.wav'
else
ShowMessage('Fehler');
  for i:=1 to 3 do
  SNDplaysound(platz, SND_LOOP)

end;

end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Close;
end;

procedure TForm1.Systray(var sMsg: TMessage);
begin
  // Vorgang: Klick auf das Icon neben der Uhr und Anzeige der Anwendung
  inherited;
  if (sMsg.LParam = WM_LBUTTONDOWN) then begin
    Show;
    Shell_NotifyIcon(NIM_DELETE, @NIM);
    Application.Restore; //zeigt die Anwendung wieder an
  end;
end;

procedure TForm1.ApplicationEvents1Minimize(Sender: TObject);
begin
  //Vorgang: Minimieren der Anwendung, Entfernung des Taskleisteneintrags
  //und Hinzufügen des Programmicons neben der Uhr
  Form1.FormStyle:=fsStayOnTop;
  Hide;
  with NIM do begin
    cbSize := SizeOf (nIM);
    Wnd := Handle;
    uID := 0;
    uFlags := NIF_ICON or NIF_MESSAGE or NIF_TIP;
    uCallbackMessage := IC_CLICK;
    hIcon := Application.Icon.Handle;
    szTip := 'Test-Programm';
  end;
  Shell_NotifyIcon(NIM_ADD, @NIM);
end;


end.



Moderiert von user profile iconPeter Lustig: Code- durch Delphi-Tags ersetzt.


Ja-Pa - So 06.06.04 12:35

robin86 hat folgendes geschrieben:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
begin
if DirectoryExists('c:\windows'then
platz:='c:\windows\media\ringin.wav'
else if DirectoryExists('d:\windows'then
platz:='d:\windows\media\ringin.wav'
else if DirectoryExists('e:\windows'then
platz:='e:\windows\media\ringin.wav'
else if DirectoryExists('f:\windows'then
platz:='f:\windows\media\ringin.wav'
else if DirectoryExists('g:\windows'then
platz:='g:\windows\media\ringin.wav'



Und was ist wenn Windows unter H: installiert worden ist?
Oder jemand Windows NT oder 2000 installiert hat? Da heißt das Verzeichnis "Windows" nämlich "winnt".
Das Windows-Verzeinis kannst du auch einfach so ermitteln:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
function GetWinDir: string
var 
  dir: array [0..MAX_PATH] of Char; 
begin 
  GetWindowsDirectory(dir, MAX_PATH); 
  Result := StrPas(dir); 
end;


Für das Sytray-Icon kannst du auch diese Komponente verwenden:
http://swiss.torry.net/vcl/system/tasks/tytsystray.zip

Übrigens: Hier
http://swiss.torry.net/apps/utilities/tray/aclock.exe
gibt es schon in etwa so ein Programm, das du gerade programmierst.
Falls du das Programm also "nur für dich" programmierst, kannst du auch dieses Programm verwenden.


Tino - So 06.06.04 13:44
Titel: Re: Hilfe mit Systray
robin86 hat folgendes geschrieben:
aber leider funzt es nich ganz.

Was genau funktioniert denn nicht? Fehlermeldungen?


robin86 - So 06.06.04 17:07

Nur wenn ich minimiert habe, ist das Prog trotzdem in die Taskleiste gegangen ;)

@Ja-Pa
Danke für den Tipp ;)


Ja-Pa - So 06.06.04 18:47

Wenns weiter nichts ist...
So kannst du die Schaltfläche in der Taskbar ausblenden:


Delphi-Quelltext
1:
2:
3:
4:
ShowWindow(Application.Handle, SW_HIDE );
SetWindowLong(Application.Handle, GWL_EXSTYLE, GetWindowLong(Application.Handle, GWL_EXSTYLE) 
              or WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);
ShowWindow(Application.Handle, SW_SHOW);


robin86 - So 06.06.04 21:31

Ok, noch ma was ganz anderes, ich wollte GetWinDir in ne eigne dll schreiben:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
library WindowsDirectory;

uses
  SysUtils,
  Classes,
  Windows;

{$R *.res}

function GetWinDir: Ansistring;
var
  dir: array [0..MAX_PATH] of Char;
begin
  GetWindowsDirectory(dir, MAX_PATH);
  Result := StrPas(dir);
end;

exports
GetWinDir;

begin

end.


Das ist die dll. Die Krieg ich aber mir dem Prog

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
unit aufrufdll;

interface


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

function GetWinDir:ansistring; stdcall;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetWinDir; stdcall;
external 'WindowsDirectory.dll';

procedure TForm1.Button1Click(Sender: TObject);
var dire: ansiString;
begin
dire:=GetWinDir;
Label1.Caption:=dire;
end;

end.

nicht zumm laufen. Kann mir bitte wer sagen warum nicht????


Moderiert von user profile iconPeter Lustig: Code- durch Delphi-Tags ersetzt.


Delete - So 06.06.04 21:58

robin86 hat folgendes geschrieben:
Ok, noch ma was ganz anderes, [...]

Eigentlich: Neue Frage, neuer Thread.

Zitat:
[...] ich wollte GetWinDir in ne eigne dll schreiben:

Ach ja? Und warum? Ist für mich doppelt gemoppelt, weil die Funktion bereits von einer Bibliothek zur Verfügung gestellt wird.


Ansonsten, zum ursprünglichen Thema: klick [http://www.delphi-forum.de/viewtopic.php?p=12310#12310] - mit der Einschränkung, dass sie bei [WIN]-M nicht richtig reagiert. Aus dem Beitrag:
Zitat:
Wie gesagt: wenn du den Hotkey [WIN]-M benutzt, bleibt der Taskbar-Button.

Das liegt IMHO daran, dass die VCL den entsprechenden Befehl nicht zur Bearbeitung weiterleitet. Bei einem nonVCL-Programm geht die Minimierung in die TNA auch mit dem o.g. Hotkey problemlos.


robin86 - Mo 07.06.04 15:36

@JA-Pa

Wenn ich dein systray benutzen will, was mach ich dann Falsch:

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.Button1Click(Sender: TObject);
begin
Systray.TSystray.Minimize;
end;


DieProzedur lässt sich nich aufrufen


Ja-Pa - Mo 07.06.04 20:37

Was heißt denn "lässt sich nicht aufrufen"?
Gibt es diese Methode nicht oder gibt es eine Fehlermeldung?
Ich hab die Anwendung mit

Delphi-Quelltext
1:
Application.Minimize;                    

minimiert.

Und was das mit der DLL betrifft:
Warum machst du für so wenig Code eine eigenene DLL?
Verwende es doch einfach so in der gleichen Unit.


robin86 - Mo 07.06.04 21:36

Ich meine, dass ich es ja per uses einbinden muss (oder?) aber dann steht da in der Systray Unit, dass man TSystray auf das Formular ziehen soll. Aber wo finde ich das TSystray?


robin86 - Di 08.06.04 09:14

Ich habe es jetzt auch mit


Delphi-Quelltext
1:
ShowWindow(GetWindow(Handle, GW_OWNER), SW_HIDE);                    


versucht, aber das klappt nich wenn ich es OnCreate machen. Ich will aber, dass das Prog gleich bei dem Start gar nicht erst in der Taskleiste erscheint. So wie bei den aneren icon in systray wie z.B. Winamp od Norton.