-
Content Count
285 -
Joined
-
Last visited
-
Days Won
2
Everything posted by Yaron
-
Interesting, let me know if you figured out how to use a layered window as a child under Delphi 7.
-
TComboBox is a wrapper for a WinAPI component. When you call ComboBox.Items.Add, it triggers a WinAPI SendMessage call, which is very very slow (relative to a standard TStringList.Add), I wrote about it here if you're interested: https://www.reddit.com/r/ZoomPlayer/comments/1iu0lm3/low_level_code_optimization_or_how_i_made_zoom/
-
This doesn't solve the performance issue. TComboBox is inherently slow because it uses SendMessage for every item you add.
-
I'm using a layered window to do a transparent UI effect over video, but as far as I know, you can't do the glass effect in hardware using standard WinAPI, I believe you have to use the composition API for that (is it still considered WinAPI?). If no video in the background then it's simple enough to use GDI+ to create an anti-aliased round rectangle (I have pure pascal code to do it, but it's slower), Gaussian blur copy from the background image on paint, etc. You'd also have to intercept the hittest message to allow resizing/moving of a borderless window.
-
I designed an open-source (MIT license) TComboBox replacement that's not based on WinAPI: https://github.com/bLightZP/ZPComboBox My software (Zoom Player) uses a similar options dialog design to your own and using this component cut the form's create -> show time in half. P.S. I see you're using TTreeView, if you're restoring the last TreeView selected item when the form opens incorrectly, it can incur ~700ms penalty, something worth checking out.
-
Does anyone know a delphi component that can play videos from a stream
Yaron replied to ToddFrankson's topic in VCL
You can do this using DirectShow, but as far as I know, there is no DirectShow filter (component) that can load from a TStream, you would have to write one yourself or use an AI to write one for you. I believe there are sources for the "File Source Async" DirectShow filter, you can use that as a base, replacing the disk IO with TStream commands. But it will be much easier to write the stream to a file in a temp folder and then play it. -
Beyond what you're already using, there is a slight speedup trick of setting the TComboBox's style to "csSimple" when adding the items and then restoring the style afterwards. And since you're inserting the same data into the controls, might be slightly faster to do it only once, keep a pointer to the first object and then just do Assign on the items. But I'm afraid the speed difference between adding items to a TStringList compared to a TComboBox is ridiculous and it might just be better to write a replacement component (which I'm currently investigating).
-
I am designing a new media player UI and have been documenting my work, posting about programming and UI design in laymen terms on reddit. Recently, I posted about basic UI code optimization logic and thought it may be interesting for novice programmers. Since the post is simplified for non-programmers, I'll share here that I'm using WinAPI's layered windows and GDI+ to render the anti-aliased text and bar-shapes, preserving the alpha channel.
-
As part of a new feature I'm working on, I wrote functions to browse and get streaming URLs for the Top-3 popular media servers (Plex, Emby and Jellyfin) through an easy to use abstraction layer. I open-sourced the code here: https://github.com/bLightZP/Zoom-Player-emby-jellyfin-client-plugin/tree/main
-
My media player is using a skinned window with no title and is written in Delphi 7. I am not sure if it's the Delphi 7 or the skinned form, but Window's snap to zone when dragging the window to the edge of the screen doesn't trigger automatically. Does anyone know if there is a manual way to trigger it (cause the transparent overlay showing the new layout while dragging the window to appear)?
-
I previously discussed the issue of not being able to upgrade my app to support the latest Android SDK because I haven't been making enough money on Android development to justify upgrading Delphi beyond v10.3. My app is very simple, so I was thinking I may find a "compilation" partner that would just compile the source code for me on the latest version of Delphi. Does that pose any licensing issues? I mean you're not expected to just develop for yourself, right?
-
Yes, I'm aware, but Delphi is so slow under android that I wrote most of the UI code myself using bitmaps (and optimized the bitmap code too).
-
Advice needed: Maintaining a Delphi application on the Google Play Store
Yaron posted a topic in Cross-platform
I require some advice from the sages of this forum, In 2019 I wanted to learn cross-platform development so I purchased the latest version of Delphi at the time and I wrote an companion Android app for my main Windows based software. The Android app did not justify paying continued version renewals (making less than $400/year) so I stopped updating to new versions of Delphi, stopping at v10.3. Even though my Android application is very basic, I don't think I can submit an app created in Delphi 10.3 to the google play store due to the old SDK version Google no longer accepts. My question is, what is be the best path forward to allow me to submit new versions of the app to the google play store? Use the community version? Rewrite the app in a free alternative to Delphi (any recommendations)? Something else I haven't considered? -
Advice needed: Maintaining a Delphi application on the Google Play Store
Yaron replied to Yaron's topic in Cross-platform
So my only option to develop an Android app for free is to abandon Pascal as a language? -
Advice needed: Maintaining a Delphi application on the Google Play Store
Yaron replied to Yaron's topic in Cross-platform
How practical would it be to try converting my app to a Lazarus project? -
I need advice on converting a 500k lines 32bit Delphi 7 application to 64bit
Yaron posted a topic in General Help
I hope this is the right spot & apologize if it isn't. I am the developer of Zoom Player, a windows media playback software developed in Delphi and initially released early 2000. Since then, Zoom Player has grown to over 500,000 lines of code and code-base wise, Zoom Player is stuck at Delphi 7. Over the years I got around most of Delphi 7's shortcoming using custom code, but now I've reached a point where converting Zoom Player to 64bit is becoming a greater necessity. I own a license to Delphi 10.3 so that is the 64bit target code-base I'm aiming for. Do you have any advice for me on ways to automate the jump from Delphi 7 32bit to Delphi 10.3 64bit without breaking the code in 1000's of places? Is there an AI agent or some other tool that could help me in this context? Right now this feels like a pain-staking months long project, am I wrong? -
I need advice on converting a 500k lines 32bit Delphi 7 application to 64bit
Yaron replied to Yaron's topic in General Help
From what you're writing, it seems that I'm in more of a mess than I initially considered. Most of the strings I use are WideString in order to support Unicode text in Delphi 7, not only that, all of my base visual components are based on the TNT Unicode library (e.g. TTNTForm, TTNTListBox, TTNTStringList, etc), so I can't even load the project without getting lots of error messages and I'm not even sure if the TNT Unicode library is compatible with Delphi 10.3, which means I have to revert 1000's of work-arounds for unicode text that I've implemented over the years. My code also uses quite a bit of ASM optimized code for Audio DSP, graphic processing, etc. -
I need advice on converting a 500k lines 32bit Delphi 7 application to 64bit
Yaron replied to Yaron's topic in General Help
Is there a way for me to continue developing/fixing the current Delphi 7 version while slowly fixing the code (maintaining Delphi 7 compatibility) based on compiler errors in the Delphi 10.3 environment without breaking everything? Or is my only option to maintain two separate code-bases until I successfully complete the transition? -
I need advice on converting a 500k lines 32bit Delphi 7 application to 64bit
Yaron replied to Yaron's topic in General Help
Everyone replying about strings, my code deals with a lot of UTF8 encoded strings, wouldn't leaving "string" as is has the potential of breaking UTF8 encoding in places? -
I need advice on converting a 500k lines 32bit Delphi 7 application to 64bit
Yaron replied to Yaron's topic in General Help
Thank you everyone for your kind advance. Zoom Player is already fully unicode, I bypassed this Delphi 7 limitations by using the TNT Unicode Controls, so at least part of the process wouldn't be as painful. Since whatever string that needed to support unicode is already defined as "WideString", I thought of doing a blind search and replace from "String" to "AnsiString". -
It's a relatively new image format, part of the AV1 specification. I haven't found any Delphi compatible sample code or a dll with Delphi headers for this format, any hints?
-
ImageEn is overkill and I can't pay for it. I couldn't find the actual compiled DLL for the GitHub project, otherwise I'd do the headers myself. I simply can't compile the DLLs as I don't have the infrastructure for this. I am aware that there is a section in the readme file that points to a windows library, but it doesn't link to a DLL (the only file there is "avif_x64_Release.lib"), so I'm not sure how I can use that in Delphi. Nope, nothing came up (and I did search both Google and Github before posting here). Thank you, but that's a video component, which interestingly enough is not an issue as there are AV1 video decoders out there that can be used in Delphi through DirectShow.
-
How do I get the client's IP address in a Server.Resources function?
Yaron posted a topic in MARS-Curiosity REST Library
Hi @Andrea Magni To improve security and statistics, I need access to the client's IP address when my function triggers in server.resources: [Path('projectX')] TProjectXServicesResource = class protected public [GET, Produces(TMediaType.TEXT_HTML)] function xHome([QueryParam] lang : String) : String; [POST, Consumes(TMediaType.MULTIPART_FORM_DATA), Produces(TMediaType.TEXT_HTML)] function xAction([FormParams] AParams: TArray<TFormParam>): String; end; function TProjectXServicesResource.xHome([QueryParam] lang : String) : String; begin // Need access to the client's IP here end; function TProjectXServicesResource.xAction([FormParams] AParams: TArray<TFormParam>) : String; begin // Need access to the client's IP here end; How can I obtain the client IP? -
I got a DM with a request on how I added Android AdMob interstitial ads, here's the code: First the definition: {$IF DEFINED(ANDROID) and DEFINED(ADMOB_FULLPAGE)} TInterStitialAdViewListener = class(TJavaLocal, JIAdListener) private FAD: JInterstitialAd; public constructor Create(AAD: JInterstitialAd); procedure onAdClosed; cdecl; procedure onAdFailedToLoad(errorCode: Integer); cdecl; procedure onAdLeftApplication; cdecl; procedure onAdOpened; cdecl; procedure onAdLoaded; cdecl; end; {$ENDIF} [code] Then in the private section of the main form: [code] {$IF DEFINED(ANDROID) and DEFINED(ADMOB_FULLPAGE)} LAdViewListener : TInterStitialAdViewListener; FInterStitial : JInterstitialAd; {$ENDIF} In the form's onCreate: {$IFDEF ADMOB_FULLPAGE} FInterStitial := TJInterstitialAd.JavaClass.init(MainActivity); {$IFDEF TRACEDEBUG} FInterStitial.setAdUnitId(StringToJString('ca-app-pub-3940256099942544/1033173712')); // google test ad {$ELSE} FInterStitial.setAdUnitId(StringToJString('ca-app-pub-xxxxxxxxxxxxxxxxxxx/xxxxxxxxxxx')); // real ad code {$ENDIF} {$ENDIF} And finally: {$IF DEFINED(ANDROID) and DEFINED(ADMOB_FULLPAGE)} constructor TInterStitialAdViewListener.Create(AAD: JInterstitialAd); begin inherited Create; FAD := AAD; {$IFDEF TRACEDEBUG}AddDebugEntry('InterStitialAdViewListener created');{$ENDIF} end; procedure TInterStitialAdViewListener.onAdClosed; begin {$IFDEF TRACEDEBUG}AddDebugEntry('InterStitialAdViewListener AdClosed event');{$ENDIF} //MainForm.ShowModal; end; procedure TInterStitialAdViewListener.onAdFailedToLoad(errorCode: Integer); begin {$IFDEF TRACEDEBUG}AddDebugEntry('InterStitialAdViewListener AdFailedToLoad code #'+errorCode.toString);{$ENDIF} {$IFDEF TRACEDEBUG}ShowMessage('AdFailedToLoad code #'+errorCode.toString);{$ENDIF} end; procedure TInterStitialAdViewListener.onAdLeftApplication; begin {$IFDEF TRACEDEBUG}AddDebugEntry('InterStitialAdViewListener AdLeftApplication');{$ENDIF} end; procedure TInterStitialAdViewListener.onAdLoaded; begin {$IFDEF TRACEDEBUG}AddDebugEntry('InterStitialAdViewListener AdLoaded');{$ENDIF} FAD.show; end; procedure TInterStitialAdViewListener.onAdOpened; begin {$IFDEF TRACEDEBUG}AddDebugEntry('InterStitialAdViewListener AdOpened');{$ENDIF} end; procedure TMainForm.ShowInterStitialAd; var LADRequestBuilder: JAdRequest_Builder; LadRequest: JAdRequest; begin LADRequestBuilder := TJAdRequest_Builder.Create; {$IFDEF TRACEDEBUG}LADRequestBuilder.addTestDevice(MainActivity.getDeviceID);{$ENDIF} LadRequest := LADRequestBuilder.build(); LAdViewListener := TInterStitialAdViewListener.Create(FInterStitial); CallInUIThread( procedure begin FInterStitial.setAdListener(TJAdListenerAdapter.JavaClass.init (LAdViewListener)); FInterStitial.loadAd(LadRequest); end); end; {$ENDIF}
-
I am using the microsoft's WebView2 API to embed the chromium based edge browser inside my Delphi 7 application (using Winsoft's WebView2 wrapper component). My problem is that WebView2's ExecuteScript function returns results asynchronously through a call-back function, which is a problem because my app needs to setup a few things based on the javascript function's result and can't proceed until the data is available. I couldn't find any way in Delphi to process the results synchronously without calling "Application.ProcessMessages" in a loop until the result function is triggered (I can't use "Sleep" because then the result function will never be triggered). Of course calling "Application.ProcessMessages" in a loop is not very desirable, so I'm wondering if there's a better approach?