AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

"Flackern" durch SetWindowRgn?

Ein Thema von JayBee · begonnen am 28. Jul 2006 · letzter Beitrag vom 28. Jul 2006
Antwort Antwort
Seite 1 von 2  1 2      
JayBee

Registriert seit: 20. Jul 2006
21 Beiträge
 
Delphi 5 Standard
 
#1

"Flackern" durch SetWindowRgn?

  Alt 28. Jul 2006, 00:44
Hallo ihrs da,

ich habe ein Problem mit einer selbstgeschriebenen "Binäruhr".
Diese Zeigt in Form von Kreisen die für 1, 2, 4,... stehen die aktuelle Uhrzeit an.
Der Code ist (warscheinlich) sehr Umständlich, aber mir ist nichts besseres eingefallen.

Über einen Timer wird jede Sekunde die Uhrzeit abgefragt und in drei Variablen gespeichert (h, m und s)
Danach wird für jeden zu erscheinenden Punkt über eine if-Abfrage ein Region kreiert und zu guter letzt per CombineRgn und SetWindowRgn die Form auf die Punktwe zurechtgestuzt.
Allerdings habe ich das Problem, das nach einiger Zeit (manchmal 20 Sekunden, manchmal 2 Minuten) mein Bildschirm im Sekundentakt anfängt zu "flackern" (Der desktop erschein und alle fenster werden neu geladen). Für abhilfe wäre ich sehr dankbar, da dieses geflacker doch arg stört, und ich auch gerne mal wissen würde woran es liegt.

mFg
JayBee


PS: Hier noch der Quellcode
Code:
procedure TForm1.FormCreate(Sender: TObject);
begin
 Form1.Top := 300;
 Form1.Width := 169;
 Form1.Height := 100;
 Form1.Left := 1111;
 Form1.Timer1Timer(self); // Direkt nach dem Start das Timer-Event aufrufen um nicht für kurze Zeit die komplette Form zu zeigen
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
 t: String;
 h, m, s: Integer;
 s1, s2, s4, s8, s16, s32, m1, m2, m4, m8, m16, m32, h1, h2, h4, h8, h16, NewRgn: HRGN;
