Jump to content

David Hoyle

Members
  • Content Count

    184
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by David Hoyle


  1. Thank you @David Heffernan and @Eugine Savin.

    Clearly, I was too ambitious. I tried a few other things with generics and then abandoned them when they didn't work either.

    I decided to change the underlying coordinate system to Single from Integer and I'm using TPointF and TRectF and the real-time rendering in my application, even with VCL styles, does not seem to have diminished.

    Still need to test on an old machine with a crappy graphics card but I think this will allow me to do what I want going forwards.


  2. I'm trying to create a rending engine that can use different canvas's where the coordinate system could Integer or Single. This is so that the differences between the output systems can be abstracted at the canvas level.

    I've tried to used generics (see code below) but it will not compile. I don't know whether I'm trying to be too ambitious or whether I'm missing something.

    The below code is a test project that shows the issue. Any help would be appreciated.

    Note: The below code is not intended to run as it's missing some implementations, I'm just looking for it to compile.

    Program IndirectGenerics;
    
    {$APPTYPE CONSOLE}
    
    {$R *.res}
    
    uses
      System.SysUtils;
    
    Type
      IPen<T> = Interface
        Function  GetWidth : T;
        Procedure SetWidth(Const AValue : T);
        Property Width : T Read GetWidth Write SetWidth;
      End;
    
      ICanvas<T> = Interface
        Function GetPen : IPen<T>;
        Property Pen : IPen<T> Read GetPen;
      End;
    
      TConcreteCanvas<T> = Class(TInterfacedObject, ICanvas<T>)
      Strict Private
        FPen : IPen<T>;
      Strict Protected
        Function GetPen : IPen<T>;
      Public
        Constructor Create;
      End;
    
      TConcreteDrawingEngine<T> = Class
      Strict Private
        FCanvas : ICanvas<T>;
      Strict Protected
      Public
        Constructor Create(Const Canvas : ICanvas<T>);
        Procedure DoSomething;
      End;
    
    { TConcreteCanvas<T> }
    
    Constructor TConcreteCanvas<T>.Create;
    
    Begin
      // FPen := 
    End;
    
    Function TConcreteCanvas<T>.GetPen: IPen<T>;
    
    Begin
      Result := FPen;
    End;
    
    { TConcreteGantt<T> }
    
    Constructor TConcreteDrawingEngine<T>.Create(Const Canvas: ICanvas<T>);
    
    Begin
      FCanvas := Canvas;
    End;
    
    Procedure TConcreteDrawingEngine<T>.DoSomething;
    
    Begin
      FCanvas.Pen.Width := 1; // <= Does not compile as it thinks T is not Integer
    End;
    
    Var
      IntegerCanvas : ICanvas<Integer>;
      IntegerDrawingEngine : TConcreteDrawingEngine<Integer>;
      SingleCanvas : ICanvas<Single>;
      SingleDrawingEngine : TConcreteDrawingEngine<Single>;
    
    Begin
      Try
        IntegerCanvas := TConcreteCanvas<Integer>.Create;
        IntegerDrawingEngine := TConcreteDrawingEngine<Integer>.Create(IntegerCanvas);
        //...
        SingleCanvas := TConcreteCanvas<Single>.Create;
        SingleDrawingEngine := TConcreteDrawingEngine<Single>.Create(SingleCanvas);
        //...
      Except
        On E: Exception Do
          Writeln(E.ClassName, ': ', E.Message);
      End;
    
    End.

     


  3. I already do this with GExperts so I know it can be done unfortunately I'm on my work machine so cannot show you. The menu item is now hidden underneath View | Editor I think but it is there somewhere. I use Ctrl+Alt+D so I need to disable this shortcut first (disassembly view I think) and then I can assign it for Format Source.


  4. The \\?\UNC is for unicode path up to 32K in length so you can work around the MAX_PATH limit. I wouldn't expect ExtractFileDrive to work with these as you would add the \\?\UNC prefix before calling CopyFileW() etc.

    There is similar syntax for drive letter. 

    Have a look at the Microsoft Documentation (Looks like they've change something in Windows 10 recently as well - https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-copyfile

    • Like 1

  5. @Remy Lebeau you were right, I just didn't call it properly.

    The below code works for me in 10.4.1...

      // Set the control framework
      ActivateClassGroup(Vcl.Controls.TControl); // <= THIS FIXES IT!!!!!!!!!
      
      // Get the generic form editor for the current module
      Module := TACTFUtilities.CurrentModule;
      FormEditor := TACTFUtilities.FormEditor(Module);
    
      // Get the simple class name from a dropdown, i.e. TLabel, TButton, TEdit, etc
      strClassName := edtComponentClassName.Text;
      Delete(strClassName, Pos('=', strClassName), strClassName.Length);
    
      // Insert the component with the selected component parent
      If Assigned(FormEditor) Then
        Begin
          Component := FormEditor.GetCreateParent;
          Component := FormEditor.CreateComponent(
            Component,
            strClassName,
            10, 10, 50, 28
          );
          FormEditor.MarkModified;
        End;

     


  6. Okay, I'm leaning towards the issue being FMX verse VCL. I iterated all the packages below and picked out all the components and found duplicates between the frameworks.

    image.thumb.png.70a94052da6b7c6f0e8bde593ed4d919.png

    So I think GetClass() is looking up in FMX instead of VCL. Since it's now failing, selecting a VCL only component does nothing as GetClass() cannot find the component (which does not exist in FMX).

    Getting a bit late now but I know that on occasions the IDE prompts you to select which framework you are using (FMX or VCL) and I need to find out how we influence this determination (starting a new VCL app didn't work but then again I didn't save it).

×