Jump to content

RaelB

Members
  • Content Count

    72
  • Joined

  • Last visited

Posts posted by RaelB


  1. Hi,

     

    I create object list collections as below:

     

      TNotes = class(TObjectList<TNote>)
      public
        ...
      end;
      
      TBooks = class(TObjectList<TBook>)
      public
        ...
      end; 
      
      etc..

    Is there a way I can write some generic code that will be able to take in TNotes or TBooks instances, for e.g.:

    function ListToJSONString(List: TObjectList<T>): string;
    begin
    ...
    end;

    I want to call as:

      s := ListToJSONString(FNotes) or

      s := ListToJSONString(FBooks)

     

    But the function does not compile...

     

    Can such a function be declared, or do I need to change my definition of TNotes and TBooks?

     

    (I don't like using TObjectList<TNote> or TObjectList<TBook> in my code, since I want to create local (i.e. public) methods for each list type, and it is also simpler writing TNotes instead of TObjectList<TNote> each time)

     

    Thanks


  2. Is using "TJSON.ObjectToJsonObject" to convert an object into a TJSONValue (and ultimately into a string).

    Is it possible for this conversion to leave out a specific field/fields, for e.g. using some type of attribute?

     

    For example:

      TPersistItem = class(TPersistent)
      private
        FChangeStatus: TChangeStatus;
        FId: Variant;
        FLoading: Boolean;
        procedure SetId(const Value: Variant);
      protected
    ...
        procedure SetChangeStatus(const Value: TChangeStatus);
      public
    ...
      published
        property ChangeStatus: TChangeStatus read FChangeStatus write SetChangeStatus;
        property Id: Variant read FId write SetId;
      end;

    I don't want fields "ChangeStatus" and "Loading" to be included in the result.

     

    Thanks


  3. Hi,

    I ask this question because I don't have 2 monitors so I can't test this for myself.

    Is moving from Per Monitor V1 to Per Monitor V2 "only good and no bad", or does one need to take care of certain things when making the move?

    By "only good and no bad", I mean there will be advantages, however, if certain V2 related events are not handled, the behaviour will default to V1 behaviour..

    Thanks

    Rael


  4. On 9/17/2021 at 3:45 PM, dummzeuch said:

    ...  And not just for 10 projects but for about 50 (not all of these active at the same time, of course). That's nothing I need to imagine, that's my actual working environment.

    So how do you manage working in an IDE with all those different lib versions?

     

    - Do you use specific IDE's for specific projects?

    - Are you using any tools to help you with that?..

     

    Peter Below, once told me this:

    Quote

    It is possible to create project-specific IDE configurations if you really run into performance problems and the project in question really needs only a subset of your complete component set. You can disable specific design-time packages on a per-project basis, for instance. That does not solve the long search path (and browsing path, more relevant for code insight etc.) issue, though. But you can create a copy of the IDE's registry key tree (the one under HKEY_CURRENT_USER/Software) under a new key name, modify that to only get the packages needed for the project mentioned on the IDE pathes, and start the IDE with the -r command line parameter to make it use this key instead of the default. This requires a bit of fiddling with regedit, but can pay off if you have to maintain several big projects in parallel. You would have then one shortcut to the IDE for each of the projects and use the appropriate one to load a project with the associated component set.

    Perhaps you are using this idea..


  5. Hello,

     

    I have opened an old open source project in the IDE (10.3), and breakpoints seem to have been disabled for this project.

     

    image.thumb.png.553ff3cd220f0ea1b70e1d6bfc74f564.png

     

    Q1. How can I re-enable breakpoints?

    In "Linking" I have set "Debug Information" = True, and "Map file" = Detailed. What other setting is relevant here?

     

    Q2. Another thing is that whenever an error occurs, the IDE goes straight to CPU view. How do I revert to the usual behaviour of going to the line of code where the error occurred?

     

    Thanks

    Rael

     


  6. Hi,

    I'm using 15.0.33. If I change to Dark Theme, and then back to Light theme, the members area remains dark:

    image.thumb.png.e72dda1d3f4fb1d3cc98004acb821b02.png

     

    If there are members, they will fill up the box with the correct theme, but there is still an area left in dark theme:

     

    image.png.6ee70a4d7fed241dc52f108f24e38839.png

     

    I'm using Delphi 10.3.2

    Thanks

     

     


  7. Hello,

     

    I have been using the IdCoderTNEF unit to decode winmail.dat messages. This has worked fine for me in the past, however in the last couple of months, I have been receiving this error when trying to parse such messages:

     

    EIdTnefUnknownMapiType: Encountered unknown MAPI type: 72, attribute: 32768

     

    I am using the latest version of IdCoderTNEF  from the github repo (Latest commit 5fb9225 on 26 Nov 2019 )

     

    Part of my code looks like this:

     

      var
        J: Integer;
        TnefMsg: TIdMessage;
        TNefCoder: TIdCoderTNEF;
        
      begin
      
      ....
            for J := 0 to IdMessage.MessageParts.Count - 1 do
          begin
            if IdMessage.MessageParts[J] is TIdText then
              ....
    
            if IdMessage.MessageParts[J] is TIdAttachment then
            begin
    ...
              TNefCoder := TIdCoderTNEF.Create;
              try
                if TNefCoder.IsFilenameTnef(IdMessage.MessageParts[J].FileName) then
                begin
                  TnefMsg := TIdMessage.Create(nil);
                  try
                    TNefCoder.Parse(IdMessage.MessageParts[J] as TIdAttachment, TNefMsg);
                    ProcessMessage(TNefMsg);
                  finally
                    TnefMsg.Free;
                  end;
                end
                else
                  SaveMessagePart(IdMessage, IdMessage.MessageParts[J], UserName);
              finally
                TNefCoder.Free;
              end;
            end;
          end;
      ....

    Are you aware of such an issue?

    Thanks


  8. Hi,

    I have a simple pipeline, that takes in a list of 20 items, and has one stage. For each item, the stage waits 1 second, and then sends a message to the main UI, which will add the item to a Memo, and update a ProgressBar.

     

    The code is looking like this:

    procedure TForm1.AddDownloadItems;
    var
      DownloadItem: TDownloadItem;
      I: Integer;
    begin
      for I := 0 to 19 do
      begin
        DownloadItem := TDownloadItem.Create;
        DownloadItem.Id := I;
        FDownloadItems.Add(DownloadItem);
      end;
    end;
    
    procedure TForm1.Stage1(const input, output: IOmniBlockingCollection; const
      Task: IOmniTask);
    var
      Item: TDownloadItem;
      InputItem: TOmniValue;
    begin
      for InputItem in Input do
      begin
        Item := TDownloadItem(InputItem.AsObject);
        Sleep(1000);
        Task.Comm.Send(0, Item.Id);
        Output.Add(InputItem);
      end;
    end;
    
    procedure TForm1.UpdateProgress(const task: IOmniTaskControl; const msg: TOmniMessage);
    begin
      Inc(Progress);
      Memo1.Lines.Add(msg.MsgData.AsString);
      ProgressBar1.Position := Progress;
    end;
    
    procedure TForm1.GetDownloadsPipline;
    var
      Item: TDownloadItem;
    begin
      { ====== Start Pipeline ========= }
    
      Screen.Cursor := crHourGlass;
      StartTime := GetTickCount;
      FPipeline := Parallel.Pipeline
        .Stage(Stage1, Parallel.TaskConfig.OnMessage(UpdateProgress)).NumTasks(4) //Environment.Process.Affinity.Count)
        .OnStop(
          procedure
          begin
            PostMessage(Form1.Handle, WM_STOPPED, 0, 0);
          end)
        .Run;
    
      Self.AddDownloadItems;
      for Item in FDownloadItems do
        FPipeline.Input.Add(Item);
      FPipeline.Input.CompleteAdding;
    end;

    When the program runs, a few items get added to the Memo, and only afterwards the progressbar updates. This seems strange. I would expect the progress bar to update simultaneously with the memo. Please see attached video. Any ideas?

     

    Thanks

     

     

     


  9. Thanks all for the suggestions. The DDetours library was really helpful in this situation (in combination with logging), and helped me locate the problem fairly easily.

    On 1/10/2021 at 8:43 PM, Kas Ob. said:

    The thing is you need CloseHandle to pair up each create with close, but CloseHandle might be tricky as it is used with many handle types, so by only tracking CreateFile, you can find the last one succeeded in opening/creating the file and didn't close its handle yet.

    Yeah not that tricky. I just used a TStringList to keep track of opened files (i.e. Handles) and only logged calls to CloseHandle that had an entry in the stringlist (and then removed them..)

×