The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,854 other subscribers

Archive for the ‘Delphi’ Category

GExperts 1.3.10 experimental twm 2018-06-03 – twm’s blog

Posted by jpluimers on 2018/06/14

I just saved it to [WayBackGExperts 1.3.10 experimental twm 2018-06-03 – twm’s blog.

It includes:

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

Delphi MS OpenXML files – ZIP and XML…

Posted by jpluimers on 2018/06/14

If I ever need to do OpenXML in Delphi: [WayBack] For some years i’ve had a subsystem that directly manipulates MS OpenXML files… – Dany Marmur – Google+

Summary:

  • Zipping: units from mORMot. Brilliant! Fast. Does not puke!
  • XML:ing: Oxml (kluug.net).

–jeroen

 

Posted in Delphi, Development, Software Development | Leave a Comment »

Delphi, IBX and the Turkish I problem

Posted by jpluimers on 2018/06/13

Last year, it took a while to reproduce and it is likely not fixed anytime soon: if you use Delphi and IBX (InterBase Express) to connect to either InterBase or FireBird database, then in the Turkish locale do not use lowercase SQL in your Delphi code as it will break on the

I’ve decided to put this in a separate post than the one I discovered the issue in as that one focused on the Unicode and language background of the various i/I/ characters and this post on the Delphi part.

So for the non-Delphi part, read Source: Field “id” not found and the The Turkish-İ/I/i/ı and case conversion – Update on the dasBlog Turkish-I bug and a reminder to me on Globalization – Scott Hanselman.

More recently, I learned that the same problem also happens in the Azeri language or Azerbaijani language – Wikipedia via [WayBack] SQL Instance Collation – Language Neutral Required:

uppercase / lowercase mappings (though this only impacts 2 characters — dotted and dotless “i”/”I” — and for only 2 cultures — Azeri and Turkish)

In general, this problem is called [WayBack] Case Folding and many environments do not have good and ready to use solutions for this.

Basically when working with case-insensitive language identifiers, you should always use culture invariant text comparison operations. In most languages, people use either lowercase or uppercase converted operations which for Delphi >= come down to using :

The reason is simple:

  • without any parameter, ToLower and ToUpper will use [Archive.isSysLocale.DefaultLCID.
  • without any parameter, LowerCase and UpperCase will implicitly behave as if called with TLocaleOptions.loInvariantLocale, but lots of people forget they do.

The functions ToLowerInvariant and  ToUpperInvariant  were added in Delphi XE3, but ToLower(LocaleID) and ToUpper(LocaleID) in Delphi XE4.

Instead of doing uppercase and lowercase comparisons you could also use the [Archive.isSystem.SysUtils.CompareText function.

IBX however uses case conversion, and by now you will probably guessed it: IBX got it all wrong. One reproduction is at https://gist.github.com/jpluimers/643b382944ff991d07ec96abbf85548c and a thread with background is at [WayBack] What’s the Delphi equivalent of doing UpperCase with an InvariantCulture in Unicode Delphi versions? (XE and up) – Jeroen Wiert Pluimers – Google+

IBX isn’t alone: just search for other uppercase issues like Turkish i to see tons of other issues.

For IBX, I did the replacements in the diff below to fix it in Delphi XE8. I only replaced where identifiers were compared, not were actual database content was compared.

Unluckily, in the past IBX sources were hosted on CodeCentral at http://cc.embarcadero.com/Author/102 but no new bundles have been released since 2012.

Of all the locations I think IBX should not have used any case conversion here:

IBX.IBDatabaseINI.pasfunction LocalServerPath(sFile: string): string

This function uses LowerCase() but I think an NTFS specific comparison should have been used, but I’ve not investigated into a solution for that yet.

–jeroen

Read the rest of this entry »

Posted in Delphi, Delphi 10 Seattle, Delphi 10.1 Berlin (BigBen), Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Delphi XE7, Delphi XE8, Development, Software Development | Leave a Comment »

Grammar Zoo – Browsable Borland Delphi Assembler Grammar

Posted by jpluimers on 2018/06/12

Interesting: [WayBackGrammar Zoo – Browsable Borland Delphi Assembler Grammar.

It is very complete, including constructs like the [WayBackspecial directives VMTOFFSET and DMTINDEX for Delphi virtual and dynamic methods.

You can contribute to it using https://github.com/slebok/zoo/tree/master/zoo/assembly/delphi

–jeroen

Posted in Assembly Language, Delphi, Development, Software Development, x86 | Leave a Comment »

[dcc32 Fatal Error] MyProject.dpr(23): F2051 Unit GUITestRunner was compiled with a different version of DUnitX.TestFramework.ITest

Posted by jpluimers on 2018/06/12

If you ever get an error like these in Delphi XE8 and up

[dcc32 Fatal Error] MyProject.dpr(23): F2051 Unit GUITestRunner was compiled with a different version of DUnitX.TestFramework.ITest
[dcc32 Fatal Error] MyProject.dpr(23): F2051 Unit TextTestRunner was compiled with a different version of DUnitX.TestFramework.ITestListener

then you are likely your project is:

  • using a DUnit based test project in Delphi
  • not having the unit search paths defined

Solution:

  1. add this directory to your project search path: $(BDS)\source\DUnit\src
  2. ensure your project DCU output directory is writable

–jeroen

Posted in Delphi, Development, Software Development | 1 Comment »

One more reason to have an ARC win32 compiler: tracking down memory leaks efficiently

Posted by jpluimers on 2018/06/07

One of the reasons it is so hard to write ARC a compatible source base is that there is no Delphi ARC win32 compiler. So you have to debug your memory issues using the remote debugging capabilities which – besides very slow – are unstable at best.

This is the number 1 reason I have been asking for a Delphi ARC win32 compiler integrated with the native Delphi win32 debugger (in addition to the current Win32 non-ARC compiler). Hopefully [WayBack] A second example of memory usage/leaks on linux using TTask (but only running one at a time) inside a loop will show memory usage increasing depending o… – Andrew Pratt – Google+ will give Embarcadero more motivation to eventually develop one.

This besides the fact that anyone writing for ARC should buy+read [WayBack] Delphi Memory Management eBook for classic and ARC compilers via [WayBack] I have some questions about Linux & ARC and I’m hoping some experts can share their expertise because I’m not understand the results I’m seeing. For th… – Andrew Pratt – Google+

(see also [WayBack] How to free a component in Android / iOS – Stack Overflow and Delphi ARC: Free versus DisposeOf (via: Ondrej Pokorny – Google+))

–jeroen

Posted in Delphi, Development, Software Development | 3 Comments »

High DPI Patches For Delphi | The Art of Delphi Programming

Posted by jpluimers on 2018/06/06

Reminder to self to install the [WayBackHigh DPI Patches For Delphi | The Art of Delphi Programming from the [WayBack] download zip.

–jeroen

Via: [WayBack] Some things just need their time: – Uwe Raabe – Google+

Posted in Delphi, Development, Software Development | Leave a Comment »

Delphi 10.2 Tokyo: they did not fix the broken documentation tab in 10.2.2 2004, but it is an “easy” fix to do yourself

Posted by jpluimers on 2018/06/06

Since the fix is on the forums server (singular!) and that one tends to be squirrel driven lately, here it is in full via [WayBack] I see they didn’t fix the broken documentation tab in 10.2.2 2004 (professional). It’s not a show stopper but a nuisance to fix oneself. And for new dev… – Herbert Sauro – Google+ and [WayBack] I have installed Delphi 10.2.2 and the Documentation tab is all stuffed up ( see picture ). I know there is a html template page for the welcome tab, bu… – Tony Danby – Google+

In C:\Program Files (x86)\Embarcadero\Studio\19.0\Welcomepage\en

Edit Documentation.htm and insert the one piece about the innerWidth

function setFrameURL(url)
        {
            if(url){
                document.getElementById('load_html').src = url
                $("#load_html").css("display", "block");
                var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;         
                $("#load_html").css("height",(height)+"px");    
                var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;         
                $("#load_html").css("width",(width)+"px");  

It works and takes up the entire page after you restart the IDE.

If it gets up: https://forums.embarcadero.com/thread.jspa?threadID=271798

–jeroen

 

Posted in Delphi, Delphi 10.2 Tokyo (Godzilla), Development, Software Development | Leave a Comment »

Delphi versions that can convert .bpg to .groupproj files

Posted by jpluimers on 2018/06/05

Reminder to self: extend the below very incomplete list of Delphi versions that can open a Borland Project Group file with extension .bpg (from the Delphi <= 7 era) and convert it to an XML based Group Project file with extension .grouproj (from the Delphi >= 2007 era).

  • Delphi 2007

Notes:

The .bpg file is actually a makefile, see for instance [WayBackbuild – How to compile a Delphi 7 project group file (.bpg) using the command line? – Stack Overflow

Delphi 2006 and 2005 use .bdsgroup files:

The .bdsgroup files are not compatible with .groupproj files in Delphi 2007 and up: [WayBackdelphi – How to convert a D2009 .groupproj file to a D2006 .bdsgroup file? – Stack Overflow.

A .grouproj file is basically an msbuild 2013 subset, see the below links for more info:

I needed this so I could make this conversion:

–jeroen

PS: Searching for the .groupproj links also got me this: [WayBackParallel compilation of delphi projects through MSBuild – Stack Overflow

Posted in Delphi, Development, Software Development | Leave a Comment »

“Unknown function at TMethodImplementationIntercept”

Posted by jpluimers on 2018/06/01

Reminder to self: when you get Unknown function at TMethodImplementationIntercept in a Delphi stack trace from the Exception.StackTrace property or FastMM memory report:

  1. Ensure you generate a .MAP or .TDS file with full debug information
  2. Copy the .MAP or .TDS files to directory of your EXE.

Via:

The Exception.StackTrace was introduced in Delphi 2009 that extended these [WayBackException Members:

Some notes:

  • Fields where you can put hooks in; if there is no hook in place, they won’t be used:
    • [WayBackException.GetExceptionStackInfoProc Field GetExceptionStackInfoProc: function (P: PExceptionRecord): Pointer;
      • This function is called to return an opaque data structure that contains stack information for the given exception information record. This function will be called when the exception is about to be raised or if this is an external exception such as an Access Violation, called soon after the object is created.
    • [WayBackException.CleanUpStackInfoProc Field CleanUpStackInfoProc: procedure (Info: Pointer);
      • This function is called when the destructor is called to clean up any data associated with the given opaque data structure.
    • [WayBackException.GetStackInfoStringProc Field GetStackInfoStringProc: function (Info: Pointer): string;
      • This function is called to return a string representation of the opaque data structure returned by GetExceptionStackInfoProc

TMethodImplementationIntercept was introduced in the System.Rtti unit of Delphi XE6 [WayBack]:

–jeroen

Example code:


unit ExceptionHelperUnit;
interface
uses
System.SysUtils;
type
ExceptionHelper = class helper for Exception
public
function Describe: string;
class procedure RaiseNotImplementedException(const aClass: TClass; const aMethodName: string);
class function GetStackTrace: string;
end;
implementation
uses
System.RTLConsts,
System.SysConst;
type
EStackTraceException = class(Exception); // EProgrammerNotFound to make it really clear this is only to be used in very limited places ??
{ ExceptionHelper }
function ExceptionHelper.Describe: string;
var
lStackTrace: string;
begin
Result := inherited ToString();
if Self is EInOutError then
if Result = System.RTLConsts.SInvalidFileName then
Result := System.SysConst.SInvalidFileName;
if Assigned(StackInfo) then
lStackTrace := StackTrace
else
lStackTrace := 'empty';
Result := Format('Exception'#13#10'%s at $%p: %s'#13#10'with StackTrace'#13#10'%s', [ClassName, ExceptAddr, Result, lStackTrace]);
end;
class function ExceptionHelper.GetStackTrace: string;
begin
try
Result := 'Get StackTrace via Exception.';
raise EStackTraceException.Create(Result) at ReturnAddress;
except
on E: EStackTraceException do
Result := E.StackTrace;
end;
end;
class procedure ExceptionHelper.RaiseNotImplementedException(const aClass: TClass; const aMethodName: string);
begin
raise ENotImplemented.CreateFmt('Method %s.%s is not implemented.', [aClass.ClassName, aMethodName]);
end;
end.

Posted in Delphi, Development, FastMM, Software Development | Leave a Comment »