Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Probleme mit Bildschirmschonervorschau (https://www.delphipraxis.net/103569-probleme-mit-bildschirmschonervorschau.html)

Popov 29. Nov 2007 18:10

Re: Probleme mit Bildschirmschonervorschau
 
Zitat:

Zitat von Bornemaxx
@ Popov
Schade, ich gehe davon aus, dass die *.res ...

An der RES liegt es nicht. Die ist korrekt kompiliert und auch eingebunden.

Bornemaxx 29. Nov 2007 20:27

Re: Probleme mit Bildschirmschonervorschau
 
Liste der Anhänge anzeigen (Anzahl: 1)
Habe gerade noch mal schnell ein Test-Projekt erstellt. ( Ich weiß,es ist unsauber, aber für den Test reicht es.) Liegt komplett im Anhang. Habe es als *.exe compiliert und nach *.scr umbenannt und nach Windows\system32 kopiert. Dann Desktop->Eigenschaften->Bildschirmschoner. Dort wird in der Auswahlliste "Test-Bildschirmschoner" angezeigt. Es funktioniert auch, wenn man ohne die Datei "string1.res" compiliert und mit dem Resource-Hacker (z.B. hier: Resource-Hacker) die "string.res" importiert. Mit diesem Ding kann man auch den String Nummer 1 verändern und beim Beenden wieder compilieren. Das geht auch mit der bs_test.scr im Verzeichnis windows\system32.
Vielleicht kann ja auch mal jemand anderes die bs_test.scr testen, wäre interessant. Wie gesagt, ich nutze D5 und XP SP1.

Gruß Mirko

Bornemaxx 3. Dez 2007 20:53

Re: Probleme mit Bildschirmschonervorschau
 
Jetzt wird es komisch: Habe gerade die SCR-Datei einem Bekannten geschickt. Bei ihm wird auch nur der Dateiname angezeigt !!! Der Unterschied zu meinem System: Er benutzt XP Home und ich XP Professional !!!
Vielleicht findet sich ja noch jemand zum Testen.

Gruß Mirko

Delphi-Laie 25. Mai 2012 15:07

AW: Re: Eine Frage die nur die Glaskugel beantworten werden kann
 
Zitat:

Zitat von SirThornberry (Beitrag 703885)
meine Vermutung wäre das dein Programm in einer Schleife festhängt. Also das du ständig das Bild aktuallisierst und mit Application.Processmessages dafür sorgst das nachrichten verarbeitet werden. Dadurch das es in einer schleife geschieht kann das Programm jedoch nicht entladen werden. Das wäre meine Vermutung.

Diese Diskussion ist zwar schon einige Jahre alt, aber vor genau dem gleichen Problem stehe ich nun auch und finde keine Lösung.

Wenn man während der laufenden Bildschirmschonervorschauf auf "Testen" oder "Einstellungen" klickt, so müßte das Bildschirmschonerprogramm beendet und mit anderem Paremeter erneut gestartet werden.

Die Ereignisse "OnCloseQuery" und "OnClose" werden (in dieser Reihenfolge) aufgerufen, wenn man die BSS-Vorschau beenden möchte, also wird wohl der Beendenbefehl an das Programm gesendet. Das Beenden der (im Vorschaumodus eben nicht mit Tastendruck oder Mausklick beendbaren) Bildschirmschonervorschau mutiert damit aber leider im besten Falle zur Geduldsprobe oder ist sogar völlig unmöglich.

Der Timer wird zum Start nur einmal aufgerufen, und die Schonerschleife soll eigentlich für die Vorschaud und das eigentliche Schonen gleichermaßen allgemeingültig sein. Hier der Quelltext:

Delphi-Quellcode:
procedure TSaverForm.Timer1Timer(Sender: TObject);
begin
Timer1.Enabled:=false;
if copy(upperCase(paramstr(1)),1,2)<>'/C' then
  begin
    while not abbruch do
    begin
    Application.ProcessMessages;
 
    //eigentlicher Quellcode des BSS bzw. dessen Vorschau
 
    end
  end;
Application.Terminate //alternativ: SaverForm.Close
end;

procedure TSaverForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
abbruch:=true
end;
Akustische Ausgaben verrieten mir zudem, daß OnCloseQuery und OnClose viele Male abwechselnd aufgerufen werden - vermutlich wegen des Application.ProcessMessages.

Wie kann man eine solche Schleife schnell und sicher beenden? Ich probierte schon alles mögliche, unter anderem, daß Programm direkt in der Schleife zu beenden, OnClose statt OnCloseQuerey zu benutzen, beides gemeinsam, nichts hilft. Mit einem regelmäßigen Timer hingegen ist das Programm quälend langsam.

Im eigentlichen Schonermodus reagiert es hingegen sofort auf Eingaben und beendet sich sogleich.

Delphi-Laie 25. Mai 2012 18:39

AW: Re: Eine Frage die nur die Glaskugel beantworten werden kann
 
Des Rätsels Lösung findet sich hier.

Das dortige Projekt auf das wesentliche, das hier das Problem zu lösen demonstrieren soll, reduziert, sieht die Projektdatei so aus:
Delphi-Quellcode:
program Bildschirmschoner;

uses
  Forms,
  SysUtils,
  Windows,
  Graphics,
  Classes,
  scrn in 'scrn.pas' {screen};

{$E SCR}
{$R *.RES}

var DemoWnd:hwnd;
MyRect:TRect;
ScrWidth,ScrHeight:Integer;
MyCanvas:TCanvas;

begin
  Application.Initialize;

  if Copy(UpperCase(ParamStr(1)),1,2)='/P' then
    begin
    DemoWnd := StrToInt(UpperCase(ParamStr(2)));
    while not IsWindowVisible(DemoWnd) do Application.ProcessMessages;
    GetWindowRect(DemoWnd,MyRect);
    ScrWidth:=succ(MyRect.Right-MyRect.Left);
    ScrHeight:=succ(MyRect.Bottom-MyRect.Top);
    MyRect:=Rect(0,0,ScrWidth-1,ScrHeight-1);
    MyCanvas := TCanvas.Create;
    MyCanvas.Handle := GetDC(DemoWnd);

    while IsWindowVisible(DemoWnd) do
      begin
      MyCanvas.Pixels[random(ScrWidth),random(ScrHeight)]:=random(10000000);
      //Application.ProcessMessages
      end;
    MyCanvas.Free;
    Halt
    end;

  Application.CreateForm(Tscreen, screen);
  Application.Run;
end.
In der Hauptschleife werden zur Demonstration einfach farbige Pixel im Vorschaufenster ausgegeben (Farbrauschen). Das süffisante an dieser Lösung ist, daß diese Schleife sogar ohne Application.ProcessMessages auskommt und dennoch sofort beendet wird, wenn die Vorschau eines anderen Bildschirmschoners gewählt wird.

Für alle, die es interessiert...

Popov 25. Mai 2012 18:54

AW: Probleme mit Bildschirmschonervorschau
 
Das "Problem" ist, dass eigenes Überwachen der Tasten oder Maus eigentlich falsch ist. Denn aktuelle Windows Versionen verschicken eine Message die einem sagt, dass man bitte den Bildschirmschoner beenden soll. Man kann die Message ignorieren und selbst Tasten überwachen, ist aber kein Stand der Technik.

Delphi-Laie 25. Mai 2012 19:09

AW: Probleme mit Bildschirmschonervorschau
 
Ja, ich hatte gehofft, daß der Meister der Schoner sich zu Wort meldet, danke!

Ist es demnach nicht optimal, auf OnKeyDown/OnKeyPress und/oder OnMouseMove des bildschirmfüllenden und -schonenden Hauptformulares zu reagieren und in den entsprechenden Ereignisbehandlungsprozeduren das Beenden des Programmes entweder auszulösen oder wenigstens vorzubereiten?

himitsu 25. Mai 2012 19:23

AW: Probleme mit Bildschirmschonervorschau
 
Die Schleife im Timer war schon unschön, aber nun auch noch Halt?

Wie währe es mit OnIdle?

Delphi-Quellcode:
begin
  if AnsiStartsText('/P',ParamStr(1)) then //if Copy(UpperCase(ParamStr(1)),1,2)='/P' then
    begin
      DemoWnd := StrToInt(ParamStr(2));
      while IsWindow(DemoWnd) and not IsWindowVisible(DemoWnd) do // war 'ne Endlosschleife, falls es das Fenster nicht mehr gibt, oder es nie sichtbar wird
        Sleep(50);
      GetWindowRect(DemoWnd,MyRect);
      ScrWidth:=succ(MyRect.Right-MyRect.Left);
      ScrHeight:=succ(MyRect.Bottom-MyRect.Top);
      MyRect:=Rect(0,0,ScrWidth-1,ScrHeight-1);
      MyCanvas := TCanvas.Create;
      try
        MyCanvas.Handle := GetDC(DemoWnd);
        while IsWindowVisible(DemoWnd) do
          MyCanvas.Pixels[random(ScrWidth),random(ScrHeight)]:=random($FFFFFF+1);
      finally
        MyCanvas.Free;
      end;
    end
  else
    begin
      Application.Initialize;
      Application.CreateForm(TScreen, Screen);
      Application.Run;
    end;
end.

Delphi-Laie 26. Mai 2012 08:34

AW: Probleme mit Bildschirmschonervorschau
 
Zitat:

Zitat von himitsu (Beitrag 1168137)
Die Schleife im Timer war schon unschön, aber nun auch noch Halt?

Der Timer war doch nur ein 1-Schuß-Starttimer, um OnCreate zu verlassen. Halt kann man tatsächlich mit Deiner Lösung vermeiden (werde ich auch so tun, weil ich noch ein IniFile-Objekt instanziieren und entladen muß).

Mit Deinem
Delphi-Quellcode:
while IsWindow(DemoWnd) and not IsWindowVisible(DemoWnd) do // war 'ne Endlosschleife, falls es das Fenster nicht mehr gibt, oder es nie sichtbar wird
  Sleep(50);
setzt die Vorschau allerdings erst mit einer Verzögerung von etlichen Sekunden ein, auch dann, wenn man/ich das Sleep auf 0 herabsetzt/herabsetze. Das Fenster muß doch - eigentlich - auch immer sichtbar sein, denn mit /P wird doch nur gestartet, wenn man im Fenster "Eigenschaften von Anzeige" aktiv herummacht. Wenn man natürlich selber im Textfenster auf der Kommandozeile den BS-Schoner mit /P startet, also mit aller Gewalt einen Zustand erzeugt, der nicht vorgesehen ist, dann ist es wohl möglich.

Ergänzung: Es mußte wohl die Nachrichtenschleife geleert werden. Mit
Delphi-Quellcode:
while IsWindow(DemoWnd) and not IsWindowVisible(DemoWnd) do Application.ProcessMessages
startet die Vorschau augenblicklich.

Das Problem, aus einer Schleife (und bitte kein 1-ms-Timer) mit oder ohne Application.ProcessMessages ohne spürbaren Zeitverzug herauszukommen, hat sich für mich ohnehin seit gestern erledigt.

Popov 26. Mai 2012 10:34

AW: Probleme mit Bildschirmschonervorschau
 
@Delphi-Laie

Natürlich kannst du auch auf Tasten oder Maus reagieren, wird wohl genauso funktionieren, ich sag ja nur, dass Windows (ich weiß aber nicht seit wann) auch eine Message verschickt wenn der ScreenSaver läuft und eine Taste gedrückt oder Maus bewegt wurde. In dem Fall entscheidet Windows ob der ScreenSaver beendet werden soll. Allerdings ist die Auswertung nicht weniger kompliziert als wenn man es einfach selbst macht, denn laut der Beschreibung soll man bei a so reagieren, bei b so, bei c so usw.

Was den Code angeht den du nutzt, soll das ein NonVCL ScrennSaver sein?


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:14 Uhr.
Seite 3 von 4     123 4      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz