Jump to content

Uwe Raabe

Members
  • Content Count

    2558
  • Joined

  • Last visited

  • Days Won

    150

Posts posted by Uwe Raabe


  1. Besides Interfaces there are also abstract classes to accomplish this.

    unit TestA;
    
    interface
    
    type
      TAbstractTestB = class
      public
        procedure Test; virtual; abstract;
      end;
    
      TTestA = class
      public
        M_TestB: TAbstractTestB;
        constructor Create;
      end;
    
    implementation
    
    uses
      TestB;
      
    constructor TTestA.Create;
    begin
      inherited Create;
      M_TestB := TTestB.Create;
    end.
    unit TestB;
    
    interface
    
    uses
      TestA;
    
    type
      TTestB = class (TAbstractTestB)
        M_TestA: TTestA;
      public
        procedure Test; override;
      end;
      
    implementation
    
    procedure TTestB.Test;
    begin
    end;
    
    end.

    Depending on where M_TestB is assigned, you assign either a TTestB instance or create one. You can even create that instance inside TTestA as you are allowed to use unit TestB in the implementation section of TestA as shown above. 

     

    Nevertheless I suggest to remove these cyclic class dependencies altogether, but the way to do so depends heavily on your use case and the framework you are using.


  2. There are several functions to simplify your task. You can use VarIsStr to check for string variants and VasIsOrdinal for the Integer case. Also there is VarToStr to convert a Variant to string.

     

    With this you can strip down your compare function to 

    function CompareValues(const aValue1, aValue2: Variant): integer; overload;
    Begin
      Result := 0;
      // if ANY of the values is string, should compare as strings!
      if VarIsStr(aValue1) or VarIsStr(aValue2) then
        Result := CompareValues(VarToStr(aValue1), VarToStr(aValue2))
      else if VarIsOrdinal(aValue1) and VarIsOrdinal(aValue2) then // Make sure that the following cast succeeds!
        Result := CompareValues(Integer(aValue1), Integer(aValue2));
    End;

     

    • Like 1

  3. It is indeed quite a while since I had to cope with BDE problems, so my suggestion might be pretty outdated now. Nevertheless you can give it a try as it is only a small change in the registry.

     

    What helped us in the past was disabling opportunistic locking at the server side (where the database files reside). For this you have to change the value of HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\EnableOplocks from 1 to 0 (as 1 is the default value, it might even be absent). Note that you have to restart Windows to make this change effective.

     

    A drawback of this setting is a possible overall network performance drop for that server system.

     

     

    • Like 2

  4. 6 hours ago, John Kouraklis said:

    How do I enable code coverage for all the methods? Looks like I have to visit each method and enable CCM

    Unfortunately, yes! Currently that is the only way to do that. I am aware that there is plenty of room for improvement in this plugin.

    • Like 1

  5. 5 hours ago, wuwuxin said:

    MMX editor context menu entry - still not available with the latest 14.0.4 version (Delphi RIO)?

    Unfortunately it is not easy to implement this. You will find the same problem with other IDE plugins trying to do the same. Unless someone finds a valid solution for this problem and is willing to share it I may need some time to invent something by myself.


  6. Well, the OTA contains a few special interfaces regarding themes and the Unit Dependency Analyzer was the first form (or better frame in this case) making use of those. What I didn't know (because as usual those things are poorly documented - if at all) is that it seems to be forbidden to call ApplyTheme when IDE themes are disabled. Not that this could as well be caught inside ApplyTheme (just for safety - instead of crashing), so that not everybody has to add this additional check in their code.

    • Like 3

  7. 1 hour ago, FPiette said:

    How to make the window not dockable?

    As long as the form is derived from TDockForm there is no way to make it not dockable (after all that is the main purpose of a TDockForm descendant). On the other hand you are not forced to dock it in the first place. The desktop functionality isn't affected from the docking state. To store the last position of the floating window in the desktop it is sufficient to make it visible once any time before saving. It is not necessary to dock the form for that.


  8. Seems you are looking for TTimeSpan:

     

    program Project458;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils,
      System.TimeSpan;
    
    var
      span: TTimeSpan;
    begin
      span := TTimeSpan.Subtract(EncodeDate(2018,1,2)+EncodeTime(16,35,0,0), EncodeDate(2018,1,1)+EncodeTime(15,30,0,0));
      Writeln(Format('%d Day(s) %d Hour(s) %d Minute(s)', [span.Days, span.Hours, span.Minutes]));
      Readln;
    end.

     

×