1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
{
*****************************************************************************
See the file COPYING.modifiedLGPL.txt, included in this distribution,
for details about the license.
*****************************************************************************
Author:
Joost van der Sluis
Abstract:
Change the resource type (e.g. .lfm) of forms.
Every unit can have one resource file. Default is .lfm.
This unit allows to define other formats, like .xib.
}
unit UnitResources;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, LCLMemManager, Forms, LResources;
type
{ TUnitResourcefileFormat }
TUnitResourcefileFormat = class
public
class function FindResourceDirective(Source: TObject): boolean; virtual; abstract;
class function GetUnitResourceFilename(AUnitFilename: string; Loading: boolean): string; virtual; abstract;
class procedure TextStreamToBinStream(ATxtStream, ABinStream: TExtMemoryStream); virtual; abstract;
class procedure BinStreamToTextStream(ABinStream, ATxtStream: TExtMemoryStream); virtual; abstract;
class function GetClassNameFromStream(s: TStream; out IsInherited: Boolean): shortstring; virtual; abstract;
class function CreateReader(s: TStream; var DestroyDriver: boolean): TReader; virtual; abstract;
class function CreateWriter(s: TStream; var DestroyDriver: boolean): TWriter; virtual; abstract;
class function QuickCheckResourceBuffer(
PascalBuffer, LFMBuffer: TObject; // TCodeBuffer
out LFMType, LFMComponentName, LFMClassName: string;
out LCLVersion: string;
out MissingClasses: TStrings// e.g. MyFrame2:TMyFrame
): TModalResult; virtual; abstract;
class function Priority: integer; virtual; // higher priority is tested first
class function DefaultComponentClass: TComponentClass; virtual;
class function FindComponentClass({%H-}aClassName: string): TComponentClass; virtual;
end;
TUnitResourcefileFormatClass = class of TUnitResourcefileFormat;
TUnitResourcefileFormatArr = array of TUnitResourcefileFormatClass;
{ TCustomLFMUnitResourceFileFormat }
TCustomLFMUnitResourceFileFormat = class(TUnitResourcefileFormat)
public
class function ResourceDirectiveFilename: string; virtual;
class function GetUnitResourceFilename(AUnitFilename: string; {%H-}Loading: boolean): string; override;
class procedure TextStreamToBinStream(ATxtStream, ABinStream: TExtMemoryStream); override;
class procedure BinStreamToTextStream(ABinStream, ATxtStream: TExtMemoryStream); override;
class function GetClassNameFromStream(s: TStream; out IsInherited: Boolean): shortstring; override;
class function CreateReader(s: TStream; var DestroyDriver: boolean): TReader; override;
class function CreateWriter(s: TStream; var DestroyDriver: boolean): TWriter; override;
class function DefaultComponentClass: TComponentClass; override;
class function FindComponentClass(aClassName: string): TComponentClass; override;
end;
var
LFMUnitResourceFileFormat: TUnitResourcefileFormatClass = nil;// set by IDE
procedure RegisterUnitResourcefileFormat(AResourceFileFormat: TUnitResourcefileFormatClass);
function GetUnitResourcefileFormats: TUnitResourcefileFormatArr;
implementation
uses
FormEditingIntf;
var
GUnitResourcefileFormats: TUnitResourcefileFormatArr;
procedure RegisterUnitResourcefileFormat(AResourceFileFormat: TUnitResourcefileFormatClass);
var
i: Integer;
Priority: Integer;
l: Integer;
begin
Priority:=AResourceFileFormat.Priority;
i:=0;
while (i<length(GUnitResourcefileFormats))
and (GUnitResourcefileFormats[i].Priority>=Priority) do
inc(i);
l:=length(GUnitResourcefileFormats)-i;
SetLength(GUnitResourcefileFormats, length(GUnitResourcefileFormats)+1);
if l>0 then
System.Move(GUnitResourcefileFormats[i],GUnitResourcefileFormats[i+1],
l*SizeOf(TUnitResourcefileFormatClass));
GUnitResourcefileFormats[high(GUnitResourcefileFormats)] := AResourceFileFormat;
end;
function GetUnitResourcefileFormats: TUnitResourcefileFormatArr;
begin
Result := GUnitResourcefileFormats;
end;
{ TCustomLFMUnitResourceFileFormat }
class function TCustomLFMUnitResourceFileFormat.ResourceDirectiveFilename: string;
// Note: $R uses fpcres, which supports only a few formats like dfm and lfm.
// In other words: If you want other formats you need to extend fpcres or use
// other storages like include files (e.g. like the old lrs format).
begin
Result := '*.lfm';
end;
class function TCustomLFMUnitResourceFileFormat.GetUnitResourceFilename(
AUnitFilename: string; Loading: boolean): string;
begin
Result := ChangeFileExt(AUnitFilename,'.lfm');
end;
class procedure TCustomLFMUnitResourceFileFormat.TextStreamToBinStream(ATxtStream,
ABinStream: TExtMemoryStream);
begin
LRSObjectTextToBinary(ATxtStream,ABinStream);
end;
class procedure TCustomLFMUnitResourceFileFormat.BinStreamToTextStream(ABinStream,
ATxtStream: TExtMemoryStream);
begin
LRSObjectBinaryToText(ABinStream,ATxtStream);
end;
class function TCustomLFMUnitResourceFileFormat.GetClassNameFromStream(s: TStream;
out IsInherited: Boolean): shortstring;
begin
Result := GetClassNameFromLRSStream(s,IsInherited);
end;
class function TCustomLFMUnitResourceFileFormat.CreateReader(s: TStream;
var DestroyDriver: boolean): TReader;
begin
Result := CreateLRSReader(s,DestroyDriver);
end;
class function TCustomLFMUnitResourceFileFormat.CreateWriter(s: TStream;
var DestroyDriver: boolean): TWriter;
begin
Result := CreateLRSWriter(s, DestroyDriver);
end;
class function TCustomLFMUnitResourceFileFormat.DefaultComponentClass: TComponentClass;
begin
Result := FormEditingHook.StandardDesignerBaseClasses[DesignerBaseClassId_TForm];
end;
class function TCustomLFMUnitResourceFileFormat.FindComponentClass(
aClassName: string): TComponentClass;
begin
if CompareText(aClassName,'TForm')=0 then
Result:=FormEditingHook.StandardDesignerBaseClasses[DesignerBaseClassId_TForm]
else if CompareText(aClassName,'TFrame')=0 then
Result:=FormEditingHook.StandardDesignerBaseClasses[DesignerBaseClassId_TFrame]
else if CompareText(aClassName,'TDataModule')=0 then
Result:=FormEditingHook.StandardDesignerBaseClasses[DesignerBaseClassId_TDataModule]
else
Result:=nil;
end;
{ TUnitResourcefileFormat }
class function TUnitResourcefileFormat.Priority: integer;
begin
Result:=0;
end;
class function TUnitResourcefileFormat.DefaultComponentClass: TComponentClass;
begin
Result:=TForm;
end;
class function TUnitResourcefileFormat.FindComponentClass(aClassName: string): TComponentClass;
begin
Result:=nil;
end;
end.
|