1
0
mirror of synced 2024-11-21 17:43:51 +00:00

Fixed: memory leak in CreateImage method

Changed: GraphicList now uses TComponent-based items to support Visual Inheritance
This commit is contained in:
Mark van Renswoude 2007-01-04 19:47:47 +00:00
parent 7ca9314af1
commit a60c185db1
6 changed files with 895 additions and 387 deletions

View File

@ -13,16 +13,9 @@ uses
DesignIntf; DesignIntf;
type type
TX2GraphicsProperty = class(TClassProperty)
public
function AllEqual(): Boolean; override;
procedure Edit(); override;
function GetAttributes(): TPropertyAttributes; override;
end;
TX2GraphicContainerEditor = class(TComponentEditor) TX2GraphicContainerEditor = class(TComponentEditor)
private protected
procedure FindGraphics(const Prop: IProperty); procedure Convert();
public public
procedure Edit(); override; procedure Edit(); override;
procedure ExecuteVerb(Index: Integer); override; procedure ExecuteVerb(Index: Integer); override;
@ -44,62 +37,75 @@ uses
X2CLGraphicList, X2CLGraphicList,
X2CLGraphicsEditor; X2CLGraphicsEditor;
type
{==================== TX2GraphicsProperty TProtectedX2GraphicContainer = class(TX2GraphicContainer);
Editor
========================================}
function TX2GraphicsProperty.AllEqual;
begin
Result := (PropCount = 1);
end;
procedure TX2GraphicsProperty.Edit;
begin
TfrmGraphicsEditor.Execute(TComponent(GetComponent(0)));
end;
function TX2GraphicsProperty.GetAttributes;
begin
Result := [paDialog, paReadOnly];
end;
{============== TX2GraphicContainerEditor {============== TX2GraphicContainerEditor
Editor Editor
========================================} ========================================}
procedure TX2GraphicContainerEditor.FindGraphics; procedure TX2GraphicContainerEditor.Edit();
begin begin
if SameText(Prop.GetName(), 'Graphics') then TfrmGraphicsEditor.Execute(Component, Self.Designer);
Prop.Edit();
end; end;
procedure TX2GraphicContainerEditor.Edit; procedure TX2GraphicContainerEditor.ExecuteVerb(Index: Integer);
var
dsComponents: TDesignerSelections;
begin begin
dsComponents := TDesignerSelections.Create(); case Index of
try 0: Edit();
IDesignerSelections(dsComponents).Add(Component); 1: Convert();
GetComponentProperties(dsComponents, tkProperties, Designer, FindGraphics);
finally
FreeAndNil(dsComponents);
end; end;
end; end;
procedure TX2GraphicContainerEditor.ExecuteVerb; function TX2GraphicContainerEditor.GetVerb(Index: Integer): String;
begin begin
Edit(); case Index of
0: Result := 'Graphics Editor...';
1: Result := 'Convert items';
end;
end; end;
function TX2GraphicContainerEditor.GetVerb; function TX2GraphicContainerEditor.GetVerbCount(): Integer;
begin
Result := 'Graphics Editor...';
end;
function TX2GraphicContainerEditor.GetVerbCount;
begin begin
Result := 1; Result := 1;
if TProtectedX2GraphicContainer(Component).ConversionRequired then
Inc(Result);
end;
procedure TX2GraphicContainerEditor.Convert();
var
container: TX2GraphicContainer;
tempContainer: TX2GraphicContainer;
graphicIndex: Integer;
graphicItem: TX2GraphicContainerItem;
begin
if not Assigned(Designer) then
exit;
container := TX2GraphicContainer(Component);
tempContainer := TX2GraphicContainer.Create(nil);
try
tempContainer.Assign(container);
container.Clear();
for graphicIndex := 0 to Pred(tempContainer.GraphicCount) do
begin
graphicItem := TX2GraphicContainerItem(Designer.CreateComponent(TX2GraphicContainerItem, nil, 0, 0, 0, 0));
if Assigned(graphicItem) then
begin
graphicItem.Assign(tempContainer.Graphics[graphicIndex]);
graphicItem.Container := container;
end;
end;
TProtectedX2GraphicContainer(container).ConversionRequired := False;
finally
FreeAndNil(tempContainer);
end;
end; end;
@ -124,4 +130,4 @@ begin
end; end;
end. end.

View File

@ -21,12 +21,13 @@ uses
procedure Register; procedure Register;
begin begin
RegisterNoIcon([TX2GraphicContainerItem]);
RegisterComponents('X2Software', [TX2GraphicContainer, TX2GraphicList]); RegisterComponents('X2Software', [TX2GraphicContainer, TX2GraphicList]);
RegisterPropertyEditor(TypeInfo(TX2GraphicCollection), TX2GraphicContainer, 'Graphics', TX2GraphicsProperty);
RegisterComponentEditor(TX2GraphicContainer, TX2GraphicContainerEditor); RegisterComponentEditor(TX2GraphicContainer, TX2GraphicContainerEditor);
RegisterComponentEditor(TX2GraphicList, TX2GraphicListEditor); RegisterComponentEditor(TX2GraphicList, TX2GraphicListEditor);
end; end;
end. end.

View File

