首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在设计时设置特定类型的所有组件的属性。

在设计时设置特定类型的所有组件的属性。
EN

Stack Overflow用户
提问于 2013-01-22 10:07:32
回答 1查看 1.1K关注 0票数 1

在Delphi 7中是否有方法在设计时将特定类型上的所有组件的属性设置为特定的值?

我使用GExperts将所有的TQuery替换为TADOQuery,但需要相应地设置连接字符串。

我尝试过使用GExperts“”,但这似乎不适用于connection属性。

我想在.dfm文件中进行搜索和替换,但是连接属性在手动设置之前不会存储在.dfm文件中。

EN

回答 1

Stack Overflow用户

发布于 2013-01-23 08:07:08

首先,将所有查询链接到TADOConnection并仅在该组件上指定连接字符串将更明智。在开发过程中,连接字符串可能会更改几次,更不用说它可能会在客户端到客户端之间发生变化。在每一个TADOQuery上使用它就相当于对其进行硬编码。那不可能是个好主意。

其次,好好考虑一下,使用grep工具来检查实际的TADOQuery组件数量。在没有任何工具的情况下,很有可能手工完成这一任务:不能代表其他人发言,但我确信我宁愿手动更改100个查询,然后再麻烦使用一个工具。即使您使用一个工具,您仍然需要检查所有的DFM,以确保它们仍然处于正常工作状态。这要求您在IDE中打开它们。

最后,由于如果没有自动的方法,这个问题的答案将是不完整的,这里有一个简单的方法。

下面是一个简短的过程,它接受DFM文件的名称、组件类的名称以及您在DFM中想要的值。它将查找该值并确保该属性具有给定的名称。如果该属性不存在,则添加该属性。你会像这样使用它:

代码语言:javascript
复制
FixComponentPropertyInDFM('Unit16.dfm', 'TPanel', 'Caption', '''Changed Caption''');

代码,而不是使用正则表达式来确保它在Delphi7中编译。一半的代码处理识别DFM文件中的模式,因此使用正则表达式将使代码1/4的大小。

代码语言:javascript
复制
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;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14455968

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档