Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 02/22/21 in all areas

  1. What about creating a new form instance and adjust the components and properties in question from that?
  2. Stefan Glienke

    Micro optimization: Split strings

    Some of your functions have a defect as in returning an empty array when no delimiter is found - they must return a 1 element array with the input string if they should follow RTL behavior. Also you can remove some unnecessary branching and make the code simpler: function CustomSplitWithPrecountByIndex2(const aString: string; const aDelimiter: Char): TArray<string>; var i, resultLen, resultIdx, tokenPos, inputLen, lastDelimiterPos: Integer; begin inputLen := aString.Length; lastDelimiterPos := 0; resultLen := 1; for i := 1 to inputLen do if aString[i] = aDelimiter then begin Inc(resultLen); lastDelimiterPos := i; end; SetLength(Result, resultLen); resultIdx := 0; tokenPos := 1; for i := 1 to lastDelimiterPos do if aString[i] = aDelimiter then begin SetString(Result[resultIdx], PChar(@aString[tokenPos]), i - tokenPos); tokenPos := i + 1; Inc(resultIdx); end; SetString(Result[resultIdx], PChar(@aString[tokenPos]), inputLen - lastDelimiterPos); end;
  3. Antony Augustus

    SortListBox component

    I have developed a SortListBox that accepts Integer items and sorts it in Quicksort, InsertionSort and SelectionSort both order Ascending and Descending. Steps 1) Install the SortPackage.bpl 2) SortListBox Component can be found in 'Samples' page SortListBox Properties SortActive SortType SortOrder SortPackage.bpl
  4. COVID-19 got us all down a bit and even with the vaccines theoretically available now, the light at the end of the tunnel seems very far away. My own turn for a jab will probably not come before fall 2021, so I can only hope that summer will reduce the infection rates as much as it did last year, but the new mutants that spread around the world definitely aren’t good news. Maybe I can lighten up your mood a bit with a new GExperts release. There are a few bug fixes and an also a few new features in the new version, but nothing really exciting. read on in the blog post.
  5. For inspiration you may also look into this excellent answer from Uwe Raabe on Stackoverflow on a related question: https://stackoverflow.com/questions/47347578/manually-skip-a-component-from-being-created-from-the-dfm which also shows a hacky way to prevent components from getting created. I guess Uwe wasn't aware of his answer more than 3 years ago 😉 As for loading the dfm from the resource that's in the executable have a look at http://docwiki.embarcadero.com/Libraries/Sydney/de/System.Classes.TStream.ReadComponentRes
  6. xorpas

    full screen view capture

    How you solved this problem Can you put Your Code Hier ?
  7. I guess it is theoretically possible to shoehorn Delphi's streaming mechanism to do what you want. Essentially you could just reread your form with an adjusted TReader. Specifically you would not want for the components to be recreated. Have a look at the TReader events, specifically TReader.OnCreateComponent One problem though is how to "skip" rereading of components as you want to only select a number of components.
  8. For example a TMultiReadExclusiveWriteSynchronizer.
  9. Lars Fosdal

    GExperts 1.3.18 experimental twm 2021-02-21 released

    The Danes are currently having an upswing in cases due to the English mutation, and we are usually about four weeks after the Danes. I am the type of person that is happy in my own company and not dependent on hanging out with people outside the family to be stimulated, but even I am beginning to feel the pressures of self-isolation. I miss seing the users and my colleagues over a beer. That constant little ping of fear when venturing into the shopping centers and stores, wearing a mask, sanitizing my hands. It is a stress factor unlike anything I've ever endured before. There still are hundreds of thousands of people in front of me in the vaccination queue. But - you do what you can and embrace the days as they come. Thinking about Delphi things is a good diversion, so keep letting out more genies GExperts 🙂
  10. Remy Lebeau

    play all videos in one folder delphi?

    VCL's TMediaPlayer has an OnNotify event, which you can use to detect the end of playback. Load the video file paths into a list, start playing the 1st file, and use OnNotify to play the next file in the list, repeating until the list is finished.
  11. Attila Kovacs

    Micro optimization: Split strings

    My version is rather fun as some kind of pico-optimization. An on the fly enumerator! And also fast and low memory footprint. (And unidirectional 😉 TSplitEnumerator = class; TSplit = record private PValue: pointer; PDelimiter: pointer; public function GetEnumerator: TSplitEnumerator; class function Create(const AValue: string; const ADelimiter: string): TSplit; static; end; TSplitEnumerator = class private FValue: string; FDelimiter: string; FHasNext: boolean; FIndex: integer; FNIndex: integer; FLen: integer; FDelLen: integer; public constructor Create(const ASplit: TSplit); function MoveNext: boolean; {$IFNDEF DEBUG} inline; {$ENDIF} function GetCurrent: string; {$IFNDEF DEBUG} inline; {$ENDIF} property Current: string read GetCurrent; end; { TSplit } class function TSplit.Create(const AValue: string; const ADelimiter: string): TSplit; begin Result.PValue := pointer(AValue); Result.PDelimiter := pointer(ADelimiter); end; function TSplit.GetEnumerator: TSplitEnumerator; begin Result := TSplitEnumerator.Create(Self); end; { TSplitEnumerator } constructor TSplitEnumerator.Create(const ASplit: TSplit); begin FIndex := 1; pointer(FValue) := ASplit.PValue; pointer(FDelimiter) := ASplit.PDelimiter; FLen := Length(FValue); FDelLen := Length(FDelimiter); FNIndex := Pos(FDelimiter, FValue, FIndex); if (FNIndex = 0) then FNIndex := FIndex + FLen; FHasNext := (FLen > 0) and (FNIndex > 0); end; function TSplitEnumerator.GetCurrent: string; begin Result := Copy(FValue, FIndex, FNIndex - FIndex); if FNIndex + FDelLen < FLen then begin FIndex := FNIndex + FDelLen; FNIndex := Pos(FDelimiter, FValue, FIndex); if FNIndex = 0 then FNIndex := FLen + FDelLen; end else FHasNext := False; end; function TSplitEnumerator.MoveNext: boolean; begin Result := FHasNext; end; var s: string; begin for s in TSplit.Create(cShortStr, cDelimiter) do WriteLn(s); end;
  12. Arnaud Bouchez

    Micro optimization: Split strings

    Your code is sometimes not correct. For instance, CustomSplitWithPrecount() exit directly without setting result := nil so it won't change the value passed as input (remember than an array result is in fact a "var" appended argument). All those are microoptimisations - not worth it unless you really need it. I would not use TStringList for sure. But any other method is good enough in most cases. Also no need to use a PChar and increment it. In practice, a loop with an index of the string is safer - and slightly faster since you use only the i variable which is already incremented each time. To optimize any further, I would use PosEx() to find the delimiter which may be faster than your manual search on some targets. The golden rule is to make it right first. Then make it fast - only if it is worth it, and I don't see why it would be worth it.
  13. Nice, Carlo. I use the SVG preview capability from https://docs.microsoft.com/en-us/windows/powertoys/file-explorer
  14. 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:
  15. Turan Can

    full screen view capture

    The problem is solved. I convert from the Java example. Thanks. It only receives the form you send. Please check the picture above.
  16. Eric58

    AV with InApp purchase on MacOS

    Hi Francisco, I faced the same problem a few months ago, and I solved it this way: Start with the the sample code MacInAppTest.zip posted by Hans, then modify it as described further below; the modifications are necessary to account for these reasons that caused the AV crashes reported by Hans: Unlike for iOS, the DispatchToDelphi for MacOS is called outside of the mainthread. This is why the callback to TiOSProductsRequestDelegate.productsRequest behaves erratically - it is no longer threadsafe. This can be fixed using the treatment shown in the code I attach below. This treatment needs to be applied for all other callback procedures that also need to be threadsafe. Unlike for the iOS compiler, the OSX64 compiler does not adopt the ARC management model. This difference requires that the field FProductsRequestDelegate in the TiOSInAppPurchaseService class be accompanied by another IInterface field which I've named FHoldProductsRequestDelegate. See my comment in the code snippet below for the detailed explanation. My original goal was to create a workable FMX.InAppPurchase.Mac, but I no longer have that module as my goal then expanded to incorporate my custom licensing requirements over the innate differences of Mac's and Window's IAP, and I ended up regutting what I needed from both platform's working IAP code into my cross-platform IAP+Licensing module. Modifications Needed on Han's code: procedure TiOSProductsRequestDelegate.productsRequest(request: SKProductsRequest; didReceiveResponse: SKProductsResponse); var Product: SKProduct; LocalProduct: TProduct; Products: NSArray; InvalidProducts: NSArray; ProductID: NSString; I: Integer; InvalidProductIDList: TStrings; _retainedProducts, _retainedInvalidProducts: NSArray; begin if TThread.Current.ThreadID <> MainThreadID then if TThread.Current.ThreadID <> MainThreadID then //breakpoint here to prove that we are not in mainthread ; /// DispatchToDelphi call this through a thread that is not the mainthread. /// We need to route this to the mainthread via Synchronize, but first we /// extract the data needed and hold them as captured variables for use during /// mainthread processng: _retainedProducts := didReceiveResponse.products; _retainedProducts.retain; _retainedInvalidProducts := didReceiveResponse.invalidProductIdentifiers; _retainedInvalidProducts.retain; TThread.Synchronize(nil, procedure var I: Integer; begin FIAPService.FProductList.Clear; InvalidProductIDList := TStringList.Create; if FIAPService.FProducts <> nil then FIAPService.FProducts.release; Products := _retainedProducts; //instead of didReceiveResponse.Products; FIAPService.FProducts := Products; FIAPService.FProducts.retain; InvalidProducts := _retainedInvalidProducts; //instead of didReceiveResponse.invalidProductIdentifiers; if (Products <> nil) and (Products.count > 0) then for I := 0 to Pred(Products.count) do begin Product := TSKProduct.Wrap(Products.objectAtIndex(I)); LocalProduct := SKProductToProduct(Product); FIAPService.FProductList.Add(LocalProduct); end; if (InvalidProducts <> nil) and (InvalidProducts.count > 0) then for I := 0 to Pred(InvalidProducts.count) do begin ProductID := TNSString.Wrap(InvalidProducts.objectAtIndex(I)); InvalidProductIDList.Add(NSStrToStr(ProductID)); end; if FIAPService <> nil then FIAPService.DoProductsRequestResponse(FIAPService.FProductList, InvalidProductIDList); // Finally balance the retains with releases: _retainedProducts.release; _retainedInvalidProducts.release; end) end; TiOSInAppPurchaseService = class(TInterfacedObject, IFMXInAppPurchaseService) private FProductsRequest: SKProductsRequest; /// FProductsRequestDelegate implements IInterface, so when QueryProducts access /// it via the construct FProductsRequestDelegate as ILocalObject, it will trigger /// an AddRef followed by a Release when QueryProducts goes out of scope. This /// will cause FProductsRequestDelegate to be prematurely freed. To prevent this /// add a new field FHoldProductsRequestDelegate and assign it to FProductsRequestDelegate /// in the constructor. Note that the iOS compiler does not face this problem because /// its ARC memory management will automatically do an AddRef on FProductsRequestDelegate FProductsRequestDelegate: TiOSProductsRequestDelegate; FHoldProductsRequestDelegate: IInterface; ...... end;
×