19
Jun 09

Delphi: Utils :: TChainedList

:: articles :: by Gilberto Saraiva

Folks,

For everybody thats use a lot Chained lists on your projects:

 Delphi |  copy code |? 
001
uses SysUtils;
002
 
003
type
004
  PPointer = ^Pointer;
005
 
006
  TChainedList = class
007
  private
008
    FFirst   : Pointer;
009
    FLast    : Pointer;
010
    FCurrent : Pointer;
011
    FCount   : Integer;
012
    function GetCurrent: PPointer;
013
  public
014
    constructor Create;
015
    destructor Destroy; override;
016
 
017
    function First : TChainedList;
018
    function Last  : TChainedList;
019
    function Prior : TChainedList;
020
    function Next  : TChainedList;
021
 
022
    function Add: TChainedList;
023
    function Remove: TChainedList; overload;
024
    function Remove(AChainedReleaser: Pointer): TChainedList; overload;
025
 
026
    property Current: PPointer read GetCurrent;
027
    property Count: Integer read FCount;
028
  end;
029
 
030
implementation
031
 
032
type
033
  PChainedItem = ^TChainedItem;
034
  TChainedItem = record
035
    Prior, Next: PChainedItem;
036
    Data: Pointer;
037
  end;
038
 
039
{ TChainedList }
040
 
041
constructor TChainedList.Create;
042
begin
043
  FCount := 0;
044
  FFirst := nil;
045
  FLast := nil;
046
  FCurrent := nil;
047
end;
048
 
049
destructor TChainedList.Destroy;
050
begin
051
  First;
052
  while Current <> nil do
053
    Remove;
054
 
055
  inherited;
056
end;
057
 
058
function TChainedList.GetCurrent: PPointer;
059
begin
060
  if FCurrent <> nil then
061
    Result := @PChainedItem(FCurrent).Data
062
  else
063
    Result := nil;
064
end;
065
 
066
function TChainedList.First: TChainedList;
067
begin
068
  FCurrent := FFirst;
069
  Result := Self;
070
end;
071
 
072
function TChainedList.Last: TChainedList;
073
begin
074
  FCurrent := FLast;
075
  Result := Self;
076
end;
077
 
078
function TChainedList.Prior: TChainedList;
079
begin
080
  if FCurrent <> nil then
081
    FCurrent := PChainedItem(FCurrent)^.Prior
082
  else
083
    FCurrent := nil;
084
  Result := Self;
085
end;
086
 
087
function TChainedList.Next: TChainedList;
088
begin
089
  if FCurrent <> nil then
090
    FCurrent := PChainedItem(FCurrent)^.Next
091
  else
092
    FCurrent := nil;
093
  Result := Self;
094
end;
095
 
096
function TChainedList.Add: TChainedList;
097
var
098
  pNew: PChainedItem;
099
begin
100
  New(pNew);
101
  pNew^.Prior := nil;
102
  pNew^.Next := nil;
103
  pNew^.Data := nil;
104
 
105
  if FFirst = nil then
106
  begin
107
    FFirst := pNew;
108
    FLast := pNew;
109
  end else
110
  begin
111
    pNew^.Prior := PChainedItem(FLast);
112
    PChainedItem(FLast)^.Next := pNew;
113
    FLast := pNew;
114
  end;
115
 
116
  FCurrent := FLast;
117
  Result := Self;
118
  Inc(FCount);
119
end;
120
 
121
function TChainedList.Remove: TChainedList;
122
var
123
  pCur: PChainedItem;
124
begin
125
  pCur := FCurrent;
126
  if pCur^.Data <> nil then
127
    raise Exception.Create('Current item memory leak detected.');
128
 
129
  if pCur^.Next <> nil then
130
    pCur^.Next^.Prior := pCur^.Prior;
131
 
132
  if pCur^.Prior <> nil then
133
    pCur^.Prior^.Next := pCur^.Next;
134
 
135
  if pCur = FFirst then
136
  begin
137
    FFirst := pCur^.Next;
138
    FCurrent := FFirst;
