Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Systemzeit Wechsel WM_TIMECHANGE in TComponent (https://www.delphipraxis.net/124742-systemzeit-wechsel-wm_timechange-tcomponent.html)

backdraft 24. Nov 2008 15:23


Systemzeit Wechsel WM_TIMECHANGE in TComponent
 
Hallo zusammen,

ich habe eine Komponente entwickelt, und möchte gerne mitbekommen, wenn die Systemzeit umgestellt wird.
Die Nachricht WM_TIMECHANGE wird ja nur an alle Komponenten geschickt, die ein Fenster haben.

Gibt es eine andere Möglichkeit, als dass ich mir ein unsichtbares Fenster erzeuge und in dem die Nachricht abfange?
Hab ich keine Chance an die Nachricht anders ranzukommen?

mfg
Oliver

MSSSSM 24. Nov 2008 19:13

Re: Systemzeit Wechsel WM_TIMECHANGE in TComponent
 
Nicht dass ich wüsste.
Was ist denn so schlimm, ein unsichtbares Fenster zu erzeugen?

himitsu 25. Nov 2008 11:33

Re: Systemzeit Wechsel WM_TIMECHANGE in TComponent
 
Dafür gibt es sogenannte MessageOnlyWindows.

z.B.: http://www.delphipraxis.net/internal...t=messageonly*


Im Grunde sind es aber auch "nur" unsichtbare Fenster.

PS: Application/TApplication besitzt soein "unsichtbares" Fenster, damit es die Nachichtenschleife abarbeiten kann ... und wenn du "Application" in deinem Programm nutzt, dann kannst du dich auch in dessen Nachrichten Schleife reinhängen.

Union 25. Nov 2008 12:13

Re: Systemzeit Wechsel WM_TIMECHANGE in TComponent
 
Du solltest Dir für Deine Controls eine Verwaltungsklasse schreiben, die sich in die WndProc einklinkt. In dieser sollte eine Objectlist / TList sein, in die Du in dem gemeinsamen Vorfahren Deiner Controls im constructor jeweils self einträgst. Dann kannst Du beim eintreffen einer für Dich interessanten Nachricht diese an alle verwalteten Objekte weitermelden oder sonstwas mit ihnen machen.

backdraft 25. Nov 2008 21:03

Re: Systemzeit Wechsel WM_TIMECHANGE in TComponent
 
Zitat:

Zitat von Union
Du solltest Dir für Deine Controls eine Verwaltungsklasse schreiben, die sich in die WndProc einklinkt. In dieser sollte eine Objectlist / TList sein, in die Du in dem gemeinsamen Vorfahren Deiner Controls im constructor jeweils self einträgst. Dann kannst Du beim eintreffen einer für Dich interessanten Nachricht diese an alle verwalteten Objekte weitermelden oder sonstwas mit ihnen machen.

Hallo,
das ist eine gute Idee. Ich habe halt mehrere *nicht visuelle* Fenster in diversen Komponenten, die mit sowas arbeiten. Für das WM_TIMECHANGE wollte ich das jetzt nicht auch wieder so machen.

Ich glaube ich mache mir so eine Verwaltungsklasse. Diese muss dann aber Global sein, oder?

Union 26. Nov 2008 08:37

Re: Systemzeit Wechsel WM_TIMECHANGE in TComponent
 
Die Verwaltungsklasse muß für Deine Komponenten sichtbar sein. Hier ein Beispiel für die Verwaltungsklasse, das ich gestern erstellt habe:
Delphi-Quellcode:
unit uAppMessages;

interface
   uses classes, Windows, Messages;

   type

   IComponentControllerTimeComponent = interface
   ['{B4B1A347-0D72-433D-BF73-7DA96CBEB9EA}']
      procedure TimeChanged;
   end;

   TComponentController = class
   private
      FList : TList;
      procedure TimeChanged;
   protected
      FWindow : HWND;
      procedure MainWndProc(var Message: TMessage);
      procedure WndProc(var Message: TMessage); virtual;
   public
      constructor Create;
      destructor Destroy; override;
      procedure AddObject(AObject : TObject); virtual;
      procedure RemoveObject(AObject : TObject); virtual;
   end;

function ComponentController : TComponentController;

implementation

uses Forms, StdCtrls, SysUtils;

var
   FComponentController : TComponentController;

function ComponentController : TComponentController;
begin
   if FComponentController = nil then
      FComponentController := TComponentController.Create;
   result := FComponentController;
end;

{ TComponentController }

procedure TComponentController.AddObject(AObject: TObject);
begin
   if FList.IndexOf(AObject) = -1 then
   begin
      if FList.Count = 0 then
         FWindow := Forms.AllocateHWnd(MainWndProc);
      FList.Add(AObject);
   end;
end;

constructor TComponentController.Create;
begin
   inherited Create;
   FList := TList.Create;
end;

destructor TComponentController.Destroy;
begin
  FList.Free;
  inherited;
end;

procedure TComponentController.MainWndProc(var Message: TMessage);
begin
  try
    WndProc(Message);
  except
    Application.HandleException(Self);
  end;
end;

procedure TComponentController.RemoveObject(AObject: TObject);
begin
   FList.Remove(Pointer(AObject));
   if FList.Count = 0 then
      Forms.DeallocateHWnd(FWindow);
end;

procedure TComponentController.TimeChanged;
var
   i : integer;
begin
   for i := 0 to FList.Count-1 do
   begin
      // Besser über ein Interface und Supports realisieren
      // nur als Demo für die Funktionalität
      if TObject(Flist[i]).ClassNameIs('TEdit') then
         TEdit(Flist[i]).Text := TimeToStr(Now);
   end;
end;

procedure TComponentController.WndProc(var Message: TMessage);
begin
  if Message.Msg = WM_TIMECHANGE then
  begin
    TimeChanged;
    Message.Result := 0;
    Exit;
  end;
  with Message do Result := DefWindowProc(FWindow, Msg, wParam, lParam);
end;

initialization
finalization
   FComponentController.Free;
   FComponentController := nil;

end.
Und so kann man es benutzen, bei eigenen Komponenten muß das im constructor / destructor passieren:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
   ComponentController.AddObject(Edit1);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
   ComponentController.RemoveObject(Edit1);
end;

backdraft 2. Dez 2008 20:07

Re: Systemzeit Wechsel WM_TIMECHANGE in TComponent
 
Hat super geklappt, vielen Dank.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:35 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