Why 64-bit comes up now.
A 32-bit Delphi 7 executable still runs on Windows 11. Windows 11 ships only for 64-bit processors, but its WOW64 layer runs 32-bit applications as every 64-bit Windows release has, so the executable itself is not what forces the question. Three things around it do.
The first is memory. A 32-bit process has a 2 GB user address space by default, and 4 GB on 64-bit Windows when the executable is flagged large-address-aware. Applications that load large datasets, long reports, or image data reach that ceiling as an out-of-memory error while the machine still has RAM to spare.
The second is bitness. A 32-bit process cannot load a 64-bit DLL, and the reverse is also true. Microsoft 365 and Office 2019 onward install 64-bit by default, and database clients, ODBC drivers, and vendor SDKs increasingly ship 64-bit first. Each is a boundary the 32-bit process cannot cross.
The third is the toolchain. Delphi 7 shipped in 2002; a 64-bit build needs a current compiler anyway, so the two questions arrive together.
The two jumps, and why the order matters.
Between Delphi 7 and any compiler that targets Win64 sit two breaking changes, and they are different kinds of change.
The first is Unicode. Delphi 2009 redefined String as UnicodeString, Char as WideChar, and PChar as PWideChar, and every version since inherits that, so any move off Delphi 7 goes through it. It is a source-level change: the edits land wherever the original developers treated a string as an array of bytes.
The second is the 64-bit compiler, which arrived in XE2 in 2011. A Win64 build is a target-platform change: the same source compiled with an 8-byte pointer, the x64 calling convention, a different floating-point model, and new rules for inline assembler. Most VCL and RTL code compiles for both platforms unchanged; the breaks concentrate in code that touches memory or Windows directly.
Doing both at once means every failure has two possible causes. Doing Unicode first, in 32-bit, means anything that breaks after the platform switch is a 64-bit problem by definition.
What breaks.
Seven categories, all from the compiler and the platform, not from any one application. Check your version for exact types.
- Strings and file I/O
- String, Char, and PChar are UTF-16 from Delphi 2009 on. Length as a byte count, Move on strings, PChar into ANSI APIs, and Char buffers written to disk all change meaning.
- Pointer-size assumptions
- A Win64 pointer is 8 bytes; Integer stays 4. Integer-to-Pointer casts, handles in Integer fields, and hand-computed Move or FillChar sizes fail; NativeInt exists for this. Extended becomes an alias of Double.
- Inline assembler
- Win64 does not allow assembler mixed into a Pascal routine: all assembler or all Pascal, in x64 instructions. Small helpers move to Pascal; the rest sits behind a platform conditional.
- Third-party components
- Every package needs a Win64 build for the compiler you choose. Shipping vendors usually have one; source can be ported; compiled-only units without a 64-bit edition must be replaced.
- The BDE
- There is no 64-bit Borland Database Engine. An application on BDE, Paradox, or dBASE needs a new data layer before a Win64 build is possible.
- 32-bit COM, ActiveX, and device DLLs
- A 64-bit process cannot load a 32-bit in-process COM server, ActiveX control, or vendor DLL; device SDKs are often 32-bit only. Options: a 64-bit edition, an out-of-process wrapper, or leaving that piece 32-bit.
- Win32 API declarations
- Hand-written externals with Integer for handles, WParam, LParam, or LRESULT, and SetWindowLong instead of SetWindowLongPtr, truncate 64-bit values. The Winapi units are correct; local copies are not.
A sequence that works.
Each step isolates one class of failure, so the cause of any error is known before anyone opens the debugger.
- Build 32-bit on a current compiler
- Same platform and pointer sizes, so every error here is a language or library change, mostly Unicode. Upgrade or replace components now, since current packages are what Win64 needs anyway, and replace the BDE if present.
- Establish the baseline
- Get the 32-bit build passing whatever tests exist and write the missing ones: file round-trips, report output, and calculations that touch money or measurements. The 64-bit build is compared against this.
- Add the Win64 target
- Add the platform to the project and compile. What breaks now is pointer sizes, assembler, external declarations, and missing 64-bit packages, and nothing else, because Unicode is already done.
- Run the test matrix
- Both builds on the same matrix: each Windows version you support, the real database, printers, and scanners. Keep the 32-bit build from the new compiler as the fallback.
When to stay 32-bit.
WOW64 is not a stopgap. It is a supported part of 64-bit Windows, and a 32-bit application built with a current Delphi is a fully supported configuration. Staying 32-bit is right when three things hold: the working set stays comfortably under 2 GB, or 4 GB with the large-address-aware flag; every DLL, driver, and COM server the application loads exists in 32-bit; and nothing on the roadmap changes either. It also keeps 32-bit-only components and device SDKs usable without wrappers.
What it does not buy is time on the compiler question. The Unicode migration and the component upgrade are required either way, and a current compiler is what turns a later Win64 target into a small step. The honest reason to stay 32-bit is a hard dependency with no 64-bit edition, not a wish to avoid the string work.
What the assessment inventories.
For a Delphi 7 codebase headed to 64-bit, the assessment reads the source, project files, and configuration and produces an inventory with counts and locations: units and forms; compiler directives and conditional defines; every third-party package, with vendor status, source availability, and whether a Win64 edition exists; data-access components by family, including BDE aliases; inline assembler routines; casts between Integer and Pointer, and records that carry handles; external declarations outside the Winapi units; COM and ActiveX interfaces; device SDKs and their bitness; file formats the application writes itself; and whatever test coverage exists.
Everything is read from source; nothing is run and nothing in production is touched. The output is a written recommendation, 64-bit now, 32-bit on a current compiler, or a different path, with the component and data-layer work listed. The fee is quoted after the free 1-hour consultation and creditable toward a subsequent modernization project.
Where Delphi 7 code breaks on the way to Win64.
| Break category | Typical symptom | Fix |
|---|---|---|
| Unicode strings | Garbled text; strings cut to half their length; wide characters reaching ANSI APIs | AnsiString or TBytes where bytes are meant; explicit encodings for text files |
| File and stream I/O | Files from the old build no longer read; record sizes doubled | Explicit on-disk types (AnsiChar arrays, fixed-width fields); keep read compatibility |
| Pointer-size assumptions | Access violations only in the 64-bit build; handles truncated | NativeInt instead of Integer casts; sizes from SizeOf; check every Move and FillChar |
| Inline assembler | Compiler error on mixed Pascal and assembler under Win64 | Rewrite helpers in Pascal; isolate the rest behind CPUX86 and CPUX64 conditionals |
| Third-party components | Package will not install for Win64; compiled-only library with no 64-bit edition | Vendor's current release; port from source; replace what has neither |
| BDE, Paradox, dBASE | No 64-bit BDE exists | FireDAC and a supported database before the platform switch |
| 32-bit COM, ActiveX, device DLLs | Class not registered; DLL fails to load in the 64-bit process | 64-bit edition; out-of-process COM wrapper; or keep that piece 32-bit |
| Win32 API declarations | Subclassing and message handlers misbehave only in 64-bit | Winapi units; SetWindowLongPtr and GetWindowLongPtr; NativeInt for WParam, LParam, LRESULT |
Common questions
Can Delphi 7 compile a 64-bit application?
No. Delphi 7 produces 32-bit Windows executables only. The first Delphi with a 64-bit Windows compiler was XE2 in 2011; every release since, through Delphi 13, targets Win64. A 64-bit build therefore starts with a move to a current compiler.
Does a Delphi 7 application run on Windows 11?
Yes, as a 32-bit process under WOW64, which is a supported part of 64-bit Windows. What stops working is the environment: the BDE, 32-bit-only drivers and COM servers, and the 64-bit Office and ODBC components a 32-bit process cannot load.
Should we do Unicode and 64-bit in one step?
Not unless the codebase is small. Unicode is a source change and Win64 is a platform change; combined, every failure has two candidate causes. Finish the 32-bit build on the current compiler, get the tests passing, then add the Win64 target.
Do we migrate Delphi 7 to Delphi 13 directly, or through intermediate versions?
Directly. There is no benefit in stopping at 2009 or XE2 on the way; the Unicode and 64-bit changes are the same whichever current compiler you land on. Check that every component you keep has a package for the version you choose.
What if a component or device SDK has no 64-bit version?
Three options: the vendor's current release, if one exists; a port from source, if you have it; or keeping that piece in a 32-bit process called through out-of-process COM. Failing all three, that dependency is the case for staying 32-bit for now.
How long does a Delphi 7 to 64-bit migration take?
It depends on the Unicode surface, the number of third-party components, and whether the BDE is involved; the bands on the Delphi modernization page apply. The assessment produces the inventory that fixes the estimate, and its fee is creditable toward the project.
Not sure where to start?
Start with a fixed-scope Legacy Software Assessment: a read-only review of your application’s source, database, configuration, logs, and architecture, ending in findings with evidence and a written recommendation. Quoted after the free 1-hour consultation; creditable toward a subsequent modernization project.