139
  end else if pCur = FLast then
140
  begin
141
    FLast := pCur^.Prior;
142
    FCurrent := FLast;
143
  end else
144
    FCurrent := pCur^.Next;
145
 
146
  Result := Self;
147
  Dispose(pCur);
148
  Dec(FCount);
149
end;
150
 
151
function TChainedList.Remove(AChainedReleaser: Pointer): TChainedList;
152
type
153
  TRelease = procedure(APointer: Pointer);
154
var
155
  PdrRelease: TRelease;
156
begin
157
  @PdrRelease := AChainedReleaser;
158
  PdrRelease(PChainedItem(FCurrent)^.Data);
159
  PChainedItem(FCurrent)^.Data := nil;
160
  Result := Remove;
161
end;

See how to use it here: Delphi: Chained List

Hugs!



01
Sep 08

Delphi: Utils :: ToolButtonScreenPos

:: articles :: by Gilberto Saraiva

Folks,

For everybody that needs the ToolButton position:

 Delphi |  copy code |? 
1
type
2
  TToolButtonAccess = class(TToolButton);
3
 
4
function ToolButtonScreenPos(AToolButton: TToolButton): TPoint;
5
begin
6
  GetDCOrgEx(TToolButtonAccess(AToolButton).Canvas.Handle, Result);
7
  Inc(Result.X, AToolButton.Left);
8
  Inc(Result.Y, AToolButton.Top);
9
end;

Hugs!



01
Sep 08

Delphi: Utils :: SpeedButtonScreenPos

:: articles :: by Gilberto Saraiva

Folks,

For everybody that needs the Speedbutton position:

 Delphi |  copy code |? 
1
type
2
  TSpeedButtonAccess = class(TSpeedButton);
3
 
4
function SpeedButtonScreenPos(ASpeedButton: TSpeedButton): TPoint;
5
begin
6
  GetDCOrgEx(TSpeedButtonAccess(ASpeedButton).Canvas.Handle, Result);
7
  Inc(Result.X, ASpeedButton.Left);
8
  Inc(Result.Y, ASpeedButton.Top);
9
end;

Hugs!



01
Sep 08

Delphi: Utils :: DesktopArea

:: articles :: by Gilberto Saraiva

Folks,

For everybody that need to show something only on the useful area of the desktop I wrote this function:

 Delphi |  copy code |? 
1
function DesktopClientArea: TRect;
2
var
3
  rDesktop, rWinBar: TRect;
4
begin
5
  Windows.GetWindowRect(GetDesktopWindow, rDesktop);
6
  Windows.GetWindowRect(FindWindow('Shell_TrayWnd', nil), rWinBar);
7
  SubtractRect(Result, rDesktop, rWinBar);
8
end;

Hugs!



28
Jul 08

Delphi: Utils :: ChangeDropShadow

:: articles :: by Gilberto Saraiva

Folks,

With this procedure you can change the Drop Shadow effect provided by windows XP/Vista on all windows without need to reset the computer.

 Delphi |  copy code |? 
01
procedure ChangeDropShadow(AActive: boolean);
02
var
03
  Buff: Cardinal;
04
  Param: Pointer;
05
  DevMode: TDeviceMode;
06
begin
07
  with TRegistry.Create do
08
  begin
09
    RootKey := HKEY_CURRENT_USER;
10
    if OpenKey('\Control Panel\Desktop\', false) then
11
    begin
12
      ReadBinaryData('UserPreferencesMask', Buff, 4);
13
      if AActive then
14
        Buff := Buff or (1 shl 18)
15
      else
16
        Buff := Buff xor (Buff and (1 shl 18));
17
      WriteBinaryData('UserPreferencesMask', Buff, 4);
18
      Param := nil;
19
      if AActive then
20
        Param := @AActive;
21
 
22
      SystemParametersInfo(SPI_SETDROPSHADOW, 0,
23
        Param, SPIF_SENDWININICHANGE);
24
    end;
25
    Free;
26
  end;
27
end;

Hugs!