Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Form immer sichtbar/ Win+R abfangen


IhopeonlyReader - Sa 13.04.13 18:37
Titel: Form immer sichtbar/ Win+R abfangen
Guten Tag, ich wollte mal ne schöne Uhr auf mein Desktop setzen :D
alles sieht wunderbar aus, jedoch kenn ich nur 2 Möglichkeiten die Uhr nicht mimierbar zu machen...
Sie soll nicht minimiert werden wenn ich auf "Desktop anzeigen" klicke..
FsStayonTop soll vermieden werden, da sie nur auf dem Desktop sein soll (wie ein sich änderner Bildschirmhintergrund mit einer Uhr (die stimmt))
BorderStyle auf bsSizeToolWin da habe ich leider den Rand (Border) :(
Gibt es noch eine andere Möglichkeit? (ohne unbedingt auf Windows_messages zu reagieren)


Moderiert von user profile iconNarses: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Mo 15.04.2013 um 16:29


Tranx - Sa 13.04.13 20:27

Soweit ich es getestet habe, reagiert das Ereignis OnMinimize nicht auf das Windowsereignis "Desktop anzeigen". Daher ist es nicht möglich, dies durch das Ereignis OnMinimize zu realisieren. Wahrscheinlich kommt man um eine Message-Behandlungsroutine (Application.OnMessage) nicht drum rum. Aber leider habe ich da wenig Erfahrungen.


IhopeonlyReader - Sa 13.04.13 20:35

ok dann von mir aus mit Messages.. aber so, dass es Nicht über anderen Anwendungen/fenstern liegt..


Tranx - Sa 13.04.13 20:44

Aber ich habe eines getestet, und das scheint zu funktioneren.

Du benötigst doch für die Uhr einen Timer. In der Timer-Routine schreibst Du den Befehl:


Delphi-Quelltext
1:
  Application.Restore;                    


Dann wird wenigstens bei jedem Timer-Aufruf (nach x ms gemäß Timer.Interval) die Uhr wieder angezeigt. Das habe ich getestet und es funktioniert.


IhopeonlyReader - Sa 13.04.13 21:19

Also mit

Delphi-Quelltext
1:
2:
3:
4:
5:
if (WindowState=wsMinimized) then
  begin
  sleep(10);
  WindowState := wsNormal;
  end;

funktioniert es immer BIS auf wenn ich "Desktop anzeigen" geklickt habe (Win+M funktioniert es, Win+D funktioniert es nicht)

Delphi-Quelltext
1:
Application.Restore;                    

wenn ich nun irgendein Fenster in den Vordergrund rufe, (nach Win+D/Desktop anzeige) ist die Uhr auf dem Desktop wieder sichtbar.
wenn ich kein Fenster öffne, bleibt die Uhr unsichtbar

Edit: Application.Restore ändert gar nichts, wenn ich den erstgeschriebenen Quelltext verwende..


Tranx - Sa 13.04.13 21:33

Also, bei mir funktioniert das auch bei keinem offenen Fenster:

Die Timerroutine sieht bei mir so aus:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure TForm1.tmr1Timer(Sender: TObject);
begin
  lbl1.Caption := FormatDateTime('hh:nn:ss',Now);
  Tmr1.Enabled := FALSE;
  Tmr1.Enabled := TRUE;
  Application.Restore;
end;


Ich habe der Einfachkeit halber die Zeitausgabe auf einen Label gesetzt. Der Timer wird auch aufgerufen, wenn das Fenster minimiert ist.


IhopeonlyReader - Sa 13.04.13 21:45

ich habe herausgefunden, da ich mein Programm mit:

Delphi-Quelltext
1:
2:
hwndOwner := GetWindow(Handle, GW_OWNER);   
ShowWindowAsync(hwndOwner, SW_HIDE);

in der Taskleiste verstecke, funktioniert Application.Restore; nicht!
wenn ich mein Programm in der Taskleiste anzeige, so funktioniert es mit Application.Restore;

gibt es eine Möglichkeit, die beides beinhaltet?


Tranx - Sa 13.04.13 22:23

Das gilt bei mir genauso. Sobald das Programm nicht mehr in der Taskleiste auftaucht, ist die Möglichkeit, es dauerhaft anzuzeigen, nicht mehr gegeben. Möglicherweise liegt das an der unterschiedlichen Behandlung des Programms durch Windows, vielleicht wird der Timer abgeschaltet.


IhopeonlyReader - Sa 13.04.13 22:31

user profile iconTranx hat folgendes geschrieben Zum zitierten Posting springen:
vielleicht wird der Timer abgeschaltet.

Nein! Denn die Uhrzeit ist ja weiterhin "upToDate" oder besser uptoTime :D


Tranx - Sa 13.04.13 22:47

Ich habe es mal getestet.

Wenn ich eine OnHide-Prozedur wie folgt schreibe, dann funktioniert es auch mit dem Darstellen, wenn Du das Symbol in der Taskleiste deaktivierst:


Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.FormHide(Sender: TObject);
begin
  tmr1.Enabled := TRUE; // Timer aktivieren
end;


IhopeonlyReader - So 14.04.13 13:39

bei mir klappt es leider nicht...


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:
procedure TForm1.FormCreate(Sender: TObject);
var hwndOwner: HWnd;
begin
Autosize := True;
Left := 650;
Top := 250;
Label1.Caption := TimetoStr(Now);
hwndOwner := GetWindow(Handle, GW_OWNER);   
ShowWindowAsync(hwndOwner, SW_Hide);    
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if GetASyncKeyState( Ord('C'))<0 then application.terminate;

Label1.Caption := TimetoStr(Now)+' ';   // Uhrzeit anzeigen
Application.Restore;

if (WindowState=wsMinimized) then
  begin
  sleep(10);
  WindowState := wsNormal;
  end;
end;

procedure TForm1.FormHide(Sender: TObject);
begin
Timer1.Enabled := True;
end;


Tranx - So 14.04.13 17:24

Mein Test ergab, es geht nicht, wenn meine Timer-Prozedur wie folgt aussieht:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  if GetASyncKeyState( Ord('C'))<0 then application.terminate;
  lbl1.Caption := FormatDateTime('hh:nn:ss',Now);
  Tmr1.Enabled := FALSE;
  Tmr1.Enabled := true;
  //Application.BringToFront;
  Application.Restore;


allerdings funktioniert es mit nicht ausgeblendetem Application.BringToFront. Die Uhr wird selbst dann NICHT ganz nach vorne gebracht, aber ohne das Bringtofront geht es nicht.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  if GetASyncKeyState( Ord('C'))<0 then application.terminate;
  lbl1.Caption := FormatDateTime('hh:nn:ss',Now);
  Tmr1.Enabled := FALSE;
  Tmr1.Enabled := true;
  Application.BringToFront;
  Application.Restore;


P.S.: Die Abfrage nach Windowstate = wsMinimized brauche ich nicht.


IhopeonlyReader - So 14.04.13 21:17

bei mir klappt es immer noch nicht (win+M klappt, aber Win+D nicht)
dein

Delphi-Quelltext
1:
2:
Tmr1.Enabled := FALSE;  
Tmr1.Enabled := true;

lasse ich draußen..
aber meine TimerProcedure sieht dann so aus:

Delphi-Quelltext
1:
2:
3:
4:
if GetASyncKeyState( Ord('C'))<0 then application.terminate;   
Label1.Caption := TimetoStr(Now)+' ';   // Uhrzeit anzeigen
Application.BringToFront;
Application.Restore;

zusätzlich habe ich noch

Delphi-Quelltext
1:
2:
3:
4:
procedure TForm1.FormHide(Sender: TObject);
begin
Timer1.Enabled := True;
end;


dennoch klappt Nur Win+M nicht aber Win+D .. hast du deins auch mit Win+D ("Desktop anzeigen") ausprobiert?


Tranx - Mo 15.04.13 04:35

Also bei mir funktionieete es bei beiden, jedoch habe ich heute komischerweise gegenüber Gestern (Neustart?) den Effekt, dass nun das Programm nun wirklich im Vordergund ist und damit alle Kontrolle hat. Das ist sehr störend. Daher kann ich jetzt wenig weiter helfen.

Vielleicht weiß ja jemand Bescheid, der sich mit den Abläufen bei den Windows-Befehlen besser auskennt.


IhopeonlyReader - Mo 15.04.13 16:06

Mhh dein Code fängt nur Win+M ab / setztz sich danach wieder richtig :(
Bei Win+R und über Taskmanager minimieren wird sie nicht wieder Sichtbar..
falls es durch den taskmanager minimiert wurde, kann ich es mit WindowState := wsNormal; wiederholen


Sinspin - Di 16.04.13 14:57

Ich verwende fsStayOnTop und verstecken des TaskButtons und bin damit sehr zufrieden. Es geht so wie ich es haben will. Bei Vollbildanwendungen ist das Programmfenster schön unsichtbar. Und ich habe keine Probleme mit dem Focus in anderen Anwendungen. Mit aktivem Alphablending könnte ich sogar noch lesen was drunter steht, aber das nimmt irgendwie ganz schön viel CPU.


IhopeonlyReader - Di 16.04.13 16:12

naja StayonTop will ich vermeiden, da ich es ja nur auf dem Desktop sehen will.. es soll sozusagen IMMER das unterste der sichtbarem Fenster sein, gibt es kein anderes sichtbares fenster, ich es halt vorne^^.


IhopeonlyReader - Di 16.04.13 17:00

user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
naja StayonTop will ich vermeiden, da ich es ja nur auf dem Desktop sehen will.. es soll sozusagen IMMER das unterste der sichtbarem Fenster sein, gibt es kein anderes sichtbares fenster, ich es halt vorne^^.


Edit: Aber es wäre doch möglich, wenn KEIN fenster den Focus hat, fsstayontop "anzumachen"... dann wäre es sofort sichtbar oder? und wenn ein anderes fenster sichtbar wird, das fsstayontop wieder rausnehmen.. sichtbar ist es dann ja eigentlich noch, aber wird von dem anderen fenster überdeckt.. richtig?


IhopeonlyReader - So 21.04.13 15:15

- push-

Kann man eine Anwendung als "Gadget" behandeln?


IhopeonlyReader - Di 23.04.13 16:18

- push -


IhopeonlyReader - Fr 03.05.13 21:23

- push -


Gerd Kayser - Sa 04.05.13 05:13

user profile iconIhopeonlyReader hat folgendes geschrieben Zum zitierten Posting springen:
Kann man eine Anwendung als "Gadget" behandeln?

Schau Dir das hier mal an: http://www.delphipraxis.net/939191-post.html
Vielleicht hilft Dir das weiter.