////////////////////////////////////////////////////////////////////////////////
// CM2FormManager.pas
// ------------
// This unit contains the form manager used in CoolMon 2.
//
// Last Edit: Feb, 24th 2005
// Certified: NA
//
// This unit is coded in : Delphi 7
//
// Unit is copyright (c) 2003 - 2005, The CoolMon Project
////////////////////////////////////////////////////////////////////////////////
// Changes to unit
//
// 240205 - Added ReInitWindowLocation_All
////////////////////////////////////////////////////////////////////////////////
{$D+}
unit CM2FormManager;

interface

Uses Forms, Graphics, CM2FormUnit, extctrls, windows, SysUtils;

Type
 PCM2Form = ^TCM2Form;
 TCM2FormMgr = Class;
 PCM2FormMgr = ^TCM2FormMgr;
 TCM2FormMgr = Class(TObject)
 private
  fForms: Array of TCM2Form;
  ShowDesktopTimer: TTimer;
  LastFrontWindow: String;
  FPreventShowDesktop: Boolean;
  function GetCount: Integer;
  function GetForm(Index: Integer): TCM2Form;
  procedure SetForm(Index: Integer; const Value: TCM2Form);
  function GetPForm(Index: Integer): PCM2Form;
  procedure SetPreventShowDesktop(const Value: Boolean);
  procedure OnShowDesktop(Sender: TObject);
 public
  Constructor Create;
  Destructor Destroy; override;
  Procedure Delete(Index: Integer);
  Function DeleteFormByName(Name: String): Boolean;
  Function Add: Integer;
  Function AddP: PCM2Form;
  Property Count: Integer read GetCount;
  Property Form[Index: Integer]: TCM2Form read GetForm write SetForm; default;
  Property PForm[Index: Integer]: PCM2Form Read GetPForm;
  Function GetFormByName(Name: String; Var CM2Form: PCM2Form): boolean;
  Property PreventShowDesktop: Boolean read FPreventShowDesktop write SetPreventShowDesktop;
  Function ReturnSelf: PCM2FormMgr;
  Procedure ReInitWindowPosition_All;
  Function IsCM2Handle(Handle: THandle): Boolean;
  Procedure UpdatePositions;
 end;

implementation

uses
  Dialogs;

{ TCM2FormMgr }

function TCM2FormMgr.Add: Integer;
Var
 Sel: Integer;
begin
 Sel := Length(fForms);
 SetLength(fForms, Length(fForms) + 1);
 Application.CreateForm(TCM2Form, fForms[Sel]);
 fForms[Sel].MgrOwner := Self;
 fForms[Sel].Show;
 Result := Sel;
end;

function TCM2FormMgr.AddP: PCM2Form;
Var
 Sel: Integer;
begin
 Sel := Length(fForms);
 SetLength(fForms, Length(fForms) + 1);
 Application.CreateForm(TCM2Form, fForms[Sel]);
 fForms[Sel].MgrOwner := Self;
 fForms[Sel].Show;
 Result := Addr(fForms[Sel]);
end;

constructor TCM2FormMgr.Create;
begin
 ShowDesktopTimer := TTimer.Create(nil);
 ShowDesktopTimer.Interval := 50;
 ShowDesktopTimer.OnTimer := OnShowDesktop;
 ShowDesktopTimer.Enabled := true; // Default enabled
end;

procedure TCM2FormMgr.Delete(Index: Integer);
Var
 Last: Integer;
begin
 Last := Length(fForms) - 1;
 fforms[Index].Free;
 fforms[Index] := fforms[Last];
 SetLength(fForms, Length(fForms) - 1);
end;

function TCM2FormMgr.DeleteFormByName(Name: String): Boolean;
Var
 Sel, I: Integer;
begin
 Result := True;
 Sel := -1;
 For I := 0 to Length(fForms) - 1 do begin
  If uppercase(Name) = uppercase(fForms[I].Name) Then Sel := I;
 end;
 If Sel = -1 then begin
  Result := False;
  exit;
 end;
 Delete(Sel);
end;

destructor TCM2FormMgr.Destroy;
Var
 I: Integer;