@ -20,13 +20,13 @@ object frmGraphicsEditor: TfrmGraphicsEditor
Left = 189 Left = 189
Top = 0 Top = 0
Width = 4 Width = 4
Height = 424 Height = 422
end end
object pnlImage: TPanel object pnlImage: TPanel
Left = 193 Left = 193
Top = 0 Top = 0
Width = 333 Width = 333
Height = 424 Height = 422
Align = alClient Align = alClient
BevelOuter = bvNone BevelOuter = bvNone
TabOrder = 1 TabOrder = 1
@ -60,7 +60,7 @@ object frmGraphicsEditor: TfrmGraphicsEditor
Left = 0 Left = 0
Top = 26 Top = 26
Width = 333 Width = 333
Height = 370 Height = 368
Align = alClient Align = alClient
BevelInner = bvNone BevelInner = bvNone
BevelKind = bkTile BevelKind = bkTile
@ -78,7 +78,7 @@ object frmGraphicsEditor: TfrmGraphicsEditor
end end
object pnlProperties: TPanel object pnlProperties: TPanel
Left = 0 Left = 0
Top = 396 Top = 394
Width = 333 Width = 333
Height = 28 Height = 28
Align = alBottom Align = alBottom
@ -110,7 +110,7 @@ object frmGraphicsEditor: TfrmGraphicsEditor
Left = 0 Left = 0
Top = 0 Top = 0
Width = 189 Width = 189
Height = 424 Height = 422
Align = alLeft Align = alLeft
BevelOuter = bvNone BevelOuter = bvNone
TabOrder = 0 TabOrder = 0
@ -118,7 +118,7 @@ object frmGraphicsEditor: TfrmGraphicsEditor
Left = 0 Left = 0
Top = 26 Top = 26
Width = 189 Width = 189
Height = 398 Height = 396
Align = alClient Align = alClient
ItemHeight = 13 ItemHeight = 13
TabOrder = 1 TabOrder = 1
@ -168,7 +168,7 @@ object frmGraphicsEditor: TfrmGraphicsEditor
Top = 388 Top = 388
Bitmap = { Bitmap = {
494C010107000900040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 494C010107000900040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
0000000000003600000028000000400000003000000001001000000000000018 0000000000003600000028000000400000003000000001002000000000000030
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
@ -250,37 +250,14 @@ object frmGraphicsEditor: TfrmGraphicsEditor
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000001002
1002100200000000000000000000000000000000000000000000000000000000
1002000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000001002
1002100200000000000000000000000000000000000000000000000000001002
1002100200000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000001002
1002100200000000000000000000000000000000000000000000000010021002
1002100210020000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000001002
1002100200000000000000000000000000000000000000000000100210021002
1002100210021002000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000100210021002
1002100210021002000000000000000000000000000000000000000000001002
1002100200000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000010021002
1002100210020000000000000000000000000000000000000000000000001002
1002100200000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000001002
1002100200000000000000000000000000000000000000000000000000001002
1002100200000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
1002000000000000000000000000000000000000000000000000000000001002
1002100200000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
@ -301,63 +278,278 @@ object frmGraphicsEditor: TfrmGraphicsEditor
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000010421042104210421042
1042104210421042104210421042104210420000000010421042104210421042
1042104210421042104210421042104210420000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000010420000000000000000000000000000
0000000000000000000000000000000010420000000000000000000000000000
0000000000000000000000000000000000000000000000420042000000000000
00000000000000000000000000420000000000000000FF7FE07FFF7FE07FFF7F
E07FFF7FE07F00000000FF7FE07F0000104200000000FF7FE07FFF7FE07FFF7F
E07FFF7FE07F00000000FF7FE07F000010420000000000000000000000000000
0000000000000000000000000000000000000000000000420042000000000000
00000000000000000000000000420000000000000000E07FFF7FE07FFF7FE07F
FF7FE07FFF7F000018630000FF7F0000104210420000E07FFF7FE07FFF7FE07F
FF7FE07FFF7F000018630000FF7F000010420000000000420042004200420042
0042004200420042000000000000000000000000000000420042000000000000
00000000000000000000000000420000000000000000FF7FE07FFF7FE07FFF7F
E07FFF7FE07F0000E07F186300000000104200400000FF7FE07FFF7FE07FFF7F
E07FFF7FE07F0000E07F18630000000010420000FF7F00000042004200420042
0042004200420042004200000000000000000000000000420042000000000000
00000000000000000000000000420000000000000000E07FFF7FE07FFF7FE07F
FF7FE07FFF7F00000000000000000000104200400040E07FFF7FE07FFF7F1042
0040E07FFF7F0000000000000000000010420000E07FFF7F0000004200420042
0042004200420042004200420000000000000000000000420042004200420042
00420042004200420042004200420000000000000000FF7F1042E07FFF7FE07F
FF7FE07FE07FFF7FE07FFF7FE07F00001042104200401042E07FFF7F10420040
1042FF7FE07FFF7FE07FFF7FE07F000010420000FF7FE07FFF7F000000420042
0042004200420042004200420042000000000000000000420042000000000000
0000000000000000000000420042000000001042E07FE07F1042FF7FE07F1042
E07FFF7FFF7FE07FFF7FE07FFF7F000010420000004000401042E07F00400040
FF7FE07FFF7FE07FFF7FE07FFF7F000010420000E07FFF7FE07FFF7F00000000
0000000000000000000000000000000000000000000000420000000000000000
00000000000000000000000000420000000000001042FF7F1042E07F1042E07F
FF7FE07FE07FFF7FE07FFF7FE07F00001042000010420040004000400040FF7F
E07FFF7FE07FFF7FE07FFF7FE07F000010420000FF7FE07FFF7FE07FFF7FE07F
FF7FE07FFF7F0000000000000000000000000000000000420000000000000000
000000000000000000000000004200000000104210421042FF7F1042FF7FE07F
FF7FE07FFF7FE07FFF7FE07FFF7F0000104200001042004000400040FF7FE07F
FF7FE07FFF7FE07FFF7FE07FFF7F000010420000E07FFF7FE07FFF7FE07FFF7F
E07FFF7FE07F0000000000000000000000000000000000420000000000000000
0000000000000000000000000042000000000000E07F1042E07FFF7F10421042
1042104200000000000000000000000000001042004000400040004010420000
0000000000000000000000000000000000000000FF7FE07FFF7F000000000000
0000000000000000000000000000000000000000000000420000000000000000
00000000000000000000000000420000000000001042E07F1042E07F1042E07F
0000000000000000000000000000000000000040004010420000004000401042
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000420000000000000000
0000000000000000000000000000000000001042E07F00001042000000001042
E07F000000000000000000000000000000000000000000000000000000400040
1042000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000420000000000000000
000000000000000000000000000000000000E07F000000001042E07F00000000
1042000000000000000000000000000000000000000000000000000000000040
0040104200000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000001042000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000084840000848400008484000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000848400000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000084840000848400008484000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000084840000848400008484000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000084840000848400008484000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000008484000084840000848400008484000084840000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000084840000848400008484000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000848400008484000084840000848400008484000084840000848400000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000848400008484000084840000848400008484000084840000848400000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000084840000848400008484000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000008484000084840000848400008484000084840000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000084840000848400008484000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000084840000848400008484000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000084840000848400008484000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000848400000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000084840000848400008484000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000848484008484
8400848484008484840084848400848484008484840084848400848484008484
8400848484008484840084848400848484000000000000000000848484008484
8400848484008484840084848400848484008484840084848400848484008484
8400848484008484840084848400848484000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000848484000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000848484000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000008484000084
8400000000000000000000000000000000000000000000000000000000000000
0000000000000084840000000000000000000000000000000000FFFFFF0000FF
FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00000000000000
0000FFFFFF0000FFFF0000000000848484000000000000000000FFFFFF0000FF
FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00000000000000
0000FFFFFF0000FFFF0000000000848484000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000008484000084
8400000000000000000000000000000000000000000000000000000000000000
000000000000008484000000000000000000000000000000000000FFFF00FFFF
FF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000000000C6C6
C60000000000FFFFFF000000000084848400848484000000000000FFFF00FFFF
FF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000000000C6C6
C60000000000FFFFFF0000000000848484000000000000000000008484000084
8400008484000084840000848400008484000084840000848400008484000000
0000000000000000000000000000000000000000000000000000008484000084
8400000000000000000000000000000000000000000000000000000000000000
0000000000000084840000000000000000000000000000000000FFFFFF0000FF
FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF000000000000FF
FF00C6C6C6000000000000000000848484000000840000000000FFFFFF0000FF
FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF000000000000FF
FF00C6C6C60000000000000000008484840000000000FFFFFF00000000000084
8400008484000084840000848400008484000084840000848400008484000084
8400000000000000000000000000000000000000000000000000008484000084
8400000000000000000000000000000000000000000000000000000000000000
000000000000008484000000000000000000000000000000000000FFFF00FFFF
FF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF00000000000000
000000000000000000000000000084848400000084000000840000FFFF00FFFF
FF0000FFFF00FFFFFF00848484000000840000FFFF00FFFFFF00000000000000
0000000000000000000000000000848484000000000000FFFF00FFFFFF000000
0000008484000084840000848400008484000084840000848400008484000084
8400008484000000000000000000000000000000000000000000008484000084
8400008484000084840000848400008484000084840000848400008484000084
8400008484000084840000000000000000000000000000000000FFFFFF008484
840000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF0000FFFF00FFFFFF0000FF
FF00FFFFFF0000FFFF00000000008484840084848400000084008484840000FF
FF00FFFFFF00848484000000840084848400FFFFFF0000FFFF00FFFFFF0000FF
FF00FFFFFF0000FFFF00000000008484840000000000FFFFFF0000FFFF00FFFF
FF00000000000084840000848400008484000084840000848400008484000084
8400008484000084840000000000000000000000000000000000008484000084
8400000000000000000000000000000000000000000000000000000000000000
0000008484000084840000000000000000008484840000FFFF0000FFFF008484
8400FFFFFF0000FFFF008484840000FFFF00FFFFFF00FFFFFF0000FFFF00FFFF
FF0000FFFF00FFFFFF0000000000848484000000000000008400000084008484
840000FFFF000000840000008400FFFFFF0000FFFF00FFFFFF0000FFFF00FFFF
FF0000FFFF00FFFFFF0000000000848484000000000000FFFF00FFFFFF0000FF
FF00FFFFFF000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000008484000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000084840000000000000000000000000084848400FFFFFF008484
840000FFFF008484840000FFFF00FFFFFF0000FFFF0000FFFF00FFFFFF0000FF
FF00FFFFFF0000FFFF0000000000848484000000000084848400000084000000
84000000840000008400FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FF
FF00FFFFFF0000FFFF00000000008484840000000000FFFFFF0000FFFF00FFFF
FF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF00000000000000
0000000000000000000000000000000000000000000000000000008484000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000008484000000000000000000848484008484840084848400FFFF
FF0084848400FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFF
FF0000FFFF00FFFFFF0000000000848484000000000084848400000084000000
840000008400FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFF
FF0000FFFF00FFFFFF0000000000848484000000000000FFFF00FFFFFF0000FF
FF00FFFFFF0000FFFF00FFFFFF0000FFFF00FFFFFF0000FFFF00000000000000
0000000000000000000000000000000000000000000000000000008484000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000084840000000000000000000000000000FFFF008484840000FF
FF00FFFFFF008484840084848400848484008484840000000000000000000000
0000000000000000000000000000000000008484840000008400000084000000
8400000084008484840000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000FFFFFF0000FFFF00FFFF
FF00000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000008484000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000008484000000000000000000000000008484840000FFFF008484
840000FFFF008484840000FFFF00000000000000000000000000000000000000
0000000000000000000000000000000000000000840000008400848484000000
0000000084000000840084848400000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000008484000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000008484840000FFFF00000000008484
840000000000000000008484840000FFFF000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000840000008400848484000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000008484000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000FFFF0000000000000000008484
840000FFFF000000000000000000848484000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000008400000084008484840000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000008484
8400000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000

View File

@ -13,6 +13,7 @@ uses
Classes, Classes,
ComCtrls, ComCtrls,
Controls, Controls,
DesignIntf,
Dialogs, Dialogs,
ExtCtrls, ExtCtrls,
ExtDlgs, ExtDlgs,
@ -68,15 +69,17 @@ type
procedure actClearExecute(Sender: TObject); procedure actClearExecute(Sender: TObject);
private private
FComponent: TX2GraphicContainer; FComponent: TX2GraphicContainer;
FComponentDesigner: IDesigner;
procedure InternalExecute(const AComponent: TComponent); procedure InternalExecute(const AComponent: TComponent; const ADesigner: IDesigner);
procedure Administrate(); procedure Administrate();
procedure UpdatePreview(); procedure UpdatePreview();
function Active(out AIndex: Integer; function Active(out AIndex: Integer; out AGraphic: TX2GraphicContainerItem): Boolean;
out AGraphic: TX2GraphicCollectionItem): Boolean; protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
public public
class procedure Execute(const AComponent: TComponent); class procedure Execute(const AComponent: TComponent; const ADesigner: IDesigner);
end; end;
implementation implementation
@ -94,21 +97,24 @@ var
{===================== TfrmGraphicsEditor {===================== TfrmGraphicsEditor
Initialization Initialization
========================================} ========================================}
class procedure TfrmGraphicsEditor.Execute; class procedure TfrmGraphicsEditor.Execute(const AComponent: TComponent; const ADesigner: IDesigner);
begin begin
if not Assigned(GEditor) then if not Assigned(GEditor) then
GEditor := TfrmGraphicsEditor.Create(Application); GEditor := TfrmGraphicsEditor.Create(Application);
GEditor.InternalExecute(AComponent); GEditor.InternalExecute(AComponent, ADesigner);
end; end;
procedure TfrmGraphicsEditor.InternalExecute; procedure TfrmGraphicsEditor.InternalExecute(const AComponent: TComponent; const ADesigner: IDesigner);
var var
iGraphic: Integer; iGraphic: Integer;
begin begin
FComponent := TX2GraphicContainer(AComponent); FComponent := TX2GraphicContainer(AComponent);
Caption := Format('%s.Graphics', [FComponent.Name]); FComponent.FreeNotification(Self);
FComponentDesigner := ADesigner;
Caption := Format('%s Graphics', [FComponent.Name]);
// Fill graphics list // Fill graphics list
with lstGraphics.Items do with lstGraphics.Items do
@ -117,8 +123,8 @@ begin
try try
Clear(); Clear();
for iGraphic := 0 to FComponent.Graphics.Count - 1 do for iGraphic := 0 to FComponent.GraphicCount - 1 do
AddObject(FComponent.Graphics[iGraphic].DisplayName, AddObject(FComponent.Graphics[iGraphic].PictureName,
FComponent.Graphics[iGraphic]); FComponent.Graphics[iGraphic]);
finally finally
EndUpdate(); EndUpdate();
@ -132,18 +138,21 @@ begin
Show(); Show();
end; end;
procedure TfrmGraphicsEditor.FormClose; procedure TfrmGraphicsEditor.FormClose(Sender: TObject; var Action: TCloseAction);
begin begin
Action := caFree; Action := caFree;
GEditor := nil; GEditor := nil;
if Assigned(FComponent) then
FComponent.RemoveFreeNotification(Self);
end; end;
procedure TfrmGraphicsEditor.Administrate; procedure TfrmGraphicsEditor.Administrate();
var var
bEnabled: Boolean; bEnabled: Boolean;
iIndex: Integer; iIndex: Integer;
pGraphic: TX2GraphicCollectionItem; pGraphic: TX2GraphicContainerItem;
begin begin
bEnabled := Active(iIndex, pGraphic); bEnabled := Active(iIndex, pGraphic);
@ -162,18 +171,23 @@ begin
actDown.Enabled := bEnabled and (iIndex < lstGraphics.Items.Count - 1); actDown.Enabled := bEnabled and (iIndex < lstGraphics.Items.Count - 1);
end; end;
procedure TfrmGraphicsEditor.UpdatePreview; procedure TfrmGraphicsEditor.UpdatePreview();
var var
iIndex: Integer; iIndex: Integer;
pGraphic: TX2GraphicCollectionItem; pGraphic: TX2GraphicContainerItem;
begin begin
if Active(iIndex, pGraphic) then if Active(iIndex, pGraphic) then
begin begin
imgPreview.Picture.Assign(pGraphic.Picture); imgPreview.Picture.Assign(pGraphic.Picture);
txtName.Text := pGraphic.Name; txtName.Text := pGraphic.PictureName;
Administrate(); Administrate();
end;
if Assigned(FComponentDesigner) then
FComponentDesigner.SelectComponent(pGraphic);
end else
if Assigned(FComponentDesigner) then
FComponentDesigner.SelectComponent(FComponent);
end; end;
@ -181,63 +195,76 @@ end;
{===================== TfrmGraphicsEditor {===================== TfrmGraphicsEditor
Graphic Management Graphic Management
========================================} ========================================}
function TfrmGraphicsEditor.Active; function TfrmGraphicsEditor.Active(out AIndex: Integer; out AGraphic: TX2GraphicContainerItem): Boolean;
begin begin
Result := False; Result := False;
AIndex := lstGraphics.ItemIndex; AIndex := lstGraphics.ItemIndex;
if AIndex = -1 then if AIndex = -1 then
exit; exit;
AGraphic := TX2GraphicCollectionItem(lstGraphics.Items.Objects[AIndex]); AGraphic := TX2GraphicContainerItem(lstGraphics.Items.Objects[AIndex]);
Result := Assigned(AGraphic); Result := Assigned(AGraphic);
end; end;
procedure TfrmGraphicsEditor.lstGraphicsClick; procedure TfrmGraphicsEditor.lstGraphicsClick(Sender: TObject);
begin begin
UpdatePreview(); UpdatePreview();
end; end;
procedure TfrmGraphicsEditor.txtNameChange; procedure TfrmGraphicsEditor.txtNameChange(Sender: TObject);
var var
iIndex: Integer; iIndex: Integer;
pGraphic: TX2GraphicCollectionItem; pGraphic: TX2GraphicContainerItem;
begin begin
if Active(iIndex, pGraphic) then if Active(iIndex, pGraphic) then
begin begin
pGraphic.Name := txtName.Text; pGraphic.PictureName := txtName.Text;
lstGraphics.Items[iIndex] := pGraphic.DisplayName; lstGraphics.Items[iIndex] := pGraphic.PictureName;
end; end;
end; end;
procedure TfrmGraphicsEditor.actAddExecute; procedure TfrmGraphicsEditor.actAddExecute(Sender: TObject);
var var
iIndex: Integer; iIndex: Integer;
pGraphic: TX2GraphicCollectionItem; pGraphic: TX2GraphicContainerItem;
begin begin
pGraphic := FComponent.Graphics.Add(); if Assigned(FComponentDesigner) then
iIndex := lstGraphics.Items.AddObject(pGraphic.DisplayName, begin
pGraphic); pGraphic := TX2GraphicContainerItem(FComponentDesigner.CreateComponent(TX2GraphicContainerItem, nil, 0, 0, 0, 0));
lstGraphics.ItemIndex := iIndex; if Assigned(pGraphic) then
UpdatePreview(); begin
pGraphic.Container := FComponent;
actOpen.Execute(); iIndex := lstGraphics.Items.AddObject(pGraphic.PictureName,
pGraphic);
lstGraphics.ItemIndex := iIndex;
UpdatePreview();
actOpen.Execute();
end else
raise Exception.Create('Failed to create TX2GraphicContainerItem!');
end else
raise Exception.Create('Designer not found!');
end; end;
procedure TfrmGraphicsEditor.actDeleteExecute; procedure TfrmGraphicsEditor.actDeleteExecute(Sender: TObject);
var var
iIndex: Integer; iIndex: Integer;
pGraphic: TX2GraphicCollectionItem; pGraphic: TX2GraphicContainerItem;
begin begin
if Active(iIndex, pGraphic) then if Active(iIndex, pGraphic) then
begin begin
{ First attempt to remove the component; this will raise an exception
if it's not allowed, for example due to it being introduced in
an ancestor. }
pGraphic.Free();
lstGraphics.Items.Delete(iIndex); lstGraphics.Items.Delete(iIndex);
FComponent.Graphics.Delete(pGraphic.Index);
if iIndex > lstGraphics.Items.Count - 1 then if iIndex > lstGraphics.Items.Count - 1 then
iIndex := lstGraphics.Items.Count - 1; iIndex := lstGraphics.Items.Count - 1;
@ -247,10 +274,10 @@ begin
end; end;
end; end;
procedure TfrmGraphicsEditor.actUpExecute; procedure TfrmGraphicsEditor.actUpExecute(Sender: TObject);
var var
iIndex: Integer; iIndex: Integer;
pGraphic: TX2GraphicCollectionItem; pGraphic: TX2GraphicContainerItem;
begin begin
if Active(iIndex, pGraphic) then if Active(iIndex, pGraphic) then
@ -263,10 +290,10 @@ begin
end; end;
end; end;
procedure TfrmGraphicsEditor.actDownExecute; procedure TfrmGraphicsEditor.actDownExecute(Sender: TObject);
var var
iIndex: Integer; iIndex: Integer;
pGraphic: TX2GraphicCollectionItem; pGraphic: TX2GraphicContainerItem;
begin begin
if Active(iIndex, pGraphic) then if Active(iIndex, pGraphic) then
@ -280,10 +307,10 @@ begin
end; end;
procedure TfrmGraphicsEditor.actOpenExecute; procedure TfrmGraphicsEditor.actOpenExecute(Sender: TObject);
var var
iIndex: Integer; iIndex: Integer;
pGraphic: TX2GraphicCollectionItem; pGraphic: TX2GraphicContainerItem;
begin begin
if Active(iIndex, pGraphic) then if Active(iIndex, pGraphic) then
@ -292,36 +319,36 @@ begin
if dlgOpen.Execute() then if dlgOpen.Execute() then
begin begin
pGraphic.Picture.LoadFromFile(dlgOpen.FileName); pGraphic.Picture.LoadFromFile(dlgOpen.FileName);
if Length(pGraphic.Name) = 0 then if Length(pGraphic.PictureName) = 0 then
pGraphic.Name := ChangeFileExt(ExtractFileName(dlgOpen.FileName), ''); pGraphic.PictureName := ChangeFileExt(ExtractFileName(dlgOpen.FileName), '');
UpdatePreview(); UpdatePreview();
end; end;
end; end;
end; end;
procedure TfrmGraphicsEditor.actSaveExecute; procedure TfrmGraphicsEditor.actSaveExecute(Sender: TObject);
var var
iIndex: Integer; iIndex: Integer;
pClass: TGraphicClass; pClass: TGraphicClass;
pGraphic: TX2GraphicCollectionItem; pGraphic: TX2GraphicContainerItem;
begin begin
if Active(iIndex, pGraphic) then if Active(iIndex, pGraphic) then
if Assigned(pGraphic.Picture.Graphic) then begin if Assigned(pGraphic.Picture.Graphic) then begin
pClass := TGraphicClass(pGraphic.Picture.Graphic.ClassType); pClass := TGraphicClass(pGraphic.Picture.Graphic.ClassType);
dlgSave.Filter := GraphicFilter(pClass); dlgSave.Filter := GraphicFilter(pClass);
dlgSave.FileName := ChangeFileExt(pGraphic.Name, '.' + GraphicExtension(pClass)); dlgSave.FileName := ChangeFileExt(pGraphic.PictureName, '.' + GraphicExtension(pClass));
if dlgSave.Execute() then if dlgSave.Execute() then
pGraphic.Picture.SaveToFile(dlgSave.FileName); pGraphic.Picture.SaveToFile(dlgSave.FileName);
end; end;
end; end;
procedure TfrmGraphicsEditor.actClearExecute; procedure TfrmGraphicsEditor.actClearExecute(Sender: TObject);
var var
iIndex: Integer; iIndex: Integer;
pGraphic: TX2GraphicCollectionItem; pGraphic: TX2GraphicContainerItem;
begin begin
if Active(iIndex, pGraphic) then if Active(iIndex, pGraphic) then
@ -331,4 +358,16 @@ begin
end; end;
end; end;
procedure TfrmGraphicsEditor.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if (Operation = opRemove) and (AComponent = FComponent) then
begin
FComponent := nil;
Close();
end;
end;
end. end.

View File

@ -7,7 +7,6 @@
:: the problems I thought we would face. His original (Dutch) article can :: the problems I thought we would face. His original (Dutch) article can
:: be found at: :: be found at:
:: http://www.erikstok.net/delphi/artikelen/xpicons.html :: http://www.erikstok.net/delphi/artikelen/xpicons.html
::
:: Last changed: $Date$ :: Last changed: $Date$
:: Revision: $Rev$ :: Revision: $Rev$
:: Author: $Author$ :: Author: $Author$
@ -36,54 +35,42 @@ type
{ {
:$ Holds a single graphic. :$ Holds a single graphic.
} }
TX2GraphicCollectionItem = class(TCollectionItem, IChangeNotifier) TX2GraphicContainerItem = class(TComponent, IChangeNotifier)
private private
FName: String; FContainer: TX2GraphicContainer;
FPicture: TPicture; FPicture: TPicture;
FPictureName: String;
function GetIndex(): Integer;
procedure SetContainer(const Value: TX2GraphicContainer);
procedure SetIndex(const Value: Integer);
procedure SetPicture(const Value: TPicture); procedure SetPicture(const Value: TPicture);
procedure SetName(const Value: String); procedure SetPictureName(const Value: String);
protected protected
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; procedure Changed(); virtual;
function _AddRef(): Integer; stdcall; procedure InternalSetContainer(const AContainer: TX2GraphicContainer); virtual;
function _Release(): Integer; stdcall;
function GetDisplayName(): String; override; function GenerateName(): String;
procedure NotifierChanged(); procedure NotifierChanged();
procedure IChangeNotifier.Changed = NotifierChanged; procedure IChangeNotifier.Changed = NotifierChanged;
procedure ReadState(Reader: TReader); override;
procedure SetParentComponent(AParent: TComponent); override;
public public
constructor Create(Collection: TCollection); override; constructor Create(AOwner: TComponent); override;
destructor Destroy(); override; destructor Destroy(); override;
function GetParentComponent(): TComponent; override;
function HasParent(): Boolean; override;
procedure AssignTo(Dest: TPersistent); override; procedure AssignTo(Dest: TPersistent); override;
published
property Name: String read FName write SetName;
property Picture: TPicture read FPicture write SetPicture;
end;
{
:$ Holds a collection of graphics.
}
TX2GraphicCollection = class(TCollection)
private
FContainer: TX2GraphicContainer;
function GetItem(Index: Integer): TX2GraphicCollectionItem;
procedure SetItem(Index: Integer; Value: TX2GraphicCollectionItem);
protected
procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); override;
procedure Update(Item: TCollectionItem); override;
public public
constructor Create(const AContainer: TX2GraphicContainer); property Container: TX2GraphicContainer read FContainer write SetContainer stored False;
property Index: Integer read GetIndex write SetIndex stored False;
function Add(): TX2GraphicCollectionItem; published
function IndexByName(const AName: String): Integer; property Picture: TPicture read FPicture write SetPicture;
function GraphicByName(const AName: String): TX2GraphicCollectionItem; property PictureName: String read FPictureName write SetPictureName;
function PictureByName(const AName: String): TPicture;
property Items[Index: Integer]: TX2GraphicCollectionItem read GetItem
write SetItem; default;
end; end;
{ {
@ -94,28 +81,48 @@ type
} }
TX2GraphicContainer = class(TComponent) TX2GraphicContainer = class(TComponent)
private private
FGraphics: TX2GraphicCollection; FConversionRequired: Boolean;
FLists: TList; FGraphics: TList;
FLists: TList;
procedure SetGraphics(const Value: TX2GraphicCollection); function GetGraphicCount(): Integer;
function GetGraphics(Index: Integer): TX2GraphicContainerItem;
procedure SetGraphics(Index: Integer; const Value: TX2GraphicContainerItem);
protected protected
procedure GetChildren(Proc: TGetChildProc; Root: TComponent); override;
procedure SetChildOrder(Component: TComponent; Order: Integer); override;
procedure SetName(const NewName: TComponentName); override;
procedure Notification(AComponent: TComponent; Operation: TOperation); override; procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure Notify(Item: TCollectionItem; Action: TCollectionNotification); virtual;
procedure Update(Item: TCollectionItem); virtual; procedure ConvertGraphics(Reader: TReader);
procedure DefineProperties(Filer: TFiler); override;
procedure AddGraphic(const AGraphic: TX2GraphicContainerItem); virtual;
procedure RemoveGraphic(const AGraphic: TX2GraphicContainerItem); virtual;
procedure UpdateGraphic(const AGraphic: TX2GraphicContainerItem); virtual;
procedure RegisterList(const AList: TX2GraphicList); procedure RegisterList(const AList: TX2GraphicList);
procedure UnregisterList(const AList: TX2GraphicList); procedure UnregisterList(const AList: TX2GraphicList);
property ConversionRequired: Boolean read FConversionRequired write FConversionRequired;
property GraphicsList: TList read FGraphics;
property Lists: TList read FLists;
public public
constructor Create(AOwner: TComponent); override; constructor Create(AOwner: TComponent); override;
destructor Destroy(); override; destructor Destroy(); override;
procedure Clear();
function IndexByName(const AName: String): Integer; function IndexByName(const AName: String): Integer;
function GraphicByName(const AName: String): TX2GraphicCollectionItem; function GraphicByName(const AName: String): TX2GraphicContainerItem;
function PictureByName(const AName: String): TPicture; function PictureByName(const AName: String): TPicture;
procedure AssignTo(Dest: TPersistent); override; procedure AssignTo(Dest: TPersistent); override;
published
property Graphics: TX2GraphicCollection read FGraphics write SetGraphics; property Graphics[Index: Integer]: TX2GraphicContainerItem read GetGraphics write SetGraphics;
property GraphicCount: Integer read GetGraphicCount;
end; end;
{ {
@ -156,7 +163,7 @@ type
procedure DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer; procedure DoDraw(Index: Integer; Canvas: TCanvas; X, Y: Integer;
Style: Cardinal; Enabled: Boolean = True); override; Style: Cardinal; Enabled: Boolean = True); override;
procedure CreateImage(const AIndex: Integer; var AImage, AMask: TBitmap); virtual; procedure BuildImage(const AIndex: Integer; const AImage, AMask: TBitmap); virtual;
procedure AddImage(const AIndex: Integer); virtual; procedure AddImage(const AIndex: Integer); virtual;
procedure UpdateImage(const AIndex: Integer); virtual; procedure UpdateImage(const AIndex: Integer); virtual;
procedure DeleteImage(const AIndex: Integer); virtual; procedure DeleteImage(const AIndex: Integer); virtual;
@ -183,6 +190,7 @@ type
implementation implementation
uses uses
Forms,
ImgList, ImgList,
SysUtils; SysUtils;
@ -194,162 +202,233 @@ type
{=============== TX2GraphicCollectionItem { Used for conversion purposes from the old collection-based Graphics property
to the new TComponent structure. }
TDeprecatedGraphicItem = class(TCollectionItem)
private
FName: String;
FPicture: TPicture;
procedure SetPicture(const Value: TPicture);
public
constructor Create(Collection: TCollection); override;
destructor Destroy(); override;
published
property Name: String read FName write FName;
property Picture: TPicture read FPicture write SetPicture;
end;
{================ TX2GraphicContainerItem
Initialization Initialization
========================================} ========================================}
constructor TX2GraphicCollectionItem.Create(Collection: TCollection); constructor TX2GraphicContainerItem.Create(AOwner: TComponent);
begin begin
inherited;
FPicture := TPicture.Create(); FPicture := TPicture.Create();
FPicture.PictureAdapter := Self; FPicture.PictureAdapter := Self;
inherited;
end; end;
destructor TX2GraphicCollectionItem.Destroy(); destructor TX2GraphicContainerItem.Destroy();
begin begin
if Assigned(Container) then
Container.RemoveGraphic(Self);
FreeAndNil(FPicture); FreeAndNil(FPicture);
inherited; inherited;
end; end;
procedure TX2GraphicCollectionItem.AssignTo(Dest: TPersistent); procedure TX2GraphicContainerItem.AssignTo(Dest: TPersistent);
begin begin
if Dest is TX2GraphicCollectionItem then if Dest is TX2GraphicContainerItem then
with TX2GraphicCollectionItem(Dest) do with TX2GraphicContainerItem(Dest) do
Picture := Self.Picture begin
Picture := Self.Picture;
PictureName := Self.PictureName;
end
else else
inherited; inherited;
end; end;
function TX2GraphicCollectionItem.QueryInterface(const IID: TGUID; procedure TX2GraphicContainerItem.NotifierChanged();
out Obj): HResult;
begin begin
if GetInterface(IID, Obj) then Changed();
Result := 0 end;
procedure TX2GraphicContainerItem.InternalSetContainer(const AContainer: TX2GraphicContainer);
begin
FContainer := AContainer;
end;
procedure TX2GraphicContainerItem.Changed();
begin
if Assigned(Container) then
Container.UpdateGraphic(Self);
end;
function TX2GraphicContainerItem.GetParentComponent(): TComponent;
begin
if Assigned(Container) then
Result := Container
else else
Result := E_NOINTERFACE; Result := inherited GetParentComponent();
end; end;
function TX2GraphicCollectionItem._AddRef(): Integer; function TX2GraphicContainerItem.HasParent(): Boolean;
begin begin
Result := -1; if Assigned(Container) then
end; Result := True
function TX2GraphicCollectionItem._Release(): Integer;
begin
Result := -1;
end;
function TX2GraphicCollectionItem.GetDisplayName(): String;
begin
if Length(FName) > 0 then
Result := FName
else else
Result := inherited GetDisplayName(); Result := inherited HasParent();
end; end;
procedure TX2GraphicCollectionItem.NotifierChanged();
procedure TX2GraphicContainerItem.ReadState(Reader: TReader);
begin begin
Changed(False); inherited;
if Reader.Parent is TX2GraphicContainer then
Container := TX2GraphicContainer(Reader.Parent);
end; end;
procedure TX2GraphicCollectionItem.SetName(const Value: String); procedure TX2GraphicContainerItem.SetParentComponent(AParent: TComponent);
begin begin
FName := Value; if not (csLoading in ComponentState) and (AParent is TX2GraphicContainer) then
Changed(False); Container := TX2GraphicContainer(AParent);
end; end;
procedure TX2GraphicCollectionItem.SetPicture(const Value: TPicture);
function TX2GraphicContainerItem.GetIndex(): Integer;
begin
Result := -1;
if Assigned(Container) then
Result := Container.GraphicsList.IndexOf(Self);
end;
procedure TX2GraphicContainerItem.SetContainer(const Value: TX2GraphicContainer);
begin
if Value <> Container then
begin
if Assigned(Container) then
Container.RemoveGraphic(Self);
if Assigned(Value) then
Value.AddGraphic(Self);
if not (csLoading in ComponentState) then
Name := GenerateName();
end;
end;
procedure TX2GraphicContainerItem.SetIndex(const Value: Integer);
var
count: Integer;
curIndex: Integer;
newIndex: Integer;
begin
curIndex := GetIndex();
if curIndex > -1 then
begin
count := Container.GraphicsList.Count;
newIndex := Value;
if newIndex < 0 then
newIndex := 0;
if newIndex >= count then
newIndex := Pred(count);
if newIndex <> curIndex then
Container.GraphicsList.Move(curIndex, newIndex);
end;
end;
procedure TX2GraphicContainerItem.SetPicture(const Value: TPicture);
begin begin
FPicture.Assign(Value); FPicture.Assign(Value);
end; end;
procedure TX2GraphicContainerItem.SetPictureName(const Value: String);
{=================== TX2GraphicCollection
Item Management
========================================}
constructor TX2GraphicCollection.Create(const AContainer: TX2GraphicContainer);
begin begin
inherited Create(TX2GraphicCollectionItem); if Value <> FPictureName then
begin
FPictureName := Value;
FContainer := AContainer; if not (csLoading in ComponentState) then
Name := GenerateName();
end;
end; end;
function TX2GraphicCollection.Add(): TX2GraphicCollectionItem; function TX2GraphicContainerItem.GenerateName(): String;
begin function ValidComponentName(const AComponent: TComponent; const AName: String): Boolean;
Result := TX2GraphicCollectionItem(inherited Add()); var
end; checkOwner: TComponent;
existing: TComponent;
begin
Result := True;
checkOwner := AComponent;
function TX2GraphicCollection.IndexByName(const AName: String): Integer; while Assigned(checkOwner) do
var
iIndex: Integer;
begin
Result := -1;
for iIndex := Pred(Count) downto 0 do
if SameText(Items[iIndex].Name, AName) then
begin begin
Result := iIndex; existing := checkOwner.FindComponent(AName);
break;
if Assigned(existing) and (existing <> Self) then
begin
Result := False;
exit;
end;
checkOwner := checkOwner.Owner;
end; end;
end; end;
const
Alpha = ['A'..'Z', 'a'..'z', '_'];
AlphaNumeric = Alpha + ['0'..'9'];
function TX2GraphicCollection.GraphicByName(const AName: String): TX2GraphicCollectionItem;
var var
iIndex: Integer; charIndex: Integer;
counter: Integer;
resultName: String;
begin begin
Result := nil; if Assigned(Container) then
iIndex := IndexByName(AName); Result := Container.Name
if iIndex > -1 then else
Result := Items[iIndex]; Result := 'GraphicContainerItem';
for charIndex := 1 to Length(PictureName) do
if PictureName[charIndex] in AlphaNumeric then
Result := Result + PictureName[charIndex];
resultName := Result;
counter := 0;
while not ValidComponentName(Self, Result) do
begin
Inc(counter);
Result := resultName + IntToStr(counter);
end;
end; end;
function TX2GraphicCollection.PictureByName(const AName: String): TPicture;
var
pGraphic: TX2GraphicCollectionItem;
begin
Result := nil;
pGraphic := GraphicByName(AName);
if Assigned(pGraphic) then
Result := pGraphic.Picture;
end;
procedure TX2GraphicCollection.Notify(Item: TCollectionItem;
Action: TCollectionNotification);
begin
inherited;
if Assigned(FContainer) then
FContainer.Notify(Item, Action);
end;
procedure TX2GraphicCollection.Update(Item: TCollectionItem);
begin
inherited;
if Assigned(FContainer) then
FContainer.Update(Item);
end;
function TX2GraphicCollection.GetItem(Index: Integer): TX2GraphicCollectionItem;
begin
Result := TX2GraphicCollectionItem(inherited GetItem(Index));
end;
procedure TX2GraphicCollection.SetItem(Index: Integer; Value: TX2GraphicCollectionItem);
begin
inherited SetItem(Index, Value);
end;
{==================== TX2GraphicContainer {==================== TX2GraphicContainer
@ -359,12 +438,14 @@ constructor TX2GraphicContainer.Create(AOwner: TComponent);
begin begin
inherited; inherited;
FGraphics := TX2GraphicCollection.Create(Self); FGraphics := TList.Create();
FLists := TList.Create(); FLists := TList.Create();
end; end;
destructor TX2GraphicContainer.Destroy(); destructor TX2GraphicContainer.Destroy();
begin begin
Clear();
FreeAndNil(FGraphics); FreeAndNil(FGraphics);
FreeAndNil(FLists); FreeAndNil(FLists);
@ -373,95 +454,264 @@ end;
function TX2GraphicContainer.IndexByName(const AName: String): Integer; function TX2GraphicContainer.IndexByName(const AName: String): Integer;
var
graphicIndex: Integer;
begin begin
Result := FGraphics.IndexByName(AName); Result := -1;
for graphicIndex := Pred(GraphicCount) downto 0 do
if SameText(Graphics[graphicIndex].Name, AName) then
begin
Result := graphicIndex;
break;
end;
end; end;
function TX2GraphicContainer.GraphicByName(const AName: String): TX2GraphicCollectionItem; function TX2GraphicContainer.GraphicByName(const AName: String): TX2GraphicContainerItem;
var
graphicIndex: Integer;
begin begin
Result := FGraphics.GraphicByName(AName); Result := nil;
graphicIndex := IndexByName(AName);
if graphicIndex > -1 then
Result := Graphics[graphicIndex];
end; end;
function TX2GraphicContainer.PictureByName(const AName: String): TPicture; function TX2GraphicContainer.PictureByName(const AName: String): TPicture;
var
graphic: TX2GraphicContainerItem;
begin begin
Result := FGraphics.PictureByName(AName); Result := nil;
graphic := GraphicByName(AName);
if Assigned(graphic) then
Result := graphic.Picture;
end; end;
procedure TX2GraphicContainer.AssignTo(Dest: TPersistent); procedure TX2GraphicContainer.AssignTo(Dest: TPersistent);
var
destContainer: TX2GraphicContainer;
graphicIndex: Integer;
begin begin
if Dest is TX2GraphicContainer then if Dest is TX2GraphicContainer then
with TX2GraphicContainer(Dest) do begin
Graphics := Self.Graphics destContainer := TX2GraphicContainer(Dest);
destContainer.Clear();
for graphicIndex := 0 to Pred(Self.GraphicCount) do
with TX2GraphicContainerItem.Create(destContainer) do
begin
Assign(Self.Graphics[graphicIndex]);
Container := destContainer;
end;
end
else else
inherited; inherited;
end; end;
procedure TX2GraphicContainer.Notification(AComponent: TComponent; Operation: TOperation); procedure TX2GraphicContainer.Clear();
begin begin
if not Assigned(FLists) then while GraphicsList.Count > 0 do
exit; TX2GraphicContainerItem(GraphicsList.Last).Free();
if Operation = opRemove then
FLists.Remove(AComponent)
else
// In design-time, if a TX2GraphicList is added and it doesn't yet have
// a container, assign ourselves to it for lazy programmers (such as me :))
if (Operation = opInsert) and (csDesigning in ComponentState) and
(AComponent is TX2GraphicList) and
(not Assigned(TX2GraphicList(AComponent).Container)) then
TX2GraphicList(AComponent).Container := Self;
inherited;
end; end;
procedure TX2GraphicContainer.Notify(Item: TCollectionItem;
Action: TCollectionNotification); procedure TX2GraphicContainer.GetChildren(Proc: TGetChildProc; Root: TComponent);
var var
iList: Integer; graphicIndex: Integer;
graphic: TX2GraphicContainerItem;
begin begin
case Action of for graphicIndex := 0 to Pred(GraphicCount) do
cnAdded: begin
for iList := FLists.Count - 1 downto 0 do graphic := Graphics[graphicIndex];
TX2GraphicList(FLists[iList]).AddImage(Item.Index); Proc(graphic);
cnDeleting:
for iList := FLists.Count - 1 downto 0 do
TX2GraphicList(FLists[iList]).DeleteImage(Item.Index);
end; end;
end; end;
procedure TX2GraphicContainer.Update(Item: TCollectionItem); procedure TX2GraphicContainer.SetChildOrder(Component: TComponent; Order: Integer);
begin
if GraphicsList.IndexOf(Component) >= 0 then
(Component as TX2GraphicContainerItem).Index := Order;
end;
procedure TX2GraphicContainer.SetName(const NewName: TComponentName);
var var
iList: Integer; oldName: String;
graphicIndex: Integer;
begin begin
if Assigned(Item) then oldName := Self.Name;
for iList := FLists.Count - 1 downto 0 do
TX2GraphicList(FLists[iList]).UpdateImage(Item.Index) inherited;
else
for iList := FLists.Count - 1 downto 0 do if Self.Name <> oldName then
TX2GraphicList(FLists[iList]).RebuildImages(); begin
{ Re-generate names for graphic components }
for graphicIndex := 0 to Pred(GraphicCount) do
Graphics[graphicIndex].Name := Graphics[graphicIndex].GenerateName();
end;
end;
procedure TX2GraphicContainer.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
case Operation of
opInsert:
{ In design-time, if a TX2GraphicList is added and it doesn't yet have
a container, assign ourselves to it for lazy programmers (such as me :)) }
if (csDesigning in ComponentState) and
(AComponent is TX2GraphicList) and
(not Assigned(TX2GraphicList(AComponent).Container)) then
TX2GraphicList(AComponent).Container := Self;
opRemove:
begin
if AComponent is TX2GraphicContainerItem then
RemoveGraphic(TX2GraphicContainerItem(AComponent))
else if AComponent is TX2GraphicList then
Lists.Remove(AComponent);
end;
end;
end;
procedure TX2GraphicContainer.DefineProperties(Filer: TFiler);
begin
inherited;
{ Previous versions used a Collection to hold the container items. As this
wasn't Visual Inheritance-friendly, container items are now TComponents.
This will convert the deprecated Graphics property. }
Filer.DefineProperty('Graphics', ConvertGraphics, nil, False);
end;
procedure TX2GraphicContainer.ConvertGraphics(Reader: TReader);
var
graphics: TCollection;
graphicIndex: Integer;
graphicItem: TDeprecatedGraphicItem;
begin
graphics := TCollection.Create(TDeprecatedGraphicItem);
try
if Reader.NextValue = vaCollection then
begin
FConversionRequired := True;
Clear;
Reader.ReadValue;
Reader.ReadCollection(graphics);
for graphicIndex := 0 to Pred(graphics.Count) do
begin
graphicItem := TDeprecatedGraphicItem(graphics.Items[graphicIndex]);
{ Note: this create the item just fine, but won't add a line to the
form's definition; the designer can take care of that. }
with TX2GraphicContainerItem.Create(Self) do
begin
Picture := graphicItem.Picture;
PictureName := graphicItem.Name;
Container := Self;
end;
end;
end;
finally
FreeAndNil(graphics);
end;
end;
procedure TX2GraphicContainer.AddGraphic(const AGraphic: TX2GraphicContainerItem);
var
graphicIndex: Integer;
listIndex: Integer;
begin
graphicIndex := GraphicsList.Add(AGraphic);
AGraphic.InternalSetContainer(Self);
AGraphic.FreeNotification(Self);
for listIndex := Pred(Lists.Count) downto 0 do
TX2GraphicList(Lists[listIndex]).AddImage(graphicIndex);
end;
procedure TX2GraphicContainer.RemoveGraphic(const AGraphic: TX2GraphicContainerItem);
var
graphicIndex: Integer;
listIndex: Integer;
begin
graphicIndex := AGraphic.Index;
if graphicIndex > -1 then
begin
for listIndex := Pred(Lists.Count) downto 0 do
TX2GraphicList(Lists[listIndex]).DeleteImage(graphicIndex);
GraphicsList.Delete(graphicIndex);
AGraphic.InternalSetContainer(nil);
end;
end;
procedure TX2GraphicContainer.UpdateGraphic(const AGraphic: TX2GraphicContainerItem);
var
graphicIndex: Integer;
listIndex: Integer;
begin
graphicIndex := AGraphic.Index;
if graphicIndex > -1 then
begin
for listIndex := Pred(Lists.Count) downto 0 do
TX2GraphicList(Lists[listIndex]).UpdateImage(graphicIndex);
end;
end; end;
procedure TX2GraphicContainer.RegisterList(const AList: TX2GraphicList); procedure TX2GraphicContainer.RegisterList(const AList: TX2GraphicList);
begin begin
if FLists.IndexOf(AList) = -1 then if Lists.IndexOf(AList) = -1 then
FLists.Add(AList); begin
Lists.Add(AList);
AList.FreeNotification(Self);
end;
end; end;
procedure TX2GraphicContainer.UnregisterList(const AList: TX2GraphicList); procedure TX2GraphicContainer.UnregisterList(const AList: TX2GraphicList);
begin begin
FLists.Remove(AList); if Lists.Remove(AList) > -1 then
AList.RemoveFreeNotification(Self);
end; end;
procedure TX2GraphicContainer.SetGraphics(const Value: TX2GraphicCollection);
function TX2GraphicContainer.GetGraphicCount(): Integer;
begin begin
FGraphics.Assign(Value); Result := GraphicsList.Count;
end;
function TX2GraphicContainer.GetGraphics(Index: Integer): TX2GraphicContainerItem;
begin
Result := TX2GraphicContainerItem(GraphicsList[Index]);
end;
procedure TX2GraphicContainer.SetGraphics(Index: Integer; const Value: TX2GraphicContainerItem);
begin
TX2GraphicContainerItem(GraphicsList[Index]).Assign(Value);
end; end;
@ -600,7 +850,7 @@ begin
if not Assigned(FContainer) then if not Assigned(FContainer) then
exit; exit;
if (AIndex < 0) or (AIndex >= FContainer.Graphics.Count) then if (AIndex < 0) or (AIndex >= FContainer.GraphicCount) then
exit; exit;
if (not Assigned(FContainer.Graphics[AIndex].Picture.Graphic)) or if (not Assigned(FContainer.Graphics[AIndex].Picture.Graphic)) or
@ -669,8 +919,8 @@ begin
end; end;
procedure TX2GraphicList.CreateImage(const AIndex: Integer; procedure TX2GraphicList.BuildImage(const AIndex: Integer;
var AImage, AMask: TBitmap); const AImage, AMask: TBitmap);
function RGBTriple(const AColor: TColor): TRGBTriple; function RGBTriple(const AColor: TColor): TRGBTriple;
var var
cColor: Cardinal; cColor: Cardinal;
@ -707,13 +957,11 @@ var
begin begin
if not FConvert then if not FConvert then
begin begin
AImage := TBitmap.Create();
AImage.Width := Self.Width; AImage.Width := Self.Width;
AImage.Height := Self.Height; AImage.Height := Self.Height;
AImage.Canvas.Brush.Color := clWhite; AImage.Canvas.Brush.Color := clWhite;
AImage.Canvas.FillRect(Rect(0, 0, AImage.Width, AImage.Height)); AImage.Canvas.FillRect(Rect(0, 0, AImage.Width, AImage.Height));
AMask := TBitmap.Create();
AMask.Assign(AImage); AMask.Assign(AImage);
exit; exit;
end; end;
@ -826,7 +1074,7 @@ begin
bmpImage := TBitmap.Create(); bmpImage := TBitmap.Create();
bmpMask := TBitmap.Create(); bmpMask := TBitmap.Create();
try try
CreateImage(AIndex, bmpImage, bmpMask); BuildImage(AIndex, bmpImage, bmpMask);
Assert(AIndex <= Self.Count, 'AAAH! Images out of sync! *panics*'); Assert(AIndex <= Self.Count, 'AAAH! Images out of sync! *panics*');
if AIndex = Self.Count then if AIndex = Self.Count then
@ -859,7 +1107,7 @@ begin
bmpImage := TBitmap.Create(); bmpImage := TBitmap.Create();
bmpMask := TBitmap.Create(); bmpMask := TBitmap.Create();
try try
CreateImage(AIndex, bmpImage, bmpMask); BuildImage(AIndex, bmpImage, bmpMask);
Replace(AIndex, bmpImage, bmpMask); Replace(AIndex, bmpImage, bmpMask);
finally finally
FreeAndNil(bmpMask); FreeAndNil(bmpMask);
@ -897,7 +1145,7 @@ begin
if not Assigned(FContainer) then if not Assigned(FContainer) then
exit; exit;
for iIndex := 0 to FContainer.Graphics.Count - 1 do for iIndex := 0 to Pred(FContainer.GraphicCount) do
AddImage(iIndex); AddImage(iIndex);
finally finally
EndUpdate(); EndUpdate();
@ -998,7 +1246,30 @@ begin
Dec(FUpdateCount); Dec(FUpdateCount);
end; end;
{ TDeprecatedGraphicItem }
constructor TDeprecatedGraphicItem.Create(Collection: TCollection);
begin
inherited;
FPicture := TPicture.Create();
end;
destructor TDeprecatedGraphicItem.Destroy();
begin
FreeAndNil(FPicture);
inherited;
end;
procedure TDeprecatedGraphicItem.SetPicture(const Value: TPicture);
begin
FPicture.Assign(Value);
end;
initialization
RegisterClass(TX2GraphicContainerItem);
end. end.

View File

@ -11,7 +11,6 @@ uses
Menus, Menus,
PNGImage, PNGImage,
ToolWin, ToolWin,
IconXP,
X2CLGraphicList; X2CLGraphicList;
type type