Jump to content

PolywickStudio

Members
  • Content Count

    18
  • Joined

  • Last visited

Posts posted by PolywickStudio


  1. Andy's VCL Fix Pack is a Delphi open-source unit that fixes VCL and RTL issues at runtime by patching the original functions.

     

    Andy's Unit contains easy-to-use functions to update code that cannot be easily recompiled or changed.



    If you try to change VCL sources (files in Source folder of your RadStudio, Delphi or C++ Builder installation) and attempt to recompile them within your project, you'll get multiple errors, such as: DCU mismatch, (file1.pas) is compiled with a newer version of (file2.pas). This occurs when source-code is compiled with a different file and needs to be fully recompiled.


    In the below example, I will use Andy's fix pack to fix a long standing bug - QC15408.

     


    Without fix:

    QC15408_NORMAL.png.edf6d5c61887bbc3433c98951b2d3031.png



    With fix:
    QC15408_FIX.png.3e4ec50fc2e2e95f716f314571086a9a.png

     


    Repository:

    https://github.com/PolywickStudio/AndyVCLFIXPack

     

     

    • Like 1

  2. I operate a small business doing Delphi coding and work-for-hire.


    My services are:

    • App modernization, legacy upgrades. From Delphi 1 (Windows 3.1) to Delphi XE 12.1
      See: Case Studies

     

    • I’ve personally developed on C++ UI components, newer Delphi Skia-based components.

     

    • New application development (UI work, coding).



    You can choose from different team options:

     

    • Dedicated team - need a team?

     

    • Staff augmentation (developers on-and-off basis),
       
    • Outsourcing (such as, 3 hours a week, Once a month to update Delphi app)



    What you get:

     

    • Full source-code in Github/ Gitlab/ BitBucket / Azure repository.
       
    • CI/CD build (where applicable), so when there's check-in, a build is made.
       
    • Markdown documented and unit tested code. Optional profiling project if code is slow.
       
    • Warranty (if there's a small fix it'll get fixed).



    I'm top-rated on Upwork and on Embarcadero Blogs.


     

    My website and contact form.
     


  3. Here's the distilled Delphi code:

    unit exampleunit;
    interface
    uses
      Windows,
      Messages,
      SysUtils,
      Classes,
      VCL.Graphics,
      VCL.Controls,
      VCL.Forms,
      VCL.Dialogs,
      VCL.StdCtrls,
      VCL.Buttons;
    
    type
      TExample = class(TCustomControl)
      protected
        procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE;
      end;
    
    procedure Register;
    implementation
    
    
    procedure TExample.WMMouseMove(var Message: TWMMouseMove);
    begin
    //
      inherited;
    end;
    
    procedure Register;
    begin
      RegisterComponents('Samples', [TExample]);
    end;
    
    end.

    Here's the C++ code. C++ Builder is, supposed to be the equivalent of Delphi, and should allow for C++-only VCL components. In reality, all the development goes one way. Delphi exported components to C++ Builder.

    Here's the C++ Builder component:

    //---------------------------------------------------------------------------
    #ifndef examplecomponentcppH
    #define examplecomponentcppH
    //---------------------------------------------------------------------------
    #include <System.Classes.hpp>
    #include <System.SysUtils.hpp>
    #include <Vcl.Controls.hpp>
    #include <Vcl.ExtCtrls.hpp>
    
    class PACKAGE TExampleCpp : public TCustomControl {
    private:
    
    protected:
      void WMMouseMove(TWMMouseMove Message);
    public:
      __fastcall TExampleCpp(TComponent *Owner);
      __fastcall virtual ~TExampleCpp();
    
    };
    #endif
    
    //---------------------------------------------------------------------------
    #pragma hdrstop
    #include "examplecomponentcpp.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    
    __fastcall TExampleCpp::TExampleCpp(TComponent *Owner)
    	: TCustomControl(Owner) {
    }
    
    __fastcall TExampleCpp::~TExampleCpp()
    {
    }
    
    void TExampleCpp::WMMouseMove(TWMMouseMove Message) {
      // what to put here that is equivalent of the Delphi version?
      TCustomControl::WMMouseMove(Message);
    }
    
    static inline void ValidCtrCheck(TExampleCpp *) { new TExampleCpp(NULL); }
    
      

    There is "inherited." It's called __super https://stackoverflow.com/questions/8326309/borland-delphi-alternative-to-super-keyword or (baseclass)::(procedure).

     


    The question is.
    In Delphi, the inherited keyword works and causes the code to go to a private procedure in controls.pas. This beaks the cannot call private procedures and functions compiler restriction in Delphi. Which is enforced in Delphi.

    In C++ Builder, it bugs out and [bcc32c Error] examplecomponentcpp.cpp(17): 'WMMouseMove' is a private member of 'Vcl::Controls::TControl'  Vcl.Controls.hpp(1655): declared private here


    Why is inherited keyword not supported in C++ Builder? Does that mean, it becomes impossible to build components in C++ Builder? the same code that compiles and works, in Delphi, cannot be done in C++ Builder?

    Why is it, the same Delphi code, exports as a C++ Builder component works in C++ Builder? When you try to do the same thing in C++ Builder, it becomes impossible, or there are no code samples.


    > You need to call the base class Dispatch() method. Or override the virtual WndProc() method instead of using a MESSAGE_MAP
    Can you show a complete example?

     


  4. In the Delphi code, I did the same, create a component from TCustomControl. I add WMMouseMove windows message

    procedure TCustomControlButton.WMMouseMove(var Message: TWMMouseMove);
    begin
      //
      inherited; // how to emulate this keyword and call base class's WMMouseMove in C++ Builder?
    end;
    
    

    In C++ Builder, I am trying to build a VCL C++ Builder component. I sub-class TCustomControl. However, I cannot seem to do the same equivalent in C++ Builder. "inherited". What should I do to solve this problem?

    void __fastcall TCustomControlButton::WMMouseMove(
        Winapi::Messages::TWMMouse &Message) {
      
      // do something...
      
      TCustomControl::WMMouseMove(Message); // OR
      __super::WMMouseMove(Message);
    }
    
    I get:
    [bcc32c Error] something.cpp(300): 'WMMouseMove' is a private member of 'Vcl::Controls::TControl'. Vcl.Controls.hpp(1655): declared private here
    

  5. I've been doing some simple testing.

     

    Delphi 11.3

     

    2000000 TStringList.AddObject in 141.17ms (14,167,115.00/s)
    TStringList.Rehash in 1us
    TStringList.Clear in 47.36ms
    first TStringList.IndexOf in 7us
    20000 TStringList.IndexOf in 8.35s (2,392.00/s)

     

    2000000 TStringListHash.AddObject in 139ms (14,387,661.00/s)
    TStringListHash.Rehash in 0us
    TStringListHash.Clear in 46.22ms
    first TStringListHash.IndexOf in 275.24ms
    20000 TStringListHash.IndexOf in 5.60ms (3,570,790.00/s)
     

    2000000 TDictionary.AddObject in 788.58ms (2,536,188.00/s)
    TDictionary.Clear in 292.92ms
    20000 TDictionary.IndexOf in 3.24ms (6,172,839.00/s)

     

    Spring4D's IDictionary

    20000 IDictionary.Add in 3.38ms (5,917,159.00/s)
    first IDictionary.TryGetValue in 1us
    20000 IDictionary.TryGetValue in 753us (26,560,424.00/s)
     

    Use Spring?

     

    • Like 1

  6. On 3/17/2021 at 7:16 AM, Stefan Glienke said:

    As always you again seem to only read half of what I wrote.

     

    
    Base line (code as you posted) - running on an i5-3570K @ 3.4GHz
    
    Get Name from ID (Search by integer):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       46         397       60         23         48         59
       50       72         474       67         28         52         59
      100      105         504       62         32         51         59
    
    Get ID from Name (Search by string):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       21         373      106         11         25        107
       50      105         443      109         18         26        110
      100      204         487      104         23         29        103
    
    Use equalitycomparer from Tiny.Generics.pas for TDict and Spring - running on the i5-3570K @ 3.4GHz
    
    Get Name from ID (Search by integer):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       45         407       44         24         49         44
       50       71         468       42         27         48         42
      100       96         499       43         32         53         43
    
    Get ID from Name (Search by string):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       21         379       26         11         27         25
       50      106         445       25         18         27         25
      100      207         483       26         22         29         27
    
    Simply put "procedure Main;" after the CreateRandomData procedure and "end;begin Main;" before the end. - running on the i5-3570K @ 3.4GHz
    
    Get Name from ID (Search by integer):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       28         387       27         25         32         26
       50       51         455       25         28         32         24
      100       76         487       27         32         34         27
    
    Get ID from Name (Search by string):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       22         380       27         12         25         27
       50      105         446       24         18         28         24
      100      207         489       25         24         30         26
      
    Same code as before but running on an i7-8700 @ 3.2Ghz
    
    Get Name from ID (Search by integer):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       23         306       21         20         27         20
       50       42         355       22         24         28         20
      100       63         377       22         26         29         21
    
    Get ID from Name (Search by string):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       17         299       16          7         18         17
       50       72         359       16         13         19         17
      100      139         383       17         21         22         18
      
    Same code compiled with XE8 and also running on the i7-8700 @ 3.2GHz
    
    Get Name from ID (Search by integer):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       26         292       22         20         24         21
       50       65         342       22         23         26         21
      100      112         355       21         25         26         23
    
    Get ID from Name (Search by string):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       24         281       17          8         18         18
       50      116         331       18         13         20         18
      100      215         347       17         16         22         17
    

    Edit - for bonus points - I fixed the TArray.BinarySearch case by using an IComparer that I prepared and stored as field because that a) solves the return stack buffer glitch caused my TDelegatedComparer and b) avoids producing an anonymous method every time that method is being called. Also got rid of the CompareValue call in BinarySearchByID, can use < and >.

    Can I ask.

     

    Do you have the source-code for your changes you made?

     

    The source-code in this thread has only for the Sequenced, TArray.BinS, TDict and TSynDict,  not Spring.

     

    For CustomBinS, the hash routine often access violation 'out of range' and not suitable for larger arrays...

     

    On 3/17/2021 at 7:16 AM, Stefan Glienke said:
    
    Running on the i5-3570k @ 3.4Ghz
    
    Get Name from ID (Search by integer):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       26          64       25         21         31         27
       50       52          73       26         23         32         30
      100       77          84       25         23         34         25
    
    Get ID from Name (Search by string):
    records Sequenced  TArray.BinS  TDict  CustomBinS  TSynDict     Spring
       10       22          63       25         11         27         27
       50      105          81       24         18         27         26
      100      205          94       24         22         29         27

     

     


  7. Let's say you have a set of repeat numbers:

     

     TDictionary<integer1, TDicationary<integer2, integer3>>

     

    [1, [2, 1]]

    [1, [1, 2]]

    [1, [1, 3]]

    (huge... like 30000)

    [2, [2, 1]]

    [2, [1, 2]]

    [2, [1, 3]]

    ...

    [3, [2, 1]]

    [3, [1, 2]]

    [3, [1, 3]]

     

     

    What would be a fast way to select all numbers with

    [x, [x, 1]], then [x, [x, 2]] ?

     

     

    I do a loop but there must be a faster way than loop the loop.


  8. I have question.

     

    I need a data structure that looks like this:

     

    DataStructure<TKey1, TKey2, TValue, TPayLoad>

     

    Where

     

    - there the data is sorted by 2 keys.

    - the value can be any (e.g., integer, string).

    - there is a ternary Payload which stores non-sorted data.

     

    I want to the data to have 2 primary key indexes, TKey1 or TKey2.

     

    I query TKey1 = '1', I get all values of (TKey1 = 1) for the data.

    I query TKey2 = '2', I get all values of (TKey2 = 1) for the data.

     

    Problem.

    1. I use TDictionary and THashList, Not sure how to store TKey1, TKey2, and TValue1 with TPayLoad.

    I could use TDictionary<TPair<TKey1, TKey2>, TPair(TValue1, TPayload>);

    - how to search by partial, where I special only one part of TPair?

     

    2. I tried TObjectList, I cannot order by TKey2, just TKey1 and store everything inside an Object.

    It gets slow trying to do filtered-search and retrieve filtered by TKey1 or TKey2.

     

    3. I tried TList, but I want to get an order by TKey1 and TKey2, I need to keep sorting it as often.

     

    4. I need to keep TKey1, TKey2 as ordered lists to quickly index/query TValue.

     

    Any ideas?

     

     

     

     

     

     

     

     

     

     

     

     

     

     

×