- You can use SynZip to replace your Zip library. In my case, I use Abbrevia component set for Zip and Unzip, but Abbrevia contains many units and if only the Zip and Unzip of functionality are used, it might be worth to using much more small SynZip
- You can replace your base64 routines with mORMot's as it is much faster when the data to be encode/decode is big
Thursday, October 27, 2016
Expierence of Enhancing existing projects with mORMot
Thursday, October 6, 2016
A disadvantage of UPX
When UPX compress your executable, it not only compress the code inside the executable, but also compress the resource data in the executable, thus the resource data becomes not readable for other applications, one scenario is that you compile message table into your executable and use this executable as the resource file for some settings such as use it as the value of "EventMessageFile" for defining your own Event Log source in the Windows registry, unfortunately, if you do so, firstly, the Event Log view will not find the descriptions for your event's ID and category, secondly it might crash your Windows Event Log service and even worse, the service might not be able to recover even its Recovery setting has been set up.
You can reproduce what I have say in following steps:
- Download UPX from https://github.com/upx/upx/releases/tag/v3.91 (latest release at the time this blog is written)
- Find an Event Log source from within "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application", whose EventMessageFile is an EXE and it has some events you can see them in Event Viewer
- Use UPX to compress the EXE you have found in step 2
- Restart the Event Log viewer if it is open
- Check the event then you can see that the first sentence is something lik "The description for Event ID xxx from source yyy cannot be found"
- Try to filter on current log to show event only from that chosen source, the event view might crashes because the Windows Event Log service has crashed by now in some cases.
Sunday, September 6, 2015
Migrate SVN repository to Mercurial repository
- Install hgsubversion:
- hg clone https://hgsubversion.googlecode.com/hg/ ~\hgsubversion
- Add below lines to %USERPROFILE%\Mecurial.INI
[extensions]
hgsubversion = ~/hgsubversion/hgsubversion - user hg help hgsubversion to confirm above installation
- Clone SVN repository:
- hg clone https://hostname/svn/repositoryname, if it requires authentication, use below command instead:
hg clone svn+https://hostname/svn/repositoryname to type in the username and password at the prompt, or
use “—config” to specify the username and password like hg clone –config hgsubversion.username=username
--config hgsubversion.password svn+https://hostname/svn/repositoryname
- hg clone https://hostname/svn/repositoryname, if it requires authentication, use below command instead:
- Upload the repository:
hg push <remote repository url>
Referrence:
http://blogs.atlassian.com/2011/03/goodbye_subversion_hello_mercurial/
Thursday, March 19, 2015
Bamboo on Demand–Failed to download artifact in the job
I was new to Bamboo on Demand and I added an Artifact Download Task into the default job trying to download an artifact built from another plan.
It looked nothing could be wrong as all the information were filled by choosing the value from the drop down boxes except that destination path.
But the truth was that the job failed due to failed to download the artifact. I checked the artifact, it was there, I checked the destination path,
no typo, same path used for its own artifacts which were built before I added the download task.
Comparing to other plans on the same Bamboo on Demand server, I found that the plan whose artifact was referenced to be download had
a small different setting from other plans. The difference was that the plan had not specified a folder for checking out the source code, i.e.,
in the Source Code Check out task, Checkout Directory is blank. By put in an folder name to this box and use the same folder as the start
folder in the Location box for Artifact setting, the problem solved!
Tuesday, May 20, 2014
I Spy Bad Code – Change Screen.Cursor
Recently, I have seen following code appeared again and again in one of application written in Delphi:
begin
…
Screen.Cursor := crHourGlass;
try
…except
Screen.Cursor := crDefault;
…
end; {try}
Screen.Cursor := crDefault;
end;
This code works in most of the time, but it does have one issue, it makes an assumption that the cursor was crDefault thus it change the cursor back to default before the end. What if the cursor is not default before entering this code block? We can improve the code as following thus it will restore the cursor to what it is before this code block:
begin
…
LSavedCursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
try
…except
Screen.Cursor := LSavedCursor;
…
end; {try}
Screen.Cursor := LSavedCursor;
end;
Or more proper way (in my opinion) is to use a try … finally block to protect the code block and it will guarantee the cursor will be restored:
begin
…
LSavedCursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
try
try
… //doing busy business code insert hereexcept
…
end; {try}finally
Screen.Cursor := LSavedCursor;end;
end;
Can it be improved further? The answer is YES and NO. If you are still using Delphi earlier than Delphi 2009, then the answer is NO, because we are going to use Anonymous Method which was introduced by Delphi 2009 and later version of Delphi.
With above code, you actually need to define the local variable LSaveCursor in each method in which it has above code, so it is a bit trivial, and you cannot refactoring above code to a method because the actually doing busy business code is vary from method to method, refactoring each doing busy business code to a method and then pass the method’s point will be a over kill approach. But with anonymous method, we don’t need to refactoring doing busy business code to a method, instead, we can pass the code as an anonymous method.
First we need to create a procedure to take care the logic for changing the cursor to hour glass and restore it when it completes. Below is the procedure:
procedure BusyDoing (AProc:TProc);
var
LSavedCursor : TCursor;
begin
LSavedCursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
try
AProc;
finally
Screen.Cursor := LSavedCursor;
end;
end;
This procedure has one parameter AProc which is a pre-defined anonymous method which is defined in unit System.SysUtils as
TProc = reference to procedure;
To use this procedure, all we need to do is enclose the doing busy business code as an anonymous method like this:
BusyDoing(
procedure
begin
… //doing busy business code insert hereend
);
That is it, very neat, isn’t it?
Sunday, March 16, 2014
Paint.Net 4.0 Beta is available
Now its version 4.0 beta is available for download. There is a feature in 4.0 which I like the most is “Copy Merged”. What it does is copy from all layers as one image, which is equivalent to what you have to achieve
by many steps in v3.5:
- Flatten the layers
- Copy all
- Undo the flattern
Thursday, March 6, 2014
My First Orchard CMS Website
I have inherited TheThemeMachine as the theme. I have restyled the menu bar so it
is not so techy. I have created a slider module (based on bxslider) for showing the
featured products. I use taxonomies for product category, Amba.ImagePowerTools
for product picture. I do not use Map module for showing Google Map, instead I use
HTML widget.