CodeCentral Submissions for Ray Vecchio Generated by Atom.NET 2020-05-28T08:49:39-07:00 A handy memory/handle usage logging tool. &lt;Fixes:22/02/2017&gt; Ray Vecchio 2017-02-23T09:19:27-08:00 2017-02-23T09:19:27-08:00 This is a handy memory/handle usage logging tool, to log various OS resources. This is a handy memory/handle usage logging tool, written in Delphi, but can be linked to a C++ application.The resources that will can be logged are GDI and User Handles (mainly, window handles), dump all the application's virtual memory usage, thread count etc. The zip file contains a few units, for simple logging of the various OS resource values. I also added a code for a package, installable in the IDE. (If you have Delphi or RADStudio, if want to use it, directly. I have also added a C++ package that can be installed into the IDE with memory logging code. This will output GDI and User Handle information into the Messages Pane, every time you switch to a new project. A log file will be created in the &quot;C:\temp&quot; directory as default, you can modify this location in &quot;IDELogMemoryUsageUnit.pas&quot;. You can also log memory usage after each codesight compile but this makes for very big logs.There is also a small console mode application. I used created the package track various memory issues in the IDE. Fix for Find in Files Dialog problems with Large Fonts Ray Vecchio 2017-02-23T03:51:55-08:00 2017-02-23T03:51:55-08:00 When large fonts are used the Find in Files dialog in the IDE is cut off, this package will, change the height and make the dialog resize-able. The attached code has a Delphi and a C++ package code (it links in the Delphi code), which monitors when the Search Dialog is shows and sets it to the correct size, it also makes the dialog resize-able. A QD tracer for Clang compiler on Windows.&lt;FIXED&gt; Ray Vecchio 2016-12-15T06:07:18-08:00 2016-12-15T06:07:18-08:00 A Quick and Dirty profiler/tracer for Clang compiler on Windows. Allows you to profile all compiled functions in your C++ application, built with the Clang based C++ compilers. This code makes use of a built in feature of the Clang compilers, when you specify &quot;-finstrument-functions&quot;, the compiler will then inject two functions into the entry and exit of each function that the compiler compiles. The added profile code will log to a file (and the debugger via an ODS, but this will slow execution) the function address and microseconds taken (it can handle nanoseconds). This function address can then be looked up in the MAP file for the application to get the function name.To make this tracer work add the following option to the compiler options list&quot;-finstrument-functions&quot; (w/o quotes) to the compiler options for the 64-bit compilerProject | Options | &quot;C++ Compiler&quot; | Advanced | &quot;Additional options to pass to the compiler&quot;for the 32-bit CLANG compilerProject | Options | &quot;C++ Compiler&quot; | Advanced | &quot;Other options&quot; | &quot;Additional options to pass to the compiler&quot;add the tracer source to your project, and build, the compiler will then inject the tracing functions into every entry and exit of each function it compiles.This now works in Seattle and Berlin. The Exemarker utility modifies/shows fields in a PE binary. Ray Vecchio 2016-07-05T03:50:21-07:00 2016-07-05T03:50:21-07:00 The Exemarker utility modifies/shows fields in a PE binary. It combines what is available in LAMarker and TimeMarker, but adds more flexibility. &lt;Update1&gt; Please use with care... The Exemarker utility allows you modify several characteristics of a PE binary, namely the File, DLL characteristics, as well as individual section characteristics, date time stamps and header checksums. Update1: added, the ability to zero-ing checksums. ***WARNING*** this *can* break your binary!! So use the tool with care and make sure you know what you are changing. The tool will always make a backup of the binary you want to modify before any changes are made. To see all the options just type &quot;exemarker&quot; at the command prompt. This utility to adjusts internal date time stamps of a binary. Ray Vecchio 2016-04-15T08:06:20-07:00 2016-04-15T08:06:20-07:00 This utility (TimeMarker.exe) adjusts the internal date time stamps of a binary's PE header and resource directories. This utility (TimeMarker.exe) adjusts the internal date time stamps of a binary. In the PE header and resource directories of a binary. It will also create a back up of any file before attempting to modify the binary.Copyright (c) Roy Nelson, supplied as Beerware.USAGE: TimeMarkerUSAGE: TimeMarker [options] -FFileName [-HC] [-T[F][datetime -&gt; &quot;dd/MM/yyyy hh:mm:ss&quot;]]Options :-Q Quiet-? Help-HC Recalculate and write header checksum.-T[datetime as &quot;dd/MM/yyyy hh:mm:ss&quot;] Sets PE datetime stamps. Example: &quot;15/04/2016 16:04:25&quot; (NB: with quotes),-TF means the specified the file's creation time will be used as the datetime stamp.To see available settings, execute &quot;TimeMarker -FFileName&quot;NOTE: The datetime format used will be different depending on your locale and your settings. LAMarker, a tool to set/unset Large Address Aware bits Ray Vecchio 2016-01-13T13:39:24-08:00 2016-01-13T13:39:24-08:00 LAMarker is a tool to set/unset Large Address Aware bits, in the PE header of a binary. LAMarker is a tool to set/unset Large Address Aware bits, in the PE header of a binary. It can be used for instance to make the XE3 and upwards C++ linkers Large Address Aware, and allow you use the -GH command line open to adjust the linker heaps.USAGE: LAMarkerUSAGE: LAMarker [options] -FFileNameOptions :-Q Quiet-? Help-M Mark as Large Address Aware-U Unmark as Large Address AwareIf no options are specified other than -Ffilename.exe then the PE header flags and checksum will be displayed.If you specified the -M or -U the original file will be backed up with the extension .old Using the LA marked linker you might see this issue more often (although you do see this occasionally in the normal linker):1) You have an application that just works...2) You move a control in the dfm, no code changes.3) MAKE... the application crashes in the start up code, in a number of cases it will be in the delayloading code.4) When you make some code change OR a clean and a build, the application will work again.To resolve this issue, you set the linker options to clear the state files before a link, (in the IDE Project | Options | &quot;C++ Linker&quot; | Advanced | Clear state before linking -&gt;TRUE, it is the &quot;-C&quot; option for the command line linker) this is counter productive for incremental linking, BUT you will not get this mysterious startup crash. &lt;Update3&gt;A temporary fix (imperfect) for Large Fonts R10 Ray Vecchio 2015-10-08T04:13:50-07:00 2015-10-08T04:13:50-07:00 &lt;Update&gt;A temporary fix (imperfect) for displaying very large text when Large Fonts are used, in RAD Studio 10 Seattle. This is a package you can build and install in the RAD Studio 10 Seattle IDE, (or in C++Builder 10) that adjusts the fonts to a default of 10 OR to the value you might have specified in the registry. More here: fixes added:1) TTabsets font reset2) second level modal forms' font is also now adjusted.To install the package, do the following:1) File | Open | Open Project and select the file &quot;FixLargeFontDialogs.dproj&quot; (for C++Builder users there is a subdirectory \CBPackage select &quot;CPPFixLargeFontDialogs.cbproj&quot;)2) the in the &quot;Project Manager&quot; normally on the right of the screen, Right-Click the &quot;FixLargeFontDialogs.bpl&quot; or &quot;CPPFixLargeFontDialogs.bpl&quot; for C++ users3) then you select &quot;Install&quot;, it will build and install into the IDE. 4) your dialog fonts should then look better A tool to terminate Android ADB when it locks files in the IDE Ray Vecchio 2015-09-11T02:58:42-07:00 2015-09-11T02:58:42-07:00 Under some circumstance it looks as if the Android ADB locks files and prevents the compilation or debugging of an application. &lt;New&gt; Under some circumstance it looks as if the Android ADB locks files and prevents the compilation or debugging of an application. This package will add an option under the &quot;Run&quot; menu that will run adb and allow it to cleanly terminate any servers left running in on your system. There is full source code to the package so you can modify it as you like, perhaps add call in the finalization code of the package to shut adb down when the IDE is closed too. I changed the package to check if there is an adb running and NOT read the location from the registry. External storage helper functions for Android Ray Vecchio 2015-03-10T09:13:07-07:00 2015-03-10T09:13:07-07:00 Miscellaneous &quot;flattened&quot; helper functions for Android external storage from the Environment class, for Delphi and C++ Miscellaneous &quot;flattened&quot; helper functions for Android external storage from the Environment class, for Delphi and C++ GetExternalStorageState: string;isExternalStorageWritable: boolean;isExternalStorageReadable: boolean;GetExternalStorageDirectory: string;GetDataDirectory: string;GetDownloadCacheDirectory: string;GetRootDirectory: string;getStorageState(FilePath : string) : string;isExternalStorageEmulated : boolean;isExternalStorageRemovable : boolean;//this does not work on all flavours of Androidfunction GetExternalSDCardDirectory: string;This is the most robust way of getting the SD cards locationsfunction GetSysSecondaryStorage: string;function GetSysExternalStorage: string;For C++ and Delphi add the .pas files to your project, then use &quot;Use Unit&quot; to add Androidapi.IOUtilsEx to your uses clause and in C++, to #include &lt;Androidapi.IOUtilsEx.hpp&gt; Source for an add-in to easily manage packages the IDE loads Ray Vecchio 2015-02-06T03:36:57-08:00 2015-02-06T03:36:57-08:00 Compile and install the add-in to allow you to easily specify what packages the IDE will load. This add-in will allow you to easily specify which packages will be loaded by the IDE, by modifying the IDE's registry key. ***WARNING*** If you use this package you can potentially cause the IDE not to be able to start up so please be *CAREFUL*. In this situation you can use regedit to rename the IDE registry key, 1) rename "HKCU\Software\Embarcadero\BDS\X.X" to "HKCU\Software\Embarcadero\BDSOld\X.X" 2) start the IDE as normal. How to use this code:1) Open and install the attached package code into the IDE.2) The go to Tools | Options | “Third Party” | “Package Editor” | Packages 3) Click on the packages you do *not* want to load up next time you start the IDE (NOTE: please heed the warning above)4) Click OK… if you have made any changes you will see a message telling you to restart the IDE.How you can make use of this package.1) You can either use the package to selectively change the functionality the IDE will have, when you restart the IDE. NOTE: some packages will automatically be loaded by the IDE irrespective of the registry changes, but in general it should heed the registry values.2)a) You can create various Windows shortcuts and specify specific "-r" options on the command line for the IDE for instance: "BDS.EXE -rlean" (without quotes) OR "BDS.EXE -rWin32Only" etc.b) Start the IDE from one these shortcuts.c) Install this package and specify JUST the packages you want to load for this configuration. d) So now when you start the IDE from this shortcut it will only load the packages/functionality you want.This package code should also work with earlier versions but the uses clauses will have to be edited, and then you will have to create a new project file. Releasing Unit cache to reduce out of memory errors in the IDE Ray Vecchio 2014-11-10T06:23:22-08:00 2014-11-10T06:23:22-08:00 This is a slightly modified version that that will only flush the cache for packages, and it now only flushes the cache after a compile. The package now flushes the cache after a debug session. The Delphi compiler, caches compiled units in memory. Due to Unicode strings, more RTTI, template support etc the unit sizes have grown over the years so they occupy more memory. Couple this with more packages being used in the IDE and possibly more 3rd party packages. One can see how it makes the compiler's job of allocating sufficient memory for this caching process very difficult. This package will flush the unit cache before each project compilation. The debugger also caches the debug information, after an application terminates, this version will now flush the cache after each debug session. This *will* cause a performs hit. Included is the code for this package kept as simple and as lean as possible. 64/32bit COM interop Ray Vecchio 2014-10-10T13:17:12-07:00 2014-10-10T13:17:12-07:00 Here an easy way to use 64bit COM classes in 32bit applications and vice a versa... I have created a simple unit to do the leg work.1) Create your COM automation objects as normal.2) add the unit &quot;COMDLLSurrogateUnit&quot;3) then modify the name of the TAutoObjectFactory to TAutoObjectDLLSurrogateFactoryHere is what the changes look like:&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt; unit ImplTest64bitCOMUnit; interface uses ComObj, ActiveX, COM64BitTest_TLB, StdVcl; type TTest64BitCOM = class(TAutoObject, ITest64BitCOM) protected procedure Testing; safecall; end; implementation uses ComServ, Dialogs, COMDLLSurrogateUnit; // heavy lifting unitprocedure TTest64BitCOM.Testing; begin ShowMessage(ClassName); end; initialization //***NOTE*** the new Automation class factory TAutoObjectDLLSurrogateFactory.Create(ComServer, TTest64BitCOM, Class_Test64BitCOM, ciMultiInstance, tmApartment); end. &gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;&gt;How it works...Essentially what the unit does it the follow, say you want to use a 32-bit application to call a 64bit COM class: 1) Create the 64bit COM class, make it an Automation object this should make life easier. 2) build and register the 64 bit COM DLL 3) use regedit and go to HKey_Classes_Root\CLSID\&lt;your GUID&gt; 4) Add a new string value called &quot;AppID&quot; and give it the same value as &lt;your GUID&gt; 5) now go to HKey_Classes_Root\Wow6432Node\AppID\ 6) add a new key with the same GUID as the CLSID i.e. &lt;your GUID&gt; 7) under the new key create a string value called &quot;DllSurrogate&quot; (without the quotes) and leave the data empty 8) the registry system should have mirrored the AppID in HKey_Classes_Root\AppID\&lt;your GUID&gt; 9) in the IDE in your 32bit application just link in the XXX_TLB.pas of the 64-bit COM class 10) and use COM object as normal. To use the COM classes in components in the IDE1) register and set up your 64-bit COM DLL as I previously described 2) you need to use the tlibimp from the \Bin64 directory to generate the component wrapping code. 3) create a package and add the generated file from 2) to the package and install the package.All of the information on how to accomplish this is found here: &lt;New&gt;Use MSBuild externally from the IDE, for all projects. Ray Vecchio 2014-03-11T05:35:42-07:00 2014-03-11T05:35:42-07:00 This tool can allow any project (Delphi and C++) to be built outside the IDE using MSBuild. This tool can allow any project (Delphi and C++) to be built outside the IDE using MSBuild, the log will then be displayed in the IDE's Messages pane as an &quot;MSBuild&quot; tab. A similar feature is available in XE2 but only for C++ projects. It is pretty simple and I'll extend it over time so different MSbuild option can be selected in Tools | Options at the moment I have not support it. The version will look for the latest MSbuild and use that, it will also use the multi-processor support available from .Net 3.5 upwards. 1) Build the project.2) Install the package in the IDE.3) You will now have a new menu item in Project |&quot;External MSBuild&quot; 4) and a submenu with items which are self explanatory5) There will now be properties you can set in the Tools|Options|ThirdParty | MSbuild options. (I might add more in the future, like choosing the number of processors you want he build to spread across, it defaults to 4 at the moment) 6) if no log file is chosen then the output is dynamically shown in the MSBuild message tab as the build proceeds, you can now also stop the build at any time. 7) best is give it a try and any feedback is welcome and if you extend it also fine let me know so I can also build it in... I have re-jigged the code a lot so please report any issues...I fixed a problem with usage of StrFloat on locales where the decimal separator is a not a &quot;period&quot;.To build it in XE3 you need to change some of the units in the uses clause to use the new namespaced units. A fix for Welcome Page, Stack Overflow at startup of 2010. Ray Vecchio 2013-10-30T05:56:54-07:00 2013-10-30T05:56:54-07:00 This package with source resolves the Stack Overflow and out of memory problem with the Welcome page. This package with source resolves the Stack Overflow and out of memory problem with the Welcome page. The problem is an issue with the languageStrings.xsl that causes a recursive call in the startup javascript, this problem only appears in very sporadic situations. All this does is clear the IE cache of the file mentioned above... 1) use REGEDIT and go to this registry key: &quot;HKEY_CURRENT_USER\Software\Embarcadero\BDS\XX.0\Known IDE Packages&quot;OR &quot;HKEY_CURRENT_USER\Software\CodeGear\BDS\XX.0\Known IDE Packages&quot;where XX corresponds to your version of Rad Studio/Delphi/C++Builder2) modify the data for this string &quot;$(BDS)\Bin\startpageideXXX.bpl&quot; again the value if XXX will depend of your version. Change the Data for the entry from: &quot;Start Page IDE Package&quot; to &quot;__Start Page IDE Package&quot; (by prepending two underscores to the string)3) start the IDE it should now start without the start up page appearing4) Open the FixStartPage.dproj in the IDE and build the package (this presumes that you got the IDE up and running by either not showing the Start up page or disabling it in the registry)5) in the Project Manager, right-click and choose &quot;Install&quot; 6) Shut the IDE down, 7) Reverse the registry modification in you did in steps 1) and 2) 8) Now every time the IDE starts the IE cache should be cleared, the Startup page should show and not cause a stack fault again.If you only have C++Builder installed:1) Run the &quot;RAD Studio Command Prompt&quot; 2) at the command prompt navigate to the location of the project file &quot;FixStartPage.dproj&quot;3) then run MSBuild as follows: &quot;MSBuild FixStartPage.dproj&quot; without the quotes. This should build the package aka &quot;FixStartPage.BPL&quot;. 4) in the IDE you can then install the package by going to Component | &quot;Install Packages&quot; | [Add...] select &quot;FixStartPage.BPL&quot; and click [Open] and then [OK]5) you can now repeat the 6) - 8) of the above instructions A unit and demo for simple HTMLHelp support in FMX Ray Vecchio 2013-07-01T03:06:22-07:00 2013-07-01T03:06:22-07:00 Allows the use of HTML Help in Firemonkey application, allow popups and Table of Contents, Keyword, and helpcontxt/HelpId HTML help. Lots more features can be added this can be used as an easy starting point. Allows the use of HTML Help in Firemonkey application, you can 1) use keyword help,2) HelpContext help3) Popup help based on the a HelpKeyword (this feature can be extend, it is just kept very simple in this version)4) Show the Table of ContentsTo use the unit, you must specify the location of the help file and register the form that will want the help support, this enable the WndProc for the form to be hooked and monitored for the WM_HELP message. I also added support for pressing Ctrl-F1, which will activate the popup, as FMX does not support the WS_EX_CONTEXTHELP style.Some caveats, to use the Keyword search you MUST make sure that:1) HelpContext value is set to an integer... any integer other than zero will do, this will tell FMX to same the keyword to the form file (.FMX)2) that you have text for the HelpKeyword3) the HelpType is set to htKeyWord4) if you press Ctrl-F1 you will also get a popup help, based in the Keyword text.5) copy the &quot;help.chm&quot; file to the same location as the EXE before testing the demo (there is a Delphi and C++ demo). A hack fix for RegisterWindowMessage Atom leak... Ray Vecchio 2012-09-07T09:11:37-07:00 2012-09-07T09:11:37-07:00 When launching Delphi applications multiple times these applications will leak atoms due the usage of RegisterWindowMessage (RWM) in Control.pas (or VCL.Controls.pas) NOTE: This *only* happens when the Controls unit is linked in. This can cause applications to fail with messages like &quot;not being able to create a window&quot; or &quot;not enough storage to complete an operation&quot; etc. The reason for the problem...1) the GlobalAtom table is actually a part of a bigger table that is used internally by the operating system, to store window classes, atoms, clipboard format AND more importantly RegisterWindowMessage (RWM) registered messages. Now unlike GlobalAtoms there is no corresponding Delete API to remove RWM messages, (my guess is as this global it is probably due to security/vulnerbility purposes). 2) You will have noted that GlobalAtoms are indeed correctly clean up, in the VCL code, but as you can see we CANNOT clean up the ONE RWM message we allocate. (this is done in (VCL.)Controls.pas InitControls) 3) Now the issue is, in Windows versions prior to Win2k8/Vista/Win7, this was far less of a problem because the process memory was not randomised... so the &quot;ControlAtomString&quot; always had the same value for the same application and the RWM value was reused by the OS, AND the OS did strictly enforce a limit on these atoms.4) The reason what the RWM was used in the VCL was specifically for drag/drop and docking support when a Windowed control was allocated in a statically linked DLL (ie one that does not use packages) because it allowed the VCL to NOT pass back a pointer to a control allocated in EXE to the DLL and viceversa. What is included in the zip file:1) the source to an application that will show the allocated atoms called Atomiser, the last column is important when you start any Delphi VCL application up and shut is down you will see the RWM atoms increasing. When you click on one of the items in the last two list boxes the caption will show which running application allocated the atom or RWM, if the caption is blank it means the application has terminated, but it can give report incorrect applications as the OS will reuse PIDs.2) There is a file called &quot;RWMFixUnit.pas&quot; that contains the hack, it replaces the call to RWM in the Controls unit and uses the GlobalAtom value (that will get cleaned up) instead of the leaky RWM. You HAVE to add this unit before the Controls (otherwise it will complain!) and it will only work in statically linked applications. I have simplified the implementation, so it will just reuse the global atom for the &quot;ControlOfs&quot; leak, all other RWM allocation will proceed as normal. 3) I have added a service version of atomiser that you can install as a service and will dump put a logfile every 10 seconds. This will show any leaks in the Windows Session used to run services.&lt;new&gt; The new version of the atomiser will now run on XP, and I have added a new fix unit that will fix both statically linked binaries and ones that use packages. So add either &quot;RWMFixUnit.pas&quot; OR &quot;RWMFullFixUnit.pas&quot; to your projects and make sure it is placed before then Forms or Controls unit in a project. AutoPlayCancel component. Ray Vecchio 2011-11-07T07:35:27-08:00 2011-11-07T07:35:27-08:00 This component installs an AutoPlayCancel handler, while the application is running and will intercept all autoplay notifications. The component installs a COM Object into the Running Object Table (ROT) by implementing the IQueryCancelAutoPlay interface. Any device that then activates an AutoPlay event, will cause the component to to be called. The component's eventhandler can then determine, from the information passed to it, to allow or disallow the autoplay. The COM object is only instantiated inside the application and does not need to regsiter in the global COM framework. It also handles the ability to be run in administrator mode. This Beerware, if you meet me in a pub one day, buy me a beer or more... Using Direct3D and TCanvas GDI improve speed in Vista. Ray Vecchio 2009-03-18T09:23:15-07:00 2009-03-18T09:23:15-07:00 Using Direct3D and TCanvas' GDI calls to improve graphics performance in Vista. Because of the modifications to the Vista Graphics subsystem the GDI calls are now routed along a different route to go to the Graphics driver, hence the GDI output show a significant drop in performance compare to Windows XP. Using the supplied control canvas one use Direct3D to get comparable performance to WinXP while still keeping the old TCanvas code.This is beerware...Roy Nelson#R;