r/delphi

After 35 years of developing software, I discovered something I apparently still didn't know how to do: Price it.
▲ 13 r/delphi

After 35 years of developing software, I discovered something I apparently still didn't know how to do: Price it.

When I moved Zilch Standard from VCL to FMX, it was a substantial rewrite - SQLite, a fluid resizable interface, light and dark themes, and a path toward cross-platform distribution.

I raised the price to $69.95 because my investment had gone up, Delphi cost more, FastReport cost more, FastSpring cost more, and the product was substantially better.

Then I arbitrarily added another $10 for the Microsoft Store.

That didn't go particularly well. 😉

The mistake wasn't believing the software had value. The mistake was calculating that value almost entirely from my side of the desk.

I wrote about what happened, the pricing research I eventually did, and the distinction I finally learned between B2B and B2C software pricing.

Maybe another Delphi developer can learn this one before spending 35 years figuring it out.

https://capecodgunny.blogspot.com/2026/08/35-years-delphi-development-pricing.html

u/Dazzling-Fishing593 — 5 days ago
▲ 16 r/delphi

HTML UI + Delphi logic via WebView2 - I've shipped two tools this way. Tell me where this approach breaks.

I've spent most of my career writing Windows desktop software in Delphi, and the UI layer has always been the part I fight with. So I went the other way: let Edge WebView2 render the interface, keep every line of logic in Pascal, and wrap the whole thing in a component.

It's called Astraeus, it's still in development, and I'd rather have it torn apart here than find the holes after release.

How it actually looks

Drop a TEdgeBrowser (Align := alClient) and a TAstraeusWindow on the form, put your index.html in web\, F9. The bridge is typed on both ends:

Astraeus1.Register('todos.add',
  procedure(const Req: IAstraeusRequest; const Res: IAstraeusResponse)
  begin
    Res.Ok(TTodoRepo.Add(Req.AsString('title')));
  end);

const id = await astraeus.invoke('todos.add', { title: 'Buy coffee' });

Component, not runtime — no singleton, no global state, no initialization call. Two windows in one process each carry their own bridge. Release builds pack the web\ folder into the executable, so distribution is MyApp.exe plus WebView2Loader.dll.

Proof it isn't a toy

Two products already built exactly like this, HTML for the entire UI and Delphi only on the calls, the same shape as Tauri:

The parts that took real work

Frameless windows are the tax you pay: custom title bar, rounded corners, Snap, maximize without flicker, browser shortcuts disabled. Then the startup gap — WebView2 needs a second or two, and the window sits there grey until the page paints, so there's a background color property and an option to hold the window until the first frame (or until the app says it's ready). Then transparency via per-pixel alpha so Windows 10 gets it too, not just Mica on 11. And an interop layer with my own ICoreWebView2 declarations, tested against the real runtime, because every RTL version exposes a different subset.

10.4 Sydney or later, Win32 and Win64, Evergreen runtime. CI builds both packages for both platforms and runs lint checks and test programs before anything gets committed.

Honest gaps: 10.4 has never run this code, and the design-time package has no test coverage — the wizard and property editors are verified by me using them, nothing more.

So: what am I not seeing?

Specifically — does requiring the WebView2 runtime cost you real users in practice? Is the memory footprint of an embedded browser something your customers would notice? And for anyone who tried this and went back to VCL or FMX, what made you turn around?

u/andre-br — 7 days ago
▲ 5 r/delphi

A story of how I hunted memory leaks in HeidiSQL

TL;DR: opening one database and clicking one table leaks 1153 objects, ~190 KB. Nothing shows in Task Manager, nothing in the source looks wrong. RestoreListSetup creates five TStringList and frees one. The table editor's constructor builds six owning containers and the unit has no destructor.

Also: how to build HeidiSQL so a profiler can actually resolve Delphi objects, which the stock command line does not.

softanics.com
u/ArtemRazin — 8 days ago
▲ 11 r/delphi

theDANE v2 - Superb editor, debugger, profiler, reverse engineering - FREE

https://preview.redd.it/f5uogxcm3hih1.png?width=800&format=png&auto=webp&s=c82a8c4315f09ab5bc30d2ab864b8784cc7d958a

Disclosure: I wrote this. It's my project, so treat the enthusiasm accordingly.