begin
 DateTimeToString(t, 'h', Now);
 h := StrToInt(t);
 DateTimeToString(t, 'n', Now);
 m := StrToInt(t);
 DateTimeToString(t, 's', Now);
 s := StrToInt(t);

 NewRgn := CreateRectRgn(0,0,0,0);
 if (s div 32 >= 1) then begin
  s32 := CreateEllipticRgn(5, 60, 25, 80);
  s := s-32;
 end else
  s32 := CreateEllipticRgn(0, 0, 0, 0);
 if (s div 16 >= 1) then begin
  s16 := CreateEllipticRgn(30, 60, 50, 80);
  s := s-16;
 end else
  s16 := CreateEllipticRgn(0, 0, 0, 0);
 if (s div 8 >= 1) then begin
  s8 := CreateEllipticRgn(55, 60, 75, 80);
  s := s-8;
 end else
  s8 := CreateEllipticRgn(0, 0, 0, 0);
 if (s div 4 >= 1) then begin
  s4 := CreateEllipticRgn(80, 60, 100, 80);
  s := s-4;
 end else
  s4 := CreateEllipticRgn(0, 0, 0, 0);
 if (s div 2 >= 1) then begin
  s2 := CreateEllipticRgn(105, 60, 125, 80);
  s := s-2;
 end else
  s2 := CreateEllipticRgn(0, 0, 0, 0);
 if (s div 1 >= 1) then begin
  s1 := CreateEllipticRgn(130, 60, 150, 80);
 end else
  s1 := CreateEllipticRgn(0, 0, 0, 0);

 CombineRgn(NewRgn, s32, s16, RGN_OR);
 CombineRgn(NewRgn, s8, NewRgn, RGN_OR);
 CombineRgn(NewRgn, s4, NewRgn, RGN_OR);
 CombineRgn(NewRgn, s2, NewRgn, RGN_OR);
 CombineRgn(NewRgn, s1, NewRgn, RGN_OR);

 if (m div 32 >= 1) then begin
  m32 := CreateEllipticRgn(5, 35, 25, 55);
  m := m-32;
 end else
  m32 := CreateEllipticRgn(0, 0, 0, 0);
 if (m div 16 >= 1) then begin
  m16 := CreateEllipticRgn(30, 35, 50, 55);
  m := m-16;
 end else
  m16 := CreateEllipticRgn(0, 0, 0, 0);
 if (m div 8 >= 1) then begin
  m8 := CreateEllipticRgn(55, 35, 75, 55);
  m := m-8;
 end else
  m8 := CreateEllipticRgn(0, 0, 0, 0);
 if (m div 4 >= 1) then begin
  m4 := CreateEllipticRgn(80, 35, 100, 55);
  m := m-4;
 end else
  m4 := CreateEllipticRgn(0, 0, 0, 0);
 if (m div 2 >= 1) then begin
  m2 := CreateEllipticRgn(105, 35, 125, 55);
  m := m-2;
 end else
  m2 := CreateEllipticRgn(0, 0, 0, 0);
 if (m div 1 >= 1) then begin
  m1 := CreateEllipticRgn(130, 35, 150, 55);
 end else
  m1 := CreateEllipticRgn(0, 0, 0, 0);

 CombineRgn(NewRgn, m32, NewRgn, RGN_OR);
 CombineRgn(NewRgn, m16, NewRgn, RGN_OR);
 CombineRgn(NewRgn, m8, NewRgn, RGN_OR);
 CombineRgn(NewRgn, m4, NewRgn, RGN_OR);
 CombineRgn(NewRgn, m2, NewRgn, RGN_OR);
 CombineRgn(NewRgn, m1, NewRgn, RGN_OR);

 if (h div 16 >= 1) then begin
  h16 := CreateEllipticRgn(30, 10, 50, 30);
  h := h-16;
 end else
  h16 := CreateEllipticRgn(0, 0, 0, 0);
 if (h div 8 >= 1) then begin
  h8 := CreateEllipticRgn(55, 10, 75, 30);
  h := h-8;
 end else
  h8 := CreateEllipticRgn(0, 0, 0, 0);
 if (h div 4 >= 1) then begin
  h4 := CreateEllipticRgn(80, 10, 100, 30);
  h := h-4;
 end else
  h4 := CreateEllipticRgn(0, 0, 0, 0);
 if (h div 2 >= 1) then begin
  h2 := CreateEllipticRgn(105, 10, 125, 30);
  h := h-2;
 end else
  h2 := CreateEllipticRgn(0, 0, 0, 0);
 if (h div 1 >= 1) then begin
  h1 := CreateEllipticRgn(130, 10, 150, 30);
 end else
  h1 := CreateEllipticRgn(0, 0, 0, 0);

 CombineRgn(NewRgn, h16, NewRgn, RGN_OR);
 CombineRgn(NewRgn, h8, NewRgn, RGN_OR);
 CombineRgn(NewRgn, h4, NewRgn, RGN_OR);
 CombineRgn(NewRgn, h2, NewRgn, RGN_OR);
 CombineRgn(NewRgn, h1, NewRgn, RGN_OR);

 SetWindowRgn(Handle, NewRgn, true);
 SetWindowPos(Handle, HWND_TOPMOST, Left,Top, Width, Height, SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
 ShowWindow(Application.Handle, SW_Hide);
end;
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#2

Re: "Flackern" durch SetWindowRgn?

  Alt 28. Jul 2006, 01:17
Warum arbeitest du da mit Regions? Zeichen doch einfach Kreise. Oder nimm Images, die du entsprechend sichtbar machst.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
JayBee

Registriert seit: 20. Jul 2006
21 Beiträge
 
Delphi 5 Standard
 
#3

Re: "Flackern" durch SetWindowRgn?

  Alt 28. Jul 2006, 01:21
Zitat von Luckie:
Warum arbeitest du da mit Regions? Zeichen doch einfach Kreise. Oder nimm Images, die du entsprechend sichtbar machst.
Wie schon gesagt ist mir zum einen grade nichts besseres eingefallen und zum anderen habe ich noch keine (funktionierende) Funktion gefunden, um in Delphi 5 die Form unsichtbar zu machen, aber einzelne Komponenten (bzw. Kreise) sichtbar zu lassen.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: "Flackern" durch SetWindowRgn?

  Alt 28. Jul 2006, 01:24
Hm stimmt, das könnte ein Problem sein. Aber so wie es jetzt ist, würde es mir auch nicht gefallen. Vor grauem Hintergrund sieht man nämlich nichts. Und da die meisten fenster grau sind, wirst du immer das Problem haben, dass man bei machen Konstellationen nichst sieht. Deswegen würde ich die Form nicht unsichtbar machen, sondern höchstens transparent und auf dem Form-Hintergrund zeichnen.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
JayBee

Registriert seit: 20. Jul 2006
21 Beiträge
 
Delphi 5 Standard
 
#5

Re: "Flackern" durch SetWindowRgn?

  Alt 28. Jul 2006, 01:57
zZt ist als Form-Hintergrund-Farbe ein Babyblau eingestellt, was dann auch die Farbe der Kreise ist. Und Blau ist doch schon gut zu erkennen auf meiner grauen SideBar.
Und da es auch mehr ein Anwendung nur für mich ist, sollte die Farbe weniger ein Problem darstellen.
(Falls ich das ganze mal veröffentlichen sollte - danke für den Tipp

Habe jetzt mal noch bischen mit Canvas rumexperimentiert, aber wenn ich in die Form zeichne und sie transparent mache, sehe ich nichts von meinen schönen Kreisen, und wenn ich versuche, auf die SideBar direkt zu zeichnen, zeichnet er nur "dahinter" (Die Sidebar steht auf "Immer im Vordergrund" und "Andocken", also praktisch ähnlich wie die Taskleiste)
  Mit Zitat antworten Zitat
Benutzerbild von stoxx
stoxx

Registriert seit: 13. Aug 2003
1.111 Beiträge
 
#6

Re: "Flackern" durch SetWindowRgn?

  Alt 28. Jul 2006, 03:45
http://www.pjh2.de/delphi/units/index.php?l=de
Phantasie ist etwas, was sich manche Leute gar nicht vorstellen können.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#7

Re: "Flackern" durch SetWindowRgn?

  Alt 28. Jul 2006, 05:37
Zitat von stoxx:
http://www.pjh2.de/delphi/units/index.php?l=de
Es wäre eventuell ganz hilfreich noch ein paar Worte zu deinem Link zu schreiben, da nicht unbedigt gleich ersichtlich ist, was du meinst.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#8

Re: "Flackern" durch SetWindowRgn?

  Alt 28. Jul 2006, 09:09
Du musst die erstellten Regionen wieder freigeben (Delphi-Referenz durchsuchenCreateRectRgn Delphi-Referenz durchsuchenDeleteObject).

Das würde dann in etwas formatierter Version so ausschauen: (siehe Anhang)
Angehängte Dateien
Dateityp: zip bintime_862.zip (2,4 KB, 6x aufgerufen)
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
JayBee

Registriert seit: 20. Jul 2006
21 Beiträge
 
Delphi 5 Standard
 
#9

Re: "Flackern" durch SetWindowRgn?

  Alt 28. Jul 2006, 12:22
Höhöh... tjaja, die Sache mit dem Freigeben...
Hab deine Unit jetzt ca. ne halbe Stunde am laufen ohne flackern

Nur was mir jetzt auffällt ist, dass die Zeit nicht richtig Angezeigt wird
Wir haben auf meine Uhr hier 12:13, ich sehe in der ersten "Zeile" einen Punkt bei 8 und 2 (macht 10) und in der zweiten Zeile bei 8, 4 und 1 (13). Also stimmt irgendwas mit den Stunden nicht.

Wenn ich statt deines dt.wHour meine formatierung über den String nehme, funktioniert hingegen alles Richtig.

mFg

//Edit: Das wird wohl da dran liegen, das bei mir die Systemzeit nicht gleich der Windowszeit ist. Problem isoliert und gelöst: ich nehm einfach meine Routine zum setzen der Zeitvariablen

Danke an alle, die geholfen haben
  Mit Zitat antworten Zitat
Benutzerbild von turboPASCAL
turboPASCAL

Registriert seit: 8. Mai 2005
Ort: Sondershausen
4.274 Beiträge
 
Delphi 6 Personal
 
#10

Re: "Flackern" durch SetWindowRgn?

  Alt 28. Jul 2006, 14:34
Besser ist es wohl die Regionen nur einmal zu erstellen. die Gesammte If-Abfragerei und das Erstellen
der Regionen können drastisch vereinfacht werden.
Damit die Lesbarkeit des Binärsystems besser erhalten bleibt kann doch die Anzeige im "Auszustand"
eine Abgedunkelte Fläche darstellen.

Eine Neue und kürzere Version die auch das Darstellen auf dem Desktop (als Kindfenster) untersützt
könnte zb: so aussehen:

Delphi-Quellcode:
unit UMain;

interface

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

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    PopupMenu1: TPopupMenu;
    Beenden1: TMenuItem;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormDestroy(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure FormPaint(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Beenden1Click(Sender: TObject);
  private
    { Private-Deklarationen }
      dt: TSystemTime;
      WinRGN: HRGN;
      procedure CreateRegions;
      procedure DrawBinTime;
  public
    { Public-Deklarationen }
    procedure CreateParams(var Params: TCreateParams); override;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

const
  Radius = 5;
  XYStep = (Radius * 2) + 2;
  Digits = 6;

  SetToDesktop = TRUE;

procedure TForm1.CreateParams(var Params: TCreateParams);
begin
  inherited;
  if SetToDesktop then
  begin
    Params.Style := WS_POPUP;
    Params.ExStyle := WS_EX_NOACTIVATE;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  BorderStyle := bsNone;
  ShowHint := TRUE;

  Width := Digits * XYStep;
  Height := 3 * XYStep;

  Top := 10;
  Left := Screen.Width - Width - 10;

  WinRGN := CreateRectRGN(0, 0, 0, 0);

  CreateRegions;

  GetSystemTime(dt);

  SetWindowRgn(Handle, WinRGN, TRUE);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  //
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  DeleteObject(WinRGN);
  
  Action := caFree;
end;

procedure TForm1.CreateRegions;
var
  i, n, x , y: Integer;
  RGN : HRGN;
begin
  y := Radius;
  for n := 1 to 3 do
  begin
    x := clientwidth - Radius;
    for i := Digits downto 1 do
    begin
      RGN := CreateEllipticRgn(x - Radius,
                               y - Radius,
                               x + Radius + 1,
                               y + Radius + 1);
      CombineRgn(WinRgn, RGN, WinRgn, RGN_OR);
      DeleteObject(RGN);
      dec(x, XYStep);
    end;
    inc(y, XYStep);
  end;
end;

function IntToBin(Int, Digits: Integer): String;
var
  i : Integer;
begin
  Result := '';
  for i := Digits - 1 downto 0 do
    Result := Result + IntToStr((Int shr i) and 1);
end;

procedure TForm1.DrawBinTime;
var
  i, n, x , y: Integer;
  s: string;
begin
  y := Radius;
  for n := 1 to 3 do
  begin
    case n of
      1: s := IntToBin(dt.wHour, Digits);
      2: s := IntToBin(dt.wMinute, Digits);
      3: s := IntToBin(dt.wSecond, Digits);
    end;

    x := clientwidth - Radius;
    for i := length(s) downto 1 do
    begin
      if s[i] <> '0then
      begin
        Canvas.Pen.Color := RGB(128, 0, 0);
        Canvas.Brush.Color := RGB(255, 0, 0);
      end else
      begin
        Canvas.Brush.Color := RGB(64, 0, 0);
        Canvas.Pen.Color := RGB(32, 0, 0);
      end;

      Canvas.Ellipse(x - Radius, y - Radius, x + Radius, y + Radius);

      dec(x, XYStep);
    end;
    inc(y, XYStep);
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
  // inlinefunction
  function ItS(V: integer): String; begin str(V:2, Result); end;
  //
begin
  GetLocalTime(dt);
  Hint := ItS(dt.wHour) + ':' + ItS(dt.wMinute) + ':' + ItS(dt.wSecond);

  DrawBinTime;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  DrawBinTime;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  if SetToDesktop then
  begin
    ShowWindow(Application.Handle, SW_Hide);
    SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);

    Windows.SetParent(Handle, GetDesktopWindow);
    SetWindowPos(Handle, HWND_BOTTOM, 0, 0, 0, 0,
      SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
  end else
    SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0,
      SWP_NOACTIVATE or SWP_NOMOVE or SWP_NOSIZE);
end;

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

end.
Angehängte Dateien
Dateityp: zip bintimes.sourcecode_446.zip (3,8 KB, 13x aufgerufen)
Matti
Meine Software-Projekte - Homepage - Grüße vom Rüsselmops -Mops Mopser
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:40 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz