Delphi 7中有没有办法在设计时通过项目将特定类型的所有组件的属性设置为特定值?
我已使用GExperts将我的TQuery
替换为TADOQuery
,但需要相应地设置连接字符串。
我尝试过使用GExperts“设置组件属性”,但这似乎不适用于连接属性。
我想在.dfm文件中进行搜索和替换,但是在手动设置之前,连接属性不会存储在.dfm文件中。
答案 0 :(得分:1)
首先,将所有查询链接到TADOConnection
会更明智,并仅在该组件上指定连接字符串。连接字符串在开发过程中可能会发生一些变化,更不用说它可能会从客户端更改为客户端。在每个TADOQuery
上使用它等同于对其进行硬编码。这不是一个好主意。
其次,给它一个好的想法,使用grep工具检查你已经获得的TADOQuery
组件的实际数量。没有任何工具可以手动执行此操作:不能代替他人,但我确定我宁愿手动更改100个查询,然后使用工具。即使您使用工具,您仍然需要检查所有DFM,以确保它们仍处于正常工作状态。这需要您在IDE中打开它们。
最后,由于没有自动执行此操作的方法,这个问题的答案就不会完整,这是一个简单的方法。
这是一个简短的过程,它采用DFM文件的名称,组件类的名称以及DFM中所需的值。它会查找值并确保属性具有给定名称。如果该属性不存在,则添加该属性。你会这样使用它:
FixComponentPropertyInDFM('Unit16.dfm', 'TPanel', 'Caption', '''Changed Caption''');
代码,不使用正则表达式来确保它在Delphi 7中编译。一半代码处理DFM文件中的识别模式,因此使用正则表达式会使代码大小为1/4
procedure FixComponentPropertyInDFM(const FileName:string; const ClassName, PropertyName, RequiredValue: string);
var L: TStringList;
i,j, iEnd, iLine: Integer;
ExtraObjectCount: Integer;
cLine, trimedLine, TestLine: string;
lcSufixString: string;
lcSufixLen: Integer;
lcPropertyPrefix: string;
lcPropertyPrefixLen: Integer;
DelphiId: AnsiString;
ValidId: Boolean;
CorrectLineValue: string;
ChangedTheDFM: BOolean;
begin
lcSufixString := LowerCase(': ' + ClassName);
lcSufixLen := Length(lcSufixString);
lcPropertyPrefix := LowerCase(PropertyName + ' =');
lcPropertyPrefixLen := Length(lcPropertyPrefix);
CorrectLineValue := PropertyName + ' = ' + RequiredValue;
ChangedTheDFM := False;
L := TStringList.Create;
try
L.LoadFromFile(FileName);
i := 0;
while i < L.Count do
begin
cLine := L[i];
// Is the current line of the form [object Name: ClassName] ?
if (Length(cLine) > lcSufixLen) and (LowerCase(System.Copy(cLine, Length(cLine)-lcSufixLen+1, lcSufixLen)) = lcSufixString) then
begin
// This line is most likely the start of an object definition, of the type I want.
// Check this further: does it start with "object"?
trimedLine := Trim(cLine);
if LowerCase(System.Copy(trimedLine, 1, 7)) = 'object ' then
begin
// Further checks. Doesn't hurt to be extra-safe.
System.Delete(trimedLine, 1, 7);
System.Delete(trimedLine, Length(trimedLine) - lcSufixLen+1, System.MaxInt);
trimedLine := Trim(trimedLine);
// What's left should be a valid Identifier. Also check that!
DelphiId := AnsiString(trimedLine); // I'm writing this on Delphi2010, but I want the code to compile on Delphi 7; And I want to use the "char-in-set"
if (Length(DelphiId) > 0) and (DelphiId[1] in ['a'..'z', 'A'..'Z', '_']) then
begin
ValidId := True;
for j:=2 to Length(DelphiId) do
if not (DelphiId[j] in ['a'..'z', 'A'..'Z', '_', '0'..'9']) then
ValidId := False;
if ValidId then
begin
// This line passed all tests. I know *for sure* an object definition of the required class starts here.
iLine := -1; // Line where the property definition was found in the DFM
iEnd := -1; // Line where the "end" that finishes the definition was found
ExtraObjectCount := 0; // Counts the depth for the extra objects we might find.
j := i+1;
while (iEnd = -1) and (j < L.Count) do
begin
TestLine := LowerCase(Trim(L[j]));
if System.Copy(TestLine, 1, 7) = 'object ' then Inc(ExtraObjectCount)
else if System.Copy(TestLine, 1, 10) = 'inherited ' then Inc(ExtraObjectCount)
else if TestLine = 'end' then
begin
// I'm seeing the end of an object. Don't know if it's *our* object
// or some other object.
Dec(ExtraObjectCount);
if ExtraObjectCount = -1 then iEnd := j; // Our object.
end
else if ExtraObjectCount = 0 then
begin
// We know we're within our object, not some embeded object.
if System.Copy(TestLine, 1, lcPropertyPrefixLen) = lcPropertyPrefix then
iLine := j;
end;
// Next line
Inc(j);
end;
// Alter the DFM!
if iLine = -1 then
begin
// Did not find the line.
if iEnd = -1 then raise Exception.Create('BUG: Did not find "end"');
L.Insert(iEnd, CorrectLineValue);
ChangedTheDFM := True;
end
else
begin
// Found the value.
if Trim(L[iLine]) <> CorrectLineValue then
begin
L[iLine] := CorrectLineValue;
ChangedTheDFM := True;
end;
end;
end;
end;
end;
end;
// Next line
Inc(i);
end;
if ChangedTheDFM then
begin
// Make a backup of the original DFM.
if FileExists(FileName + '.backup') then
raise Exception.Create(FileName + '.backup already exists.');
if not CopyFile(PChar(FileName), PChar(string(FileName + '.backup')), True) then
raise Exception.Create('Can''t create BACKUP file.');
L.SaveToFile(FileName);
end;
finally L.Free;
end;
end;