theDANE started as a native Windows editor for Pascal. Version 1 was just that — highlighting, a BNF-driven reformatter, compare/merge, a hex editor. Version 2 keeps all of it and adds the parts that used to mean leaving the window.

Debugging. A native Win32/x64 engine that reads TD32 (Delphi's format) and DWARF directly — no GDB in the middle. For FreePascal that covers -gw2-gw3 and -gw4-gw4's line tables have a discrepancy between what the spec says and what the compiler emits, which theDANE detects exactly rather than heuristically, so all three levels behave the same.

Break-at-entry lands on your program's own body rather than a runtime stub, and Ctrl+F7 runs to the first line that actually has source — useful when you've attached to something whose startup you don't care about.

Profiling, four kinds. Sampling (wall-clock and cycle counts side by side, so you can tell "waiting" from "computing"), exact instrumentation per routine and per line with heat painted into the gutter, line coverage accumulated across runs, and allocation profiling. The line probes work on x64 as well as x86 — a probe in the middle of a routine has to preserve the flags, or your if quietly takes the other branch and the measurement changes the result.

Binary work. Recursive-descent analysis producing a byte map, xrefs, basic blocks and a function list; a control flow graph; strings, pointer tables and arrays found from the code that references them. Plus the bit I'm most pleased with: Delphi class recovery from VMTs. Drop in a stripped executable and sub_00401A40 comes back as TCustomerForm.btnSaveClick — not inference, the names are genuinely in the file, and theDANE knows the layout because it's the kind of tool that builds these binaries. Everything you work out is stored in a plain-text .dane file beside the binary, so it diffs and merges in git.

Scripting. MIMERCode — a Pascal-flavoured language with contracts, typed exceptions, channels and a UI layer. Automation commands are one self-describing .mc each with their own hotkey and menu placement. The same language writes debug value formatters (how your types display at a breakpoint) and binary parsers. The API signatures are registered rather than just documented, so they feed the editor's own completion while you write the script.

local Ed := open("thedane://editor")
Ed.ReplaceSelection(UpperCase(Ed.SelectedText()))

AI, with the interesting part being what it's allowed to do. Providers are Claude, any OpenAI-protocol endpoint, Ollama, or theMIMER — local or remote, your choice, keys encrypted per Windows account. The whole layer is inert until you configure one, and a build made without AI support doesn't carry the menu at all.

The design decisions worth arguing about aren't "which model", they're these:

  • Write tools are invisible at the lower capability level. Not disabled and refused — not offered to the model in the first place, so it can't decide to try.
  • Every edit arrives as a diff you approve, expressed as text to match rather than line numbers, so a stale line count can't land a change in the wrong place.
  • Generated artefacts are verified before you see them. Ask for a binary parser and the MIMERCode that comes back has been linted and run against your actual file first. Ask for tests and they're compiled and corrected before they're shown.
  • Function naming in a disassembly has a confidence floor (nothing written below 60%), everything it writes is tagged [ai] or [ai?], and a batch run never overwrites a name you gave.
  • Uploading a binary is a refuse, not a warn.
  • There's a complete activity log, so "what did it actually do" always has an answer.

It also writes MIMERCode using a system prompt generated from the same signature registry that drives the editor's completion — so the assistant and the popup are working from one definition of the API rather than two that drift.

Personalities. That's a lot of application, so you pick how much of it exists: Editor, Developer, Reverse Engineer, or Everything. Press a shortcut belonging to a personality you're not in and it asks, tells you what it would switch you to, and does nothing at all if you decline.

One native executable, no runtime to install, starts in under a second, opens a 100k-line file about as fast as a 100-line one.

Happy to answer anything — particularly on the symbol reading, the VMT recovery, or the AI capability model, which are the parts with the most interesting corners.

https://components4developers.blog/2026/08/10/thedane-the-danish-advanced-native-editor-v2

reddit.com
u/kimmadsen — 11 days ago
▲ 13 r/delphi

Code4Delphi - Syntax Highlighting AND Form Visualizer in VS Code

I just updated my Code4Delphi VSCode extension to version 2.0, which adds a form (dfm/fmx) viualizer. Note: the goal is NOT to render the actual components, but just a box model, so that you can open any dfm file from within VSCode to see (and even edit) it's layout. Including component tree and zoom.

Feedback welcome!

https://marketplace.visualstudio.com/items?itemName=DeveloperExperts.code4delphi

u/omonien — 10 days ago
▲ 0 r/delphi

"We’ll just build our own SBOM tool" – Famous Last Words in Delphi Engineering.

Every time a new regulatory standard like the EU Cyber Resilience Act (CRA) or NIS2 hits the headlines, I see the same cycle repeat itself.

An engineering manager looks at compliance, looks at their legacy codebase, and says: "Why pay for an enterprise scanner? It’s just code. We’ll write a quick script to read our `.pas` files and generate the SBOM over the weekend."

If you are currently contemplating building your own internal Delphi SBOM analyzer (or wrapping an open-source tool that "just reads source files"), here is a friendly heads-up on what you are actually signing up for:

🎈 Closed-Source DCUs (The Compiled Black Box) - What happens when your project relies on third-party components or vendor libraries provided ONLY as compiled `.dcu` files without source code? A standard line-reader or AST source parser is completely blind here. Unless your tool can disassemble and parse the binary interface of `.dcu` files, any third-party library hidden inside compiled units will be completely missing from your SBOM.

🎈 The `.dfm` / `.fmx` File Trap (Visual Code & Hidden References)
Delphi isn't just `.pas` files. Forms (`.dfm` / `.fmx`) contain instantiated components, properties, runtime event hooks, and nested objects that aren't declared in the main source text. If your parser ignores form files, you are missing half of your visual and non-visual component stack.

🎈 Compiled Resource Files (`.res` / `.rc`)
Crucial dependencies, dynamic libraries (`.dll`), static code, and embedded manifests are frequently bundled directly inside binary resource files (`.res`). A text scanner won't see them. If you can't unpack and inspect dynamic resources, your SBOM won't reflect the actual compiled payload.

🎈 The `{$IFDEF}` Maze - Delphi codebases rely heavily on compiler directives (`{$IFDEF}`, `{$I}`). A unit declared in `uses` might be pruned out by the linker, or conditionally compiled based on target architecture and build configurations.

🎈 Call Graph Construction & Actual Usage vs. Unreachable Code - It’s not enough to know that a unit appears in a `uses` clause. To provide an accurate SBOM and properly assess CVE vulnerabilities, you need to construct a full Call Graph. Does your code actually execute functions inside Library X, or is it an unused import? Where in the call chain is that third-party code invoked? Without a Call Tree, your custom script cannot distinguish between active dependencies and unreachable code, leading to endless false positives during audits.

🛡 Beware of the "Ghost Code" - Ignoring all that will either report Ghost Code or miss your code entirely.

u/DelphiParser — 10 days ago
▲ 12 r/delphi

I built ESC Vision SDK — camera capture, recording and multi-camera tools for Delphi VCL

Hi everyone,

I’d like to introduce ESC Vision SDK, a Delphi VCL SDK I developed to make camera integration easier in Windows desktop applications.

The goal is straightforward: provide Delphi developers with a practical camera API without requiring each application to build the underlying camera and video infrastructure from scratch.

ESC Vision SDK currently provides:

• USB camera discovery
• Live camera preview
• Still-image capture
• MP4 recording with an in-application live monitor
• Multi-camera workflows and dashboards
• RTSP preview
• Optional FireDAC integration

The SDK also includes working VCL samples for Photo ID Capture, Camera Discovery, VCL Camera Preview, Camera Recording, and Multi-Camera Dashboard workflows.

Current package support is Delphi 13 VCL for Windows, Win32 and Win64.

Free Evaluation

A free evaluation is available for USB camera discovery, live preview, and still-image capture, so you can actually try the SDK before purchasing it.

All-in Developer License

The complete released SDK is US$40 for one developer and includes watermark-free capture, MP4 recording/live monitoring, multi-camera functionality, RTSP preview, FireDAC helpers, and royalty-free deployment of applications built with the SDK.

Payment is handled securely through PayPal, with the private installer/download link automatically delivered to the buyer after payment confirmation.

Website:
ESC Vision SDK — ESC Software

I’d particularly appreciate feedback from other Delphi developers. If you work with cameras, imaging, video capture, surveillance, ID/photo capture, or similar applications in Delphi, I’d be interested to hear what functionality you'd like to see in future releases.

Thanks for taking a look.

u/One-Cupcake-467 — 12 days ago