begin
  ShowDesktopTimer.Enabled := False;
  FreeAndNil(ShowDesktopTimer);
  For I := 0 to length(fForms) - 1 do Delete(0);
  inherited;
end;

function TCM2FormMgr.GetCount: Integer;
begin
 Result := Length(fForms);
end;

function TCM2FormMgr.GetForm(Index: Integer): TCM2Form;
begin
 Result := Nil;
 If (index < 0) or (Index >= Length(fForms)) then exit;
 Result := fForms[Index];
end;

function TCM2FormMgr.GetFormByName(Name: String;
  var CM2Form: PCM2Form): boolean;
Var
 I: Integer;
begin
 Result := False;
 For I := 0 to SElf.Count-1 do begin
  If Name = Self.fForms[I].Name Then begin
   Result := True;
   CM2Form := Self.PForm[I];
   Exit;
  End;
 End;
end;

function TCM2FormMgr.GetPForm(Index: Integer): PCM2Form;
begin
 Result := Nil;
 If (index < 0) or (Index >= Length(fForms)) then exit;
 Result := Addr(fForms[Index]);
end;

function TCM2FormMgr.IsCM2Handle(Handle: THandle): Boolean;
Var
 I: Integer;
begin
 Result := false;
 For I := 0 to length(fForms) - 1 do begin
  If Handle = fForms[I].Handle Then Result := true;
 end;
end;

procedure TCM2FormMgr.OnShowDesktop(Sender: TObject);
Var
 aHandle: THandle;
 strBuff: String;
 P: PChar;
 I: Integer;
begin
 aHandle := GetForegroundwindow;
 SetLength(strBuff, 1024);
 P := pchar(strBuff);
 GetClassName(aHandle, P, 1024);
 If (p = 'WorkerW') then begin
  // Desktop is showing
  For I := 0 to count - 1 do begin
   If GetPForm(i)^.PinToDesktop then begin
    If GetPForm(i)^.Visible Then SetWindowPos(GetPForm(i)^.Handle, HWND_TOPMOST, 0,0,0,0, SWP_NOCHANGE);
   end;
  end;
 end
  else
 begin
  // If the current foreground window isn't WorkerW but if it was the last time we checked
  // then we need to reinstall all windows (CM2 Forms) to their original design
  If (LastFrontWindow = 'WorkerW') then begin
   // Ensure that the current window isn't one of CM2 own
   If (p = 'TCM2Form') or (p = 'ProgMan') then begin
    Application.ProcessMessages;
    For I := 0 to count - 1 do begin
     If GetPForm(i)^.PinToDesktop then begin
      If GetPForm(i)^.Visible Then SetWindowPos(GetPForm(i)^.Handle, HWND_TOPMOST, 0,0,0,0, SWP_NOCHANGE);
     end;
    end;
   end
    else
   begin
    For I := 0 to count - 1 do begin
     Self.GetPForm(I)^.CheckforWM;
    end;
   end;
  end;
 end;
 LastFrontWindow := P;
end;

procedure TCM2FormMgr.ReInitWindowPosition_All;
Var
 I: Integer;
begin
 For I := 0 to count - 1 do begin
  fForms[I].ReInitWindowPosition;
 end;
end;

function TCM2FormMgr.ReturnSelf: PCM2FormMgr;
begin
 Result := addr(self);
end;

procedure TCM2FormMgr.SetForm(Index: Integer; const Value: TCM2Form);
begin
 If (index < 0) or (Index >= Length(fForms)) then exit;
 fForms[Index] := Value;
end;

procedure TCM2FormMgr.SetPreventShowDesktop(const Value: Boolean);
begin
 fPreventShowDesktop := Value;
 If fPreventShowDesktop then ShowDesktopTimer.enabled := True
  else ShowDesktopTimer.enabled := False;
end;

procedure TCM2FormMgr.UpdatePositions;
Var
 I: Integer;
begin
 For I := 0 to Count - 1 do begin
  If Form[I].Right > -1 then Form[I].Right := Form[I].Right;
  If Form[I].Bottom > -1 Then Form[I].Bottom := Form[I].Bottom;
  Form[I].Update;
 end;
end;

end.
