Title: Easy way to replace the system clock
Question: Several ways have been presented on how you can show strings in the system tray(see article 1963 for example). This example will demonstrate how you in a simple manner can replace the system clock with a TStatictext component.
Answer:
This technique is a simple one, and can be used for many other purposes than replacing the system clock. The advantage is, that you still have full control over your component even though its in another window.
Drop a TButton and a TStatictext on to your form and assign the events properly.
{ Example-code BEGIN }
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
StaticText1: TStaticText;
procedure Button1Click(Sender: TObject);
procedure StaticText1Click(Sender: TObject);
procedure ReplaceSystemClock;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
ReplaceSystemClock;
end;
procedure TForm1.ReplaceSystemClock;
var
Rect: TRect; // We need this for calc'ing the size of the System Tray Window
TaskbarHwnd, TrayHwnd: HWND;
begin
// First we'll find the taskbar
TaskbarHwnd := FindWindow('Shell_TrayWnd',nil);
// Next the Tray Window
TrayHwnd := FindWindowEx(TaskbarHwnd,0,'TrayNotifyWnd',nil);
{ Now we need the Rect. of the Tray window so we can position the TStatictext
somewhat accurately }
GetWindowRect(TrayHwnd,Rect);
// Right Justify is recommended because the text will otherwise extend beyond the TrayWindow bounds
StaticText1.Alignment := taRightJustify;
// Change the borderstyle to single so we can see if its positioned properly
StaticText1.BorderStyle := sbsSingle;
// Reposition it so it covers the System Clock
StaticText1.Left := (Rect.Right - Rect.Left) - StaticText1.Width - 3;
StaticText1.Top := 2;
StaticText1.Font.Name := 'Tahoma';
// Disable this, or StaticText1 will move around when you change the text
StaticText1.AutoSize := FALSE;
// Now comes the interesting part: we shift the Statictext1's parent to the Traywindow
Windows.SetParent(StaticText1.Handle,TrayHwnd);
{ Even though Statictext1 changed owner, we can still manipulate it
like it were in our own form! Which is a great advantage. }
StaticText1.Caption := 'Test';
end;
procedure TForm1.StaticText1Click(Sender: TObject);
const
ClickTest: array[0..3] of string = ('this','is','a','test');
begin
{ Your events will work just as if they were on your form }
StaticText1.Caption := ClickTest[StaticText1.Tag];
if StaticText1.Tag StaticText1.Tag := StaticText1.Tag + 1
else StaticText1.Tag := 0;
end;
end.
{ Example-code END }