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

The Delphi Vcl.Forms.TApplication.ActionUpdateDelay unit is … milliseconds

Posted by jpluimers on 2016/11/24

Don’t you love relevant documentation…

There is no unit defined for the Vcl.Forms.TApplication.ActionUpdateDelay – RAD Studio API Documentation.

It is used inside the TAppliation.Idle to fire the (undocumented) TApplication.DoActionIdle method. When the value is zero or less, then each Idle call will result in an DoActionIdle call in turn calling TCustomForm.UpdateActions for any visible form.

UpdateActions in turn will call (for the form itself, all the form’s menu items and all the form’s controls) the TControl.InitiateAction which – if there is an associated ActionLink – will call the TBasicActionLink.Update which in turn will call the TBasicAction.Suspended and TBasicAction.Update methods of which the latter will call the TBasicAction.OnUpdate event if it is assigned.

In theory, the OnUpdate method for each action can even be called multiple times (because multiple controls on visible forms can point to it), but the real culprit is that TApplication.Idle as it can be called from these places:

  • TApplication.DoApplicationIdle
  • TApplication.HandleMessage (in a loop from TApplication.Run)
  • TCustomActionMenuBar.ProcessMenuLoop (in a loop)
  • TCustomRibbon.DisplayKeyTips (in a loop)

The last three (especially HandleMessage) can be disastrous as they can be called a lot (for instance when moving the mouse), and more often than not, the OnUpdate event handlers aren’t exactly CPU friendly.

A while ago I bumped into an application where the OnUpdate event handler for one action was called half a million time in under 5 minutes.

This clearly indicated a huge problem (besides using a full CPU core slowing down the application) as apparently something was broadcasting Windows Messages like crazy.

Investigating and Solving the message flood is on the back-log with a reasonably high priority, but the highest priority issue was fixing the high CPU usage in the first place.

Apparently more users suffer from this, as there is a Vcl.Forms.TApplication.ActionUpdateDelay property which TApplication.Idle uses to call the Windows API function SetTimer to rate-limit the TApplication.DoActionIdle call tree. Luckily SetTimer does have documentation on the unit of ActionUpdateDelay: it’s milliseconds.

I’ve set it to 10 as that updating the actions ~100 times a second is fast enough for this application.

–jeroen

via:

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

Delphi: function IsRunningFromNetwork – via Lars Fosdal. I will need this one day

Posted by jpluimers on 2016/11/24

If I ever need it: function IsRunningFromNetwork that is based on WNetGetConnection.


function IsRunningFromNetwork(const ServerName:String = 'BetYouCantFindThisServer'): Boolean;
const
pMax = 2047;
var
dt: UINT;
volpath: Array[0..pMax] of Char;
sVol: String;
sz: Cardinal;
begin
Result := False;
dt := GetDriveType(PChar(ExtractFilePath(ParamStr(0))));
if dt = 4
then begin
GetVolumePathNameW(PChar(LowerCase(ParamStr(0))), volpath, pMax);
sVol := StrPas(volpath);
if not ((pos(LowerCase(ServerName), sVol) <> 0) or (pos('\\', sVol) = 1))
then begin
if pos(':', sVol) <> 0
then begin
sz := pMax;
if WNetGetConnection(pChar(Copy(sVol, 1, 2)), volPath, sz) = NO_ERROR
then Result := (pos(LowerCase(ServerName), LowerCase(StrPas(volPath))) <> 0) or (pos('\\', StrPas(volPath)) = 1);
end;
end
else Result := True;
end;
end;

Thanks Lars; I copied it to a gist for easier WordPress handling.

–jeroen

via:

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

ReservedWordsOP.txt and ReservedWordsC.txt for use with java2op in Delphi

Posted by jpluimers on 2016/11/22

