Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 01/28/21 in all areas

  1. For all who want to try to get the DDevExtensions Delphi IDE plugin to work with Delphi 10.4 can now clone the DDevExtensions git repository. It contains the project files for Delphi 10.2 and 10.3. I'm not able to help with any Delphi 10.4 issues, so you are on your own. GitHub repository: https://github.com/ahausladen/DDevExtensions
  2. Carlo Barazzetta

    Native Svg parsing and painting in Windows

    A new brick added to this story: https://github.com/EtheaDev/SVGShellExtensions A short video/demonstration:
  3. We have open sourced our Deployment Manager to simplify deployment of a large number of files or folders to iOS or Android. https://blog.grijjy.com/2021/02/07/deployman/
  4. Dalija Prasnikar

    Interface as Const parameter

    I wouldn't use any of those solutions. Because that is not golden rule. On the contrary, for reference counted types you would almost always use const to avoid unnecessary reference counting overheard. Problem is not in the method that has const, problem happens at call site. As such it should be handled at call site. First, handling it at call site allows you to trigger reference counting only for references that really need it, next, you will avoid situation where performance will become an issue and someone will go and change method signature according to common practice - using const and will inadvertently break code. Far better solutions than 1. or 2. are using additional variable instead of constructing instance during method call, This is also easy rule to remember - don't create anything inplace. Next solution would be explicitly typecasting TFoo.Create as IFoo And the last one, I like the most because it prevents you to make reference counting mistakes in other code, too, is to have class function that will create instance and return it as interface reference. As for finding all places where you can create possible problem and you need to fix it, simple search and replace can go a long way. For instance - if you have class function New, you can just replace TFoo.Create with TFoo.New and if have same parameter list, you are good.
  5. TurboMagic

    DEC 6.1 released

    Hello, there is a new release 6.1 of DEC available . It is located here: https://github.com/MHumm/DelphiEncryptionCompendium/releases/tag/V6.1 WHat's new since V6.0? * x64 compilation works out of the box now, some unit had not been properly listed for x64 * fixed the following cipher algorithms which were broken on x64: Blowfish, RC6 and Q128 * the Sapphire cipher did work with the unit test vectors but failed for some others * added SHA2-224 hash algorithm * added HMAC and pbkdf2 algorithms * somebody provided a build batch file * there is a command line application included now for setting the IDE's library path * progress even got changed and a VCL demo for that one was added * version history is a separate document in docs folder now Cheers TurboMagic
  6. Two blog posts to share: https://blog.synopse.info/?post/2021/02/13/Fastest-AES-PRNG%2C-AES-CTR-and-AES-GCM-Delphi-implementation https://blog.synopse.info/?post/2021/02/12/New-AesNiHash-for-mORMot-2 TL&DR: new AES assembly code burst AES-CTR AES-GCM AES-PRNG and AES-HASH implementation, especially on x86_64, for mORMot 2. It outperforms OpenSSL for AES-CTR and AES-PRNG, and is magnitude times faster than every other Delphi library I know about.
  7. @David Heffernan I admire your patience.
  8. {$APPTYPE CONSOLE} uses System.SysUtils, System.Diagnostics, System.StrUtils; function MyStartsWith(const SearchText, Text: string): Boolean; var Index, SearchTextLen: Integer; begin SearchTextLen := Length(SearchText); if SearchTextLen>Length(Text) then begin Result := False; Exit; end; for Index := 1 to SearchTextLen do if Text[Index]<>SearchText[Index] then begin Result := False; Exit; end; Result := True; end; const cMaxLoop = 10000000; cText = 'Error: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'; cTextNoHits = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'; cStartsWithShort = 'E'; cStartsWithLong = 'Error:'; var vSW: TStopWatch; i, vLen: integer; hitCount: Integer; vResult: boolean; begin Writeln('Substring exists at the start:'); // Short string Writeln('Short string:'); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if Copy(cText, 1, Length(cStartsWithShort)) = cStartsWithShort then Inc(hitCount); Writeln(' Copy: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MidStr(cText, 1, Length(cStartsWithShort)) = cStartsWithShort then Inc(hitCount); Writeln(' MidStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if cText.StartsWith(cStartsWithShort) then Inc(hitCount); Writeln(' StartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if StartsStr(cStartsWithShort, cText) then Inc(hitCount); Writeln(' StartsStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MyStartsWith(cStartsWithShort, cText) then Inc(hitCount); Writeln(' MyStartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); // Long string Writeln('Long string:'); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if Copy(cText, 1, Length(cStartsWithLong)) = cStartsWithLong then Inc(hitCount); Writeln(' Copy: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MidStr(cText, 1, Length(cStartsWithLong)) = cStartsWithLong then Inc(hitCount); Writeln(' MidStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if cText.StartsWith(cStartsWithLong) then Inc(hitCount); Writeln(' StartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if StartsStr(cStartsWithLong, cText) then Inc(hitCount); Writeln(' StartsStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MyStartsWith(cStartsWithLong, cText) then Inc(hitCount); Writeln(' MyStartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); Writeln; // Text DEOS NOT start with selected string Writeln('Substring NOT exists at the start:'); // Short string Writeln('Short string:'); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if Copy(cTextNoHits, 1, Length(cStartsWithShort)) = cStartsWithShort then Inc(hitCount); Writeln(' Copy: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MidStr(cTextNoHits, 1, Length(cStartsWithShort)) = cStartsWithShort then Inc(hitCount); Writeln(' MidStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if cTextNoHits.StartsWith(cStartsWithShort) then Inc(hitCount); Writeln(' StartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if StartsStr(cStartsWithShort, cTextNoHits) then Inc(hitCount); Writeln(' StartsStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MyStartsWith(cStartsWithShort, cTextNoHits) then Inc(hitCount); Writeln(' MyStartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); // Long string Writeln('Long string:'); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if Copy(cTextNoHits, 1, Length(cStartsWithLong)) = cStartsWithLong then Inc(hitCount); Writeln(' Copy: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MidStr(cTextNoHits, 1, Length(cStartsWithLong)) = cStartsWithLong then Inc(hitCount); Writeln(' MidStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if cTextNoHits.StartsWith(cStartsWithLong) then Inc(hitCount); Writeln(' StartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if StartsStr(cStartsWithLong, cTextNoHits) then Inc(hitCount); Writeln(' StartsStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MyStartsWith(cStartsWithLong, cTextNoHits) then Inc(hitCount); Writeln(' MyStartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); readln; end. Copy is clearly a shocker of an idea for this use. heap allocation!! Really?!!! And the other functions seem really slow. A simple for loop is around 10 times faster. I didn't capture any timings, but it's easy to do it on your machine. I also addressed a couple of issues with your benchmark code. I don't believe this is a bottleneck in your program, but you love premature optimisation with a rarely seen passion.
  9. Leaving aside the issues that are commented on by other, instead of if Supports(fBaseFrameClass, ISupportTask) then (fBaseFrame as ISupportTask).CheckTask; surely you need var Task: ISupportTask; ... if Supports(fBaseFrame, ISupportTask, Task) then Task.CheckTask; Two changes: Ask the implementing object rather than the class whether or not the interface is supported. Use the three argument overload of Supports so that you can get the interface while you are querying for it.
  10. Dalija Prasnikar

    Interface as Const parameter

    Yes. Since such coding pattern is not too common in Delphi because of its manual memory management. So you either cannot use it at all, or you are creating objects and passing ownership which is not the most common scenario, or you are creating reference counted instance where inplace creating creates problems. There is no performance penalty here. You need to trigger reference counting when creating new instance. That is the original issue you are solving. All you can do to prevent accidental misues is great, but sometimes people just need to use their brains and think what they are doing.
  11. Long awaited release of powerful open-source documentation generator for Pascal code is out. Get it New website, using Jekyll, generated from our wiki, see https://github.com/pasdoc/pasdoc.github.io (Michalis) Moved everything to GitHub Ancestors list is now affected by external class hierarchy (Michalis) Markdown support (Fr0sT-Brutal) Supporting bold, italic, inline code, multi-line code, URLs, lists. @note and @warning tags (Bi0T1N) @url tag (Bi0T1N) Allow to lowercase output of @nil, @false, @true by --lowercase-keywords (Bi0T1N) Automatically detect flag like [xxx] at @param description. See here for example. (PifPof) Scan implementation section of a unit in addition to the interface section (Fr0sT-Brutal) Parser improvements to correctly handle some special cases: reading chars > $FF, "*.inc" includes, files with Mac-style line endings (Fr0sT-Brutal) Mem leaks fixed (Fr0sT-Brutal) Tag parameters now could be multiline without enclosing parens by means of "line feed" character "" (Fr0sT-Brutal) Read additional command-line options from file (Fr0sT-Brutal) --auto-back-comments command-line option (Fr0sT-Brutal) pasdoc_gui opens a file given at command-line, opening WWW browser is optional (Fr0sT-Brutal) @longcode without markers fixed (Michalis) Support for namespaces in units in @links (Fr0sT-Brutal) --ignore-marker option (Fr0sT-Brutal) Test suite fixes and better documentation, in particular for Windows users Catalan translation updated (Xavier Martínez) Delphi Tokyo files, to compile all projects and packages (Carlos Feitoza Filho) Brazilian Portuguese translation updated (Carlos Feitoza Filho) Parse identifiers declared as &xxx, where "xxx" may be a reserved word. Possibility to specify additional files using -A or --additional (just like introduction or conclusion, but you can provide any number of items) (Alex Merkel) Added de.utf8 (German with UTF-8 encoding) Automatically remove %region and %endregion from comments Show visibility (public, protected, private...) inside records too (it is meanigful for advanced records) Implement in pasdoc_gui options to (Michalis) customize HTML head and body set external descriptions file configure identifiers excluded from auto-linking Rename "internal" to "nested" to describe this language feature. Because that is how it's called in official docs ( http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Nested_Type_Declarations, https://www.freepascal.org/docs-html/ref/refse41.html ) and the "internal" word has traditionally different meaning ("something not supposed to be visible/used from the outside"). (Michalis) The automatic tests are now easier to run and check (see tests/README.md) (Michalis) @raises and @param is now supported at properties as well as methods. Actually, it's supported everywhere now, but it makes sense only at properties and methods now. (Michalis) Tipue (client-side search) improvements: we have upgraded to use Tipue 6.1, which highlights the found terms we strip HTML from Tipue index, which makes the "search results" page correct Fix handling SVN fixed-length $Date:: Parsing of $if and $elseif expressions, like defined(MSWINDOWS) or defined(UNIX) (Michalis)
  12. @Marco Cantu I wish I as a subscriber could download it without having to reenter information already in your systems.
  13. There is a page in the Delphi wiki on creating packages. https://delphi.fandom.com/wiki/Creating_Packages Edit: I had totally forgotten that I wrote that page myself (many years ago). After reading through it, I must say I still like it. There isn't much I'd change today.
  14. https://github.com/DelphiPraxis/DDevExtensions/releases/tag/v2.87 compiled pre-release, not fully tested yet
  15. RAD Studio is made up of Delphi and C++Builder. On the Delphi side the Object Pascal compiler is a single pass compiler and the compiler itself is not a parallel compiler but when compiling multiple projects in parallel it was able to compile 1 billion lines of Object Pascal code in 5 minutes on the AMD Ryzen 9 5950x 16 core machine. I wanted to see if something similar was possible with C++. This post is part of our modern hardware series where we explore the massive productivity gains that can be achieved on some of the fastest CPUs available at the time of this writing in early 2021. Just how much is 1 billion lines of code? Take a look. https://blogs.embarcadero.com/threadripper-3990x-the-quest-to-compile-1-billion-lines-of-c-on-64-cores/
  16. Anders Melander

    Hashing Street Addresses ?

    I solve most of my problems in the shower. Eureka!
  17. aehimself

    Zeos 7.3 entered the beta phase.

    @Dany Marmur as far as I can see @EgonHugeist already started the development of the Zeos-based memory table. The latest snapshot already has the TZMemTable component - now it's time to start to play with it! Edit: Seems to be working as it should: procedure TForm1.FormCreate(Sender: TObject); begin ZMemTable1.FieldDefs.Add('MyField', ftWideString); ZMemTable1.Open; Try ShowMessage(ZMemTable1.RecordCount.ToString); ZMemTable1.Append; ZMemTable1.FieldByName('MyField').AsString := 'Hello world!'; ZMemTable1.Post; ShowMessage(ZMemTable1.RecordCount.ToString + sLineBreak + ZMemTable1.FieldByName('MyField').AsString); Finally ZMemTable1.Close; End; end; At the moment it throws a nullpointer AV if it's destroyed while it's open but I'll send a pull request with a fix in a minute.
  18. here, my sample how to do it: RAD Studio 10.3.3 Arch (Rio) VCL project for test none any Windows API is used (at least directly) the magic: TransparentColor on Forms! Calculate the position where is the first "Shape" and how use it in SecondForm position! FormMain or any other: unit uFormMain; interface uses ... all units necessary below type TfrmFormMain = class(TForm) Shape1: TShape; // ======== Color = YELLOW Button1: TButton; Shape2: TShape; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); private public end; var frmFormMain: TfrmFormMain; // X1frmFormMainShapeLeft: integer = 0; Y1frmFormMainShapeTop : integer = 0; implementation {$R *.dfm} uses uFormSecond; procedure TfrmFormMain.Button1Click(Sender: TObject); var lMyOffsetTop : integer; lMyOffsetLeft: integer; begin // here, my values arbitrary... lMyOffsetTop := 8; // you need calculate the margin vertical values ( area-non-client ) lMyOffsetLeft := 8; // calculate the margin horizontal values( area-non-client ) // Y1frmFormMainShapeTop := ClientToScreen(TPoint.Create(0, 0)).Y + Shape1.Top - (Self.Height - Self.ClientHeight) + lMyOffsetTop; X1frmFormMainShapeLeft := ClientToScreen(TPoint.Create(0, 0)).X + Shape1.Left - (Self.Width - Self.ClientWidth) + lMyOffsetLeft; // frmFormSecond := TfrmFormSecond.Create(nil); try frmFormSecond.ShowModal; finally frmFormSecond.Free; end; end; procedure TfrmFormMain.FormCreate(Sender: TObject); begin // Self.AlphaBlendValue := 180; // 0 = total transparence ... 255 = non-transparence // Self.AlphaBlend := true; // active transparence on form? Self.TransparentColorValue := clYellow; Self.TransparentColor := true; // end; initialization ReportMemoryLeaksOnShutdown := true; finalization end. SecondForm or any other: unit uFormSecond; interface uses ... // all units necessary below type TfrmFormSecond = class(TForm) Shape1: TShape; // ======= Color = Blue procedure FormCreate(Sender: TObject); private public end; var frmFormSecond: TfrmFormSecond; implementation {$R *.dfm} uses uFormMain; procedure TfrmFormSecond.FormCreate(Sender: TObject); begin // Self.AlphaBlendValue := 180; // 0 = total transparence ... 255 = non-transparence // Self.AlphaBlend := true; // active transparence on form? Self.TransparentColorValue := clBlue; Self.TransparentColor := true; // // Self.Left := X1frmFormMainShapeLeft - Shape1.Left; Self.Top := Y1frmFormMainShapeTop - Shape1.Top; end; end. hug
  19. Tommi Prami

    TBCEditor text editor component

    TBCEditor was made by my coworker. Saying "violation the SynEdit license" might be bit overstatement, as I remembered someone found couple of trivial pieces, when Author said show me the code and I'll rewrite, nobody did nothing so... It was ground up rewrite more than less from Scratch. Spend couple of years coding it every day basically. This weird dude who ripped TBCEditor off was extremely rude, so Author just took it off of public. Editor (or it's descendant) is in Text Editor Pro, which is very good text editor tool. And yes, totally abandoned and left in state that would need lot of work from dedicated people to fix for sure.
  20. Paperback edition of the book has been released. There is 50% discount for paperback edition for everyone who buys eBook edition. If you have already purchased the eBook version, and wish to buy the paperback, you're also eligible for a 50% discount! You can find instructions at: https://dalija.prasnikar.info/delphiebap/index.html
  21. Don't use the IDE managed version resource. Use an external RC file with a version resource instead and update it with whatever suits your build pipeline best. For example a simple bat or cmd file. I'm sure there are lots of homegrown utilities that can update the version in the dproj, an RC or RES file but I like to keep the number of dependencies down. A utility would just be yet another piece of software to install, maintain, etc.
  22. Really? Ouch 😨 It used to be much simpler: function TStringHelper.StartsWith(const Value: string): Boolean; begin Result := StartsWith(Value, False); end; function TStringHelper.StartsWith(const Value: string; IgnoreCase: Boolean): Boolean; begin if not IgnoreCase then Result := System.SysUtils.StrLComp(PChar(Self), PChar(Value), Value.Length) = 0 else Result := System.SysUtils.StrLIComp(PChar(Self), PChar(Value), Value.Length) = 0; end; function StrLComp(const Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; var I: Cardinal; P1, P2: PWideChar; begin P1 := Str1; P2 := Str2; I := 0; while I < MaxLen do begin if (P1^ <> P2^) or (P1^ = #0) then Exit(Ord(P1^) - Ord(P2^)); Inc(P1); Inc(P2); Inc(I); end; Result := 0; end; function StrLIComp(const Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; var P1, P2: PWideChar; I: Cardinal; C1, C2: WideChar; begin P1 := Str1; P2 := Str2; I := 0; while I < MaxLen do begin if P1^ in ['a'..'z'] then C1 := WideChar(Word(P1^) xor $20) else C1 := P1^; if P2^ in ['a'..'z'] then C2 := WideChar(Word(P2^) xor $20) else C2 := P2^; if (C1 <> C2) or (C1 = #0) then Exit(Ord(C1) - Ord(C2)); Inc(P1); Inc(P2); Inc(I); end; Result := 0; end; Compared to StartsStr(), which (eventually) calls CompareString(): function StartsStr(const ASubText, AText: string): Boolean; begin Result := AnsiStartsStr(ASubText, AText); end; function AnsiStartsStr(const ASubText, AText: string): Boolean; begin Result := AnsiSameStr(ASubText, Copy(AText, 1, Length(ASubText))); // WHY Copy()? AnsiStrLComp() could have been used instead! end; function AnsiSameStr(const S1, S2: string): Boolean; begin Result := AnsiCompareStr(S1, S2) = 0; end; function AnsiCompareStr(const S1, S2: string): Integer; {$IFDEF MSWINDOWS} begin Result := CompareString(LOCALE_USER_DEFAULT, 0, PChar(S1), Length(S1), PChar(S2), Length(S2)) - CSTR_EQUAL; end; {$ENDIF MSWINDOWS} {$IFDEF POSIX} begin Result := UCS4CompareStr(UnicodeStringToUCS4String(S1), UnicodeStringToUCS4String(S2)); end; {$ENDIF POSIX} I don't have RTL/VCL source code past XE3, but I keep seeing people mention how bad it's getting in recent years. This is not good.
  23. Not if the search string is longer than the other string. Then it's a buffer overrun. Use the version from my post.
  24. I had created the report in Quality Central already ( RSP-32335 ). I also attached your Project1.dpr with the report.
  25. kuzduk

    kuLibrary

    Multilanguage site it good idea but i have no time to do it. So as a the simplest solution is google translate: https://translate.google.com/translate?hl=&amp;sl=ru&amp;tl=en&amp;u=http://kuzduk.h1n.ru/_kulibrary.html - Putin approves!
×