Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 08/10/21 in Posts

  1. David Schwartz

    How to create a grid that looks like this

    I'm not buying an entire huge library for one simple UI feature. The TjanRoundedButton solves the problem from a visual standpoint, although it's not as easy to work with as I'd like. (My Delphi license is up for renewal as well, and it ain't cheap either. That library is 2/3 the cost of my Delphi renewal. I only wish I could force everybody to give ME a mandatory 4% raise every year the way EMBT does with their maintenance deals.)
  2. CHackbart

    MacOS AVPlayer and DRM

    Thanks, the whole translation from this: func requestApplicationCertificate() throws -> Data { print("requestApplicationCertificate called") // MARK: ADAPT - You must implement this method to retrieve your FPS application certificate. var certificateData: Data? = nil let request = NSMutableURLRequest(url: URL(string: DNSRestServices.DNS_FAIRLPLAY_SERVER_URL)!) request.httpMethod = "POST" request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData request.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type") let semaphore = DispatchSemaphore(value: 0) URLSession.shared.dataTask(with: request as URLRequest) { (responseData, _, error) -> Void in certificateData = responseData semaphore.signal() }.resume() semaphore.wait(timeout: .distantFuture) guard certificateData != nil else { throw ProgramError.missingApplicationCertificate } return certificateData! } func requestContentKeyFromKeySecurityModule(spcData: Data, assetID: String) throws -> Data { var ckcData: Data? = nil var licenseURL : String? licenseURL = DispatchQueue.main.sync { var licenseURLForSelectedChannel = "" if let keyWindow = UIWindow.key { let menuViewController = keyWindow.rootViewController as! MenuSplitViewController let playerController = menuViewController.viewControllers[1] as! DNSPlayerViewController licenseURLForSelectedChannel = playerController.licenseURLForSelectedChannel() ?? "" } return licenseURLForSelectedChannel } guard licenseURL != nil else { throw ProgramError.missingLicenseURL } guard let url = URL(string: licenseURLString) else { print("Error! Invalid URL!") //Do something else throw ProgramError.missingLicenseURL } let request = NSMutableURLRequest(url: url) request.httpMethod = "POST" request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringCacheData request.httpBody = spcData let postLength:NSString = NSString(data: spcData, encoding:String.Encoding.ascii.rawValue)! request.setValue(String(postLength.length), forHTTPHeaderField: "Content-Length") request.setValue("application/octet-stream", forHTTPHeaderField: "Content-Type") let semaphore = DispatchSemaphore(value: 0) URLSession.shared.dataTask(with: request as URLRequest) { (responseData, _, error) -> Void in ckcData = responseData semaphore.signal() }.resume() semaphore.wait(timeout: .distantFuture) guard ckcData != nil else { throw ProgramError.noCKCReturnedByKSM } return ckcData! } func handleStreamingContentKeyRequest(keyRequest: AVContentKeyRequest) { guard let contentKeyIdentifierString = keyRequest.identifier as? String, let contentKeyIdentifierURL = URL(string: contentKeyIdentifierString), let assetIDString = contentKeyIdentifierURL.host, let assetIDData = assetIDString.data(using: .utf8) else { print("Failed to retrieve the assetID from the keyRequest!") return } let provideOnlinekey: () -> Void = { () -> Void in do { let applicationCertificate = try self.requestApplicationCertificate() let completionHandler = { [weak self] (spcData: Data?, error: Error?) in guard let strongSelf = self else { return } if let error = error { keyRequest.processContentKeyResponseError(error) return } guard let spcData = spcData else { return } do { // Send SPC to Key Server and obtain CKC let ckcData = try strongSelf.requestContentKeyFromKeySecurityModule(spcData: spcData, assetID: assetIDString) /* AVContentKeyResponse is used to represent the data returned from the key server when requesting a key for decrypting content. */ let keyResponse = AVContentKeyResponse(fairPlayStreamingKeyResponseData: ckcData) /* Provide the content key response to make protected content available for processing. */ keyRequest.processContentKeyResponse(keyResponse) } catch { keyRequest.processContentKeyResponseError(error) } } keyRequest.makeStreamingContentKeyRequestData(forApp: applicationCertificate, contentIdentifier: assetIDData, options: [AVContentKeyRequestProtocolVersionsKey: [1]], completionHandler: completionHandler) } catch { keyRequest.processContentKeyResponseError(error) } } provideOnlinekey() } } should look more or less like this: function TContentKeyDelegate.requestApplicationCertificate(): NSData; var http: THTTPClient; Response: TMemoryStream; begin http := THTTPClient.Create; Response := TMemoryStream.Create; try http.ContentType := 'application/octet-stream'; http.Get(FAIRLPLAY_SERVER_URL, Response); result := TNSData.Wrap(TNSData.OCClass.dataWithBytes(response.Memory, response.Size)) finally Response.Free; http.Free; end; end; function TContentKeyDelegate.requestContentKeyFromKeySecurityModule(spcData: NSData; assetID: NSString): NSData; var http: THTTPClient; Response: TMemoryStream; Request: TMemoryStream; begin http := THTTPClient.Create; Response := TMemoryStream.Create; Request := TMemoryStream.Create; Request.Write(spcData.bytes^, spcData.length); try Request.Position := 0; http.ContentType := 'application/octet-stream'; http.Post(KEY_SERVER_URL, Request, Response); result := TNSData.Wrap(TNSData.OCClass.dataWithBytes(response.Memory, response.Size)) finally Request.Free; Response.Free; http.Free; end; end; procedure TContentKeyDelegate.requestCompleteHandler(contentKeyRequestData: NSData;error: NSError); var ckcData: NSData; keyResponse: AVContentKeyResponse; begin ckcData := requestContentKeyFromKeySecurityModule(contentKeyRequestData, FAssetIDString); keyResponse := TAVContentKeyResponse.Wrap(TAVContentKeyResponse.OCClass.contentKeyResponseWithFairPlayStreamingKeyResponseData(ckcData)); FKeyRequest.processContentKeyResponse(keyResponse); end; procedure TContentKeyDelegate.handleStreamingContentKeyRequest(keyRequest: AVContentKeyRequest); var contentKeyIdentifierString: NSString; assetIDData: NSData; contentKeyIdentifierURL: NSURL; dictionary: NSDictionary; begin FKeyRequest := keyRequest; contentKeyIdentifierString := TNSString.Wrap(keyRequest.identifier); contentKeyIdentifierURL := TNSUrl.Wrap(TNSUrl.OCClass.URLWithString(contentKeyIdentifierString)); FAssetIDString := contentKeyIdentifierURL.host; assetIDData := FAssetIDString.dataUsingEncoding(NSUTF8Stringencoding); dictionary := TNSDictionary.Wrap(TNSDictionary.OCClass.dictionaryWithObject(TNSNumber.OCClass.numberWithInt(1), NSObjectToID(AVContentKeyRequestProtocolVersionsKey))); keyRequest.makeStreamingContentKeyRequestDataForApp( requestApplicationCertificate, assetIDData, dictionary, requestCompleteHandler); end; I can post the whole unit if somebody is interested in. Using it with the FMX.Media class is quite simple. All you need is to assign the asset with the ContentKeyManager: LAsset := TAVURLAsset.Wrap(TAVURLAsset.OCClass.URLAssetWithURL(LURL, nil)); if LAsset.hasProtectedContent then ContentKeyManager.addContentKeyRecipient(LAsset); FPlayerItem := TAVPlayerItem.Wrap(TAVPlayerItem.OCClass.playerItemWithAsset(LAsset));
  3. darnocian

    Parsing Text search expression

    Lucene is really excellent! I can highly recommend it! I've only used it in Java. I've considered doing a port, but it is a big project to undertake. BTW. There is an older port on sourceforge: https://sourceforge.net/projects/mutis/
  4. Der schöne Günther

    No StringHelper for saving to file?

    Saving to file has nothing to do with the string itself. What's next, myString.SendOverNetworkByUDP(..)? You have TFile.WriteAllText(filePath, fileContent) from System.IoUtils, that should be enough for everybody 😉
  5. PeterPanettone

    No StringHelper for saving to file?

    That is correct - but I LOVE string helpers.
  6. Darian Miller

    upcoming language enhancements?

    I imagine if you asked today, you would get access before the week is out and have time to play with the beta before it gets released. No one really knows the expected release date (probably most at Embarcadero don't even know yet) ... but you can make an educated guess. Their current sale ends August 31 and last year 10.4.1 was released September 2 and their latest marketing says to "buy now and get the next version as soon as it's released." There's nothing saying they couldn't ship RADStudio 11 tomorrow, but if you have a little free time to test the Beta, it might be worth your time and you just might find a bug or two that can get fixed before release to make the version even better. I haven't had time to test the Beta much myself yet so I don't know how close it is. I was hoping to find some time this week. My wish would be that it wouldn't ship until it's actually ready...even if that means next year and we keep patching 10.4.2 until then.
  7. No, it's just shorter than writing: var LKeepProcessing: Boolean; begin repeat LKeepProcessing := ProcessMessage(Msg); until not LKeepProcessing; end;
  8. As ProcessMessage already does all the work, there is not much to do in the body of this loop.
  9. My all time favorite: if SomeErrorCondition then Exception.Create('Errormessage goes here'); (raise is missing, just in case you didn't notice.) Or alternatively: raise exception('SomeErrorMessage'); (create is missing) Makes for a "nice" Access Violation in the exception handler. Both were in my own code, but the first one was also in some older RTL and JVCL and Indy code (all fixed now). I blogged about this a while ago. (OMG, back then we still hat Google+ !)
  10. Well, not really. Certainly in my experience when dealing with floating point data, you can just mandate that it doesn't have thousand separators. Perhaps if you are dealing with currency then you'd need to handle thousand separators but for other data it's not necessary.
  11. My forever favorite stays this: Function GetUserID(APageIndex: Integer): Integer; Begin Case APageIndex Of 0: Result := -1; 1: Result := -1; 2: Result := -1; 3: Result := -1; [...] 50: Result := -1; Else Result := -1; End; Probably it had functionality a long time ago, but this method was still called from a live part of the code when I found it...! There were also some fancy fails (mainly memory leaks), including but not limited to: TMyClass = Class(TObject) private FOwner: TComponent; public Constructor Create(AOwner: TComponent); ReIntroduce; End; Constructor TMyClass.Create(AOwner: TComponent); Begin FOwner := AOwner; End; Or the other, which was probably a typo but took me a while to finally realize the issue: TMyClass = Class(TComponent) public Constructor Create(AOwner: TComponent); Override; End; Constructor TMyClass.Create(AOwner: TComponent); Begin inherited Create(Owner); End;
  12. IntToStr(LDataSet.AsInteger); Could use AsString directly.
  13. Uwe Raabe

    upcoming language enhancements?

    There definitely is a plan! The problem is how much of that plan turns into reality.
  14. Fr0sT.Brutal

    memory usage of TJPGImage

    Solving similar issue in my map control,. I came to 3-level cache: - Hot: Tbitmaps - Medium: PNGImages - Cold: TMemoryStreams Capacity of all levels is limited by memory and GDI handles. Comments in OSM.TileStorage.pas unit explain decisions I made
  15. Fr0sT.Brutal

    upcoming language enhancements?

    Ternary operator is just a sugar for me. I find myself using it pretty rarely because it often grows so much that it starts looking monstrous. Much more useful is || construction from C-like langs that frequently replaces ternary: res = smth ? smth : default and res = smth || default Async/await is what I use everyday, everywhere so they're my favorites.
  16. David Schwartz

    upcoming language enhancements?

    Yeah, all it says is, "Add Delphi language extensions for increasingly powerful coding" That's more than was said about ALL language extensions added in the past few releases. Given that it's singled-out in this release -- at the very top of the list, no less -- suggests maybe more is planned than one might expect. I'm also hoping they'll provide a way to generate code for smaller ARM platforms like Raspberry Pi devices and a wider array of Linux environments. 15 years ago, a PC with the power that a RPi 4 with a 1.2GHz CPU and 4GB of SD storage has on it was pretty damned expensive, and we used D4-D7 to write code for smaller environments. Given that a lot of that stuff is programmed using interpretive languages like Python, maybe Delphi could emit javascript/ASM (whatever it's called) that's easier to host on smaller platforms like this.
  17. David Schwartz

    upcoming language enhancements?

    Well, the roadmap lists "Language enhancements" as the first thing in the list for this upcoming release, but I've not seen anything specific. They often start discussing more details as the public beta gets rolling. A lot of stuff they list has resulted in some discussions with details being released. The language enhancements are almost always a surprise. But for them to actually mention it suggests they've got something more significant planned. <RANT> Delphi seems so far behind the curve when it comes to newer language features found in most contemporary languages that it has become silly. I'm tired of people who fancy themselves as highly muscular defending the lack of a jack for this type of car because it just wouldn't be the same if you didn't have to lift the car yourself to change a tire. Those "other cars" need a jack, but people who use "this car" ... BAH! We don't need no stink'n jacks! Just work out more and bulk-up those muscles! Ya, ya, ya ... and people wonder why the use of THIS type of vehicle keeps going down year after year. The vendor should put an effing jack in the trunk and anybody who doesn't want to use it can just forget it exists. Makes you wonder about all of the macho-men who objected to the use of replacing cranks on cars to get the motor running with electric starters. Delphi would be the last auto maker left without electric starters, because it would be seen as "too much like a Ford" or some other vehicle! There are around a dozen things that are found in most contemporary languages today that are missing from Delphi, and the only justification I'm aware of is because a lot of Dephi people like to scream, "we don't need no stink'n xyz or it would be too much like some other language!" Well, ya know what? All of those OTHER languages have GROWING USER BASES! Delpih keeps shrinking. Maybe saving time by having common-sense syntactic stuff found in most languages today is more important than some people think. Programmers DO LIKE TIME-SAVING FEATURES, ya know? For example, I tried using IfThen in a few places this past week and it got me into trouble ... when are we going to get a trinary operator to avoid having both options evaluated? If you think it's too much like something in some other language, just don't use it. You're free to use as many lines of code to replace a simple expression as you like. Nobody is gonna stop you! If that's not enough, switch to assembly language. (Remember, high-level languages evolved to SIMPLIFY programming vs. what assembler requires!) You can short-circuit multiple expression evaluations using logical operators (AND, OR) but that doesn't work for unassigned objects and in method calls that have side-effects, among others. Many OOP languages are now allowing a '?' to be put after assignment statements on references to objects that may be null to allow them to only work if the references are non-NULL. These are very common use cases that have evolved simple syntactic solutions in other languages to avoid multiple lines of code to address them otherwise. They're only cryptic to read if you never write code that uses them. (I rarely use things from the heap that require the ^ operator, so that stuff looks cryptic to me. But I'd never advocate that it be removed from the language for that reason!) I'm just hopeful we might be seeing some of this stuff finally showing up in Delphi (10-20 years later than other languages). I was looking at some of the code I've written in the past few days, and a lot of it is so highly idiomatic in given contexts that you'd think there would be a way of condensing it into simpler expressions without having to resort to stuffing it into subroutines or adding it to helper classes. That would only hide it away rather than simplify how it's expressed anyway. I have a feeling I'll be long gone before programming languages begin to incorporate features that let you reduce common idiomatic expressions into new syntactic structures other than subroutines. (Generics barely scratch the surface, and have a ton of limitations.) A lot of times we can't even use subroutines to simplify things in Delphi because you cannot use property names in var and out parameters on method calls, so you can't create a generic routine to pass back values to properties. You have to write a routine that's tightly-coupled to the class so it can set the properties internally, making what it's doing far more opaque than is needed. Or you just need a separate assignment statement explicitly setting property values one by one I was looking at some C++ recently ... I don't recognize any of the crap that I guess is now needed to get it to do what you need. it looks nothing like it did 20 years ago. I guess they call that "progress". </RANT>
  18. ConstantGardener

    How to create a grid that looks like this

    ...one more dependency for this? I would go with remy's solution.
  19. Remy Lebeau

    How to create a grid that looks like this

    Should be easy to replicate that in a custom-drawn TDrawGrid/TStringGrid with its grid lines turned off, and an OnDrawCell event handler to draw the rounded blobs and text inside each cell.
  20. 14.5.0 + MSI_SysProcMon - Added process username to sampling data + TMiTeC_Display - added GPU property indicating GPU presence * TMiTeC_CPU - fixed cpu core and thread count detection + TMiTeC_CPU - added SocketCount and SocketDesignation properties * TMiTeC_SMBIOS - fixed cache size detection when its size exceeding word boundary For more information about the library, download locations and documentation, see the MiTeC System Information Component Suite Home Page
  21. What is Project Maker? MiTeC Project Maker is tool for automated batch Delphi projects building. With Project Maker, you can set compiler and its configuration, define actions processed before and after building, patch version information of built binary, sign this binary with specified certificate, apply 3rd-party software protection and many more. How does Project Maker work? Project Maker offers clear powerful interface for project building task definition. Every project can contain unlimited number of tasks. Task represents Delphi project, defined in dpr or dproj file. In addition Project Maker features Profiles, where you can define common properties for project. The project can have unlimited number of profiles. Using profiles you can simply switch between variety of build configurations. Who is Project Maker targeted on? Project Maker is targeted on developers who need to make various build scenarios and make repeated actions automatic. Project Maker is simple but powerful and provides one-click building of very complex and dependent projects. For more information see https://www.mitec.cz/pm.html
  22. The new PngComponents version 1.6.0 with Delphi 10.4 Sydney support is available on GitHub: https://github.com/UweRaabe/PngComponents While the version delivered with GetIt is still on 1.4.0, the above version f.i. supports the new feature of linking to a TPngImageList by ImageName in addition to ImageIndex.
  23. mvanrijnen

    upcoming language enhancements?

    Only the updates did not fix the problems they supposed to do. LSP/Codecompletion malfunctioning. If i look the the bugs which are still open and/or being reported it does not sound like a reasonable finished product. Like delivering a car from which the weels unexpected fall of. If you'r lucky you don't have a problem, i you'r unlucky you end the day after a few hours withouth wheels. Refactoring which stops working, suddenly freezes of the IDE, suddenly exiting of the IDE, making a mess of project files etc etc. Inserting events wrong in the sourcecoude (doubleclicking an event in the property inspector), i can go on and on. Very slow "getit" a failed ripoff from the packagemanagement from other IDE's, not working GetIt sometimes.
  24. Leaving Delphi 7, and keep hoping on a reasonable release of D10 was the biggest mistake for most Delphi programmers i think. 🙂
  25. Lajos Juhász

    upcoming language enhancements?

    It's not obsolete I received as the answer from Embarcadero a couple of months ago when asked on a webinar. They feel there is no need to inform us ahead. I wonder do they actually have a plan what they would like to deliver in Delphi 11?
×