Since these files got missing again: [WayBackDoes anybody know where to get ReservedWordsOP.txt and ReservedWordsC.txt for java2OP.exe in bin\converters\java2op for Delphi 10.1 Berlin upd2? It also… – Rik van Kekem – Google+

Here they are:

Read the rest of this entry »

Posted in Delphi, Delphi 10 Seattle, Delphi 10.1 Berlin (BigBen), Development, Software Development | 2 Comments »

Hope this doesn’t repeat itself…

Posted by jpluimers on 2016/11/18

Nice error starting Delphi XE8:

[Window Title]
Error

[Content]
Registration procedure, Dbexpressentimpl.Register in package c:\program files (x86)\embarcadero\studio\16.0\Bin\DataExplorerDBXPluginEnt220.bpl raised exception class EWrapperError: Parameter MetaClass cannot be nil.
Do you want to attempt to load this package the next time a project is loaded?

[Yes] [No]

–jeroen

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

Why I always disable Castalia in Delphi

Posted by jpluimers on 2016/11/18

I wrote about disabling Castalia before. This is yet another reason why I disabled it: on a fresh install it will throw errors at startup like this one in XE8: [WayBackhttp://qc.embarcadero.com/wc/qcmain.aspx?d=139278

[20441569]{coreide220.bpl} IDEKbd... (Line 586, "IDEKbd.pas" + 0) + $79D
[20441523]{coreide220.bpl} IDEKbd... (Line 586, "IDEKbd.pas" + 0) + $757
[2044168B]{coreide220.bpl} IDEKbd... (Line 586, "IDEKbd.pas" + 0) + $8BF
[2078892A]{coreide220.bpl} KbClient.TKeyboardServices.AddKeyBinding (Line 1455, "KbClient.pas" + 10) + $19
[0DD556A9]{Castalia220.bpl} Castalianavbar.TCastaliaNavToolbarKeyBinding.BindKeyboard + $4D
[2078746B]{coreide220.bpl} KbClient.TIDEKBDFrameAPI.KeyboardChanged (Line 521, "KbClient.pas" + 10) + $16
[20788AF5]{coreide220.bpl} KbClient.CheckUpdate (Line 1490, "KbClient.pas" + 3) + $6
[20788C7E]{coreide220.bpl} KbClient.TKeyboardServices.AddKeyboardBinding (Line 1527, "KbClient.pas" + 31) + $2
[50067002]{rtl220.bpl } System.@IntfCast (Line 36449, "System.pas" + 12) + $0
[0DD55629]{Castalia220.bpl} Castalianavbar.TCastaliaNavToolbarInstallerD8.WndProc + $2D
[2108A075]{designide220.bpl} Events.TEvent.Send (Line 165, "Events.pas" + 2) + $11
[0041D2B7]{bds.exe } AppMain.PostCreateInit (Line 2095, "AppMain.pas" + 72) + $B
[50682FE9]{vcl220.bpl } Vcl.Controls.TControl.WndProc (Line 7245, "Vcl.Controls.pas" + 91) + $6
[50687B91]{vcl220.bpl } Vcl.Controls.TWinControl.WndProc (Line 10079, "Vcl.Controls.pas" + 158) + $6
[5068A86D]{vcl220.bpl } Vcl.Controls.TWinControl.Invalidate (Line 12027, "Vcl.Controls.pas" + 0) + $9
[500605B4]{rtl220.bpl } System.TMonitor.TryEnter (Line 17939, "System.pas" + 10) + $0
[507C1F58]{vcl220.bpl } Vcl.Forms.TCustomForm.WndProc (Line 4427, "Vcl.Forms.pas" + 206) + $5
[506871B0]{vcl220.bpl } Vcl.Controls.TWinControl.MainWndProc (Line 9786, "Vcl.Controls.pas" + 3) + $6
[50172DF4]{rtl220.bpl } System.Classes.StdWndProc (Line 16882, "System.Classes.pas" + 8) + $0
[507CB41F]{vcl220.bpl } Vcl.Forms.TApplication.ProcessMessage (Line 10352, "Vcl.Forms.pas" + 23) + $1
[507CB44A]{vcl220.bpl } Vcl.Forms.TApplication.ProcessMessages (Line 10374, "Vcl.Forms.pas" + 1) + $4
[0041DE2B]{bds.exe } AppMain.TAppBuilder.ApplicationActivated (Line 2264, "AppMain.pas" + 0) + $7
[50828C27]{vcl220.bpl } Vcl.AppEvnts.TCustomApplicationEvents.DoActivate (Line 201, "Vcl.AppEvnts.pas" + 1) + $E
[50829289]{vcl220.bpl } Vcl.AppEvnts.TMultiCaster.DoActivate (Line 422, "Vcl.AppEvnts.pas" + 5) + $8
[507CA8E6]{vcl220.bpl } Vcl.Forms.TApplication.WndProc (Line 9949, "Vcl.Forms.pas" + 126) + $C
[50172DF4]{rtl220.bpl } System.Classes.StdWndProc (Line 16882, "System.Classes.pas" + 8) + $0
[507CC78D]{vcl220.bpl } Vcl.Forms.TApplication.CancelHint (Line 11181, "Vcl.Forms.pas" + 6) + $D
[507CB41F]{vcl220.bpl } Vcl.Forms.TApplication.ProcessMessage (Line 10352, "Vcl.Forms.pas" + 23) + $1
[507CB462]{vcl220.bpl } Vcl.Forms.TApplication.HandleMessage (Line 10382, "Vcl.Forms.pas" + 1) + $4
[507CB795]{vcl220.bpl } Vcl.Forms.TApplication.Run (Line 10520, "Vcl.Forms.pas" + 26) + $3

 

–jeroen

Read the rest of this entry »

Posted in Castalia, Delphi, Delphi XE8, Development, QC, Software Development | 3 Comments »

Positive: Delphi 10.1 Berlin Update 2 is out – ISO links

Posted by jpluimers on 2016/11/15

Since I’m lazy and always misplace how to get the ISOs:

–jeroen

Reference: Positive: Delphi 10.1 Berlin is out; negative all Embarcadero HTTPS sites still vulnerable to DROWN attack « The Wiert Corner – irregular stream of stuff

Posted in Delphi, Delphi 10.1 Berlin (BigBen), Development, Software Development | 1 Comment »

Oh nice: the compiler settings in your .dproj files are not reflected in what Ctrl-O O emits in XE7

Posted by jpluimers on 2016/11/15

I need to test this with other Delphi versions:

Oh nice: the compiler settings in your .dproj files are not reflected in what Ctrl-O O emits as it always puts this as first line in your source code for Delphi XE7:

{$A8,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N-,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}

Which means that changing integer values in <DCC_Alighment> or <DCC_MinimumEnumSize> and boolean values in <DCC_Optimize> have no effect.

Bummer.

Source: Oh nice: the compiler settings in your .dproj files are not reflected in what…

I will officially report it as soon as https://www.ssllabs.com/ssltest/analyze.html?d=quality.embarcadero.com grades B or better.

And I need to find out if I can help determining which of these causes it via [WayBackThomas Mueller (dummzeuch) – Google+:

There are two possibilities:
1. The settings in the dproj file have no effect
2. The settings Ctrl-O O writes to the source file do not reflect the actual compiler settings but are hard coded instead.
(3. Both)

–jeroen

 

 

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

One of the #EKON20 running gags: Raize condition

Posted by jpluimers on 2016/11/11

When Ray Konopka enters the room you have a Raize condition.

Via the EKON20 sessions, it made its way into the workshop If you thought you could do multi-threading, then play “The Deadlock Empire” games – Entwickler Konferenz

–jeroen

Posted in Conferences, Delphi, Development, EKON, Event, Software Development | Leave a Comment »

Fixing `Unable to create ModelMaker Tools Shared Directory` and `Cannot create file “C:\HungarianTypeLookup.txt”. Access is denied.`

Posted by jpluimers on 2016/11/10

Like many Delphi 3rd party product, new ModelMaker Code Explorer (often abbreviated as MMX) releases have not been as thick as in the heydays (look at the history for versions 7, 8 , 9, 10, 11 and 12).

Unlike a lot of products it is still there, still very stable and hasn’t been acquired which it means it is available for a wide range of Delphi versions. So I still use it, but know certain issues will likely be never solved.

One of these issues is running ModelMaker Code Explorer as a different user than the installing user. In the authors words:

You need to install MMX as the same user that will run MMX.
MMX does not support running as a different user than the one installed.

This requirement becomes increasingly difficult to satisfy. This especially happens in more security conscious organisations where there is a clear distinction in rights between users that can install software and the ones that use the software. But it can also happen when you switch users because of infrastructure changes (new Windows domain, no Windows domain, etc).

Delphi itself copes reasonably well with that, as does GExperts, but MMX doesn’t. Despite the writeup on How to verify a Code Explorer installation? it lacks two things:

  1. explaining the below kinds of error messages when you run MMX with a different user than you installed MMX
  2. explaining some easy steps to fix this

As I roam a lot, I’ve spent about a day fiddling and writing up the below information:

Read the rest of this entry »

Posted in Delphi, Development, ModelMaker Code Explorer, Software Development | Leave a Comment »

Old Google Charting API: tools for still using them

Posted by jpluimers on 2016/11/10

While mocking the ScaleMM documentation, I bumped into a chart that I thought was an image, but is in fact generated by the (now deprecated) Image Charts API from Google.

In fact it is generated on the fly from a URL: http://chart.apis.google.com/chart?chxr=0,0,16|1,0,14682…&nonsense=something_that_ends_with.png

Compare the two below. They are identical (:

Static ScaleMM1 comparison chart

Static ScaleMM1 comparison chart

URL based ScaleMM1 comparison chart

URL based ScaleMM1 comparison chart

Even though the API is deprecated Google has no plans to turn it of, so it still works and is the easiest way to get charts into a Markdown or reStructuredText document.

In practice, it doesn’t matter if you use the chart.apis.google.com or chart.googleapis.com domain: they give the same results the same.

As I wanted to convert the results.txt to a chart, I dissected the above URL, looked up the definitions of the URL parameters (the trickiest: cds for lxy graphs and the combination of chds and chxr, easier: chls) and created a new URL for the chart below.

Read the rest of this entry »

Posted in Delphi, Development, Google, Power User, Software Development | Leave a Comment »