<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Blog OnKeySoft</title>
	<atom:link href="http://blog.onkeysoft.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.onkeysoft.com</link>
	<description></description>
	<lastBuildDate>Tue, 24 Apr 2012 08:50:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Delphi: Add log to your software with Codesite / SmartInspect / Your own method</title>
		<link>http://blog.onkeysoft.com/2012/04/24/delphi-add-log-to-your-software-with-codesite-smartinspect-your-own-method/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=delphi-add-log-to-your-software-with-codesite-smartinspect-your-own-method</link>
		<comments>http://blog.onkeysoft.com/2012/04/24/delphi-add-log-to-your-software-with-codesite-smartinspect-your-own-method/#comments</comments>
		<pubDate>Tue, 24 Apr 2012 08:22:01 +0000</pubDate>
		<dc:creator>remixtech</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Reviews]]></category>
		<category><![CDATA[codesite]]></category>
		<category><![CDATA[debug]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[smartinspect]]></category>
		<category><![CDATA[tool]]></category>

		<guid isPermaLink="false">http://blog.onkeysoft.com/?p=281</guid>
		<description><![CDATA[In this post I will expose and compare some features of different applications logging system (Which are sort of debugging tools for us).  I will give you some keys and some tips to choose the most adapted Logging system for you. This article will deal only with Delphi applications. Have your ever live this situation? [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I will expose and compare some features of different applications logging system (Which are sort of debugging tools for us). <span id="more-281"></span></p>
<p>I will give you some keys and some tips to choose the most adapted Logging system for you. This article will deal only with Delphi applications.</p>
<h2>Have your ever live this situation?</h2>
<p><img title="warnings_32" src="http://blog.onkeysoft.com/wp-content/uploads/2012/03/warnings_32.png" alt="" width="32" height="32" align="absmiddle" /> Just replace the underlined Italic Text to get your favorite situation!<a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/Title.png"><br />
</a></p>
<blockquote><p>User 1: <strong>Hi</strong>, I have a problem with <em><span style="text-decoration: underline;">your software</span></em> when I click on the button it doesn’t work he must <em><span style="text-decoration: underline;">do this thing</span></em>, after that the software crashes and I’m losing all my work….</p>
<p>User 2: <strong>Hello, </strong>Today I try a <em><span style="text-decoration: underline;">new function</span></em> but it looks like doesn’t working as expected. For proof I haven’t successfully <em><span style="text-decoration: underline;">done this thing.</span></em></p>
<p>User 3: <strong>Hi</strong>, Your software is great but after two weeks, it’s so slow, what is the problems?</p>
<p>User 4: Hi, <span style="text-decoration: underline;"><em>you app</em></span> is really unstable when I use <span style="text-decoration: underline;"><em>too much objects</em></span>.</p></blockquote>
<p>Personally I hate this !  WTF? What is “<em>The button</em>”? What are you doing with &#8220;<em>this function&#8221; </em>? Before using &#8220;<em>this function</em>&#8221; ? Fortunately, when there is a bug, there are often more messages from many customers and you get some precious clues!<br />
Generally I send another mail to have more information. Waiting for the hypothetical answer, I’m trying to search the code. But if it isn’t reproducible this is really difficult.</p>
<h2>First solution doing your own Log Solution:</h2>
<p>For my application, I started to code a log viewer and integrate an object <em><strong>TDBB_LOG </strong></em>which handle everything when I need to log things. It&#8217;s a derivated class from TDatabase (it&#8217;s mine) which contains all the necessary tools when I need to deal with SQLite Databases. So as you see it&#8217;s a really simple class which show a procedure named add_log. I used this procedure to add something to the LOG database.</p>
<pre> TDBB_LOG = class(TDatabase)
private

public

constructor Create(const the_pass: string); reintroduce; overload;
destructor Destroy; override;

procedure Add_log(const Processus, Description, Groupe: string; const Level: TLOG_Level; const Resultat: TLOG_Result);
procedure Listing_LOG(Retour: TObjectRetour; const SQL_END: string);

protected
end;

var
BDD_Log: TDBB_LOG;</pre>
<p>And the two type :</p>
<pre>
// Type pour le log
// ---------------------
TLOG_Result = (tlr_normal, tlr_warning, tlr_error);
TLOG_Level = (tll_highest, tll_high, tll_normal, tll_low, tll_lowest);
</pre>
<p>It was working pretty great; I had created a G.U.I to allow the user to see the log.</p>
<p>&nbsp;</p>
<div id="attachment_283" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/03/im0.png"><img class="size-medium wp-image-283" title="im0" src="http://blog.onkeysoft.com/wp-content/uploads/2012/03/im0-300x174.png" alt="" width="300" height="174" /></a><p class="wp-caption-text">My old log viewer</p></div>
<p>The user could select time/date interval, the number of log entries to show and the type of entries (normal, warning, error). I also add a way to expand and contract some categories, sorting, moving, re-sizing column&#8230;</p>
<div id="attachment_290" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/03/im1.png"><img class="size-medium wp-image-290" title="im1" src="http://blog.onkeysoft.com/wp-content/uploads/2012/03/im1-300x181.png" alt="" width="300" height="181" /></a><p class="wp-caption-text">It works !</p></div>
<p>At the beginning it was ok, but after some times, I realize that it was not the alpha and the omega. A lot was missing ; the performance was not fantastic (but not bad at all). And I had no time to spend more on this. My goal was to integrate a complete logging framework to correct bugs very fast and provide a good experience for my customer when they have a problem.</p>
<p>I also really would like to have a remote (and secure) access to the log for beta testers. But it will cost me again, time&#8230;</p>
<p><span style="color: #008000;"><strong>Pros:</strong></span></p>
<p>-         Price! It&#8217;s free !<br />
-         You have the Full Source, and you are not dependent of updates.<br />
-          You are doing what you want and you have access to everything In your app.<br />
-          The log system and viewer are directly in your app.<br />
-          No extra app and extra code from strangers.<br />
-          Maybe more secure?<br />
-          You add only needed things but you are often disappointed when the problem occurred and you forgave something…<br />
-          You could be proud of you : D, it&#8217;s your own logging system.</p>
<p><strong><span style="color: #800000;">Cons:</span></strong></p>
<p>-          It takes you time, and you don’t have time.<br />
-          It’s full of bugs, and it’s not reliable at the beginning.<br />
-          The log viewer is not “great” for hunting bugs and problems, really, you haven’t time to create a first world class viewer.<br />
-          The log system and viewer are directly in your app (And if it crashes?)<br />
-          You must code well and pay attention to every detail. Databases, Thread Safety, …<br />
-          The log file and viewer will not be optimized at first.<br />
-          You must code the remote access, it will takes time to code, test, debug&#8230;<br />
-          How to manage multiple instances of software ? Tobject, published property ? (-&gt; Need to code more&#8230;)<br />
-          If you have a Suite (multiple applications for one software), it will takes you again time (If you have a thread safe log manager, it will not be very long, I guess.)</p>
<p>Rate : <img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_481.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_481.png" alt="" width="48" height="48" /></p>
<p>It&#8217;s not an exhaustive list and not fully objective, forgive me I&#8217;am not omniscient.</p>
<p>Surfing on the web for a solution I found two solutions to handle logs without spending too much times coding it : <a title="SmartInspect Website" href="http://www.gurock.com/smartinspect/" target="_blank">SmartInspect</a>  by Gurok and <a title="CodeSite Raize" href="http://www.raize.com/devtools/codesite/" target="_blank">CodeSite</a> by Raize (which is provide in an express edition by Embarcadero in Delphi XE and Delphi XE2).</p>
<p>We will see the pros and cons of theses two solutions.</p>
<h2>CodeSite by Raize :</h2>
<p>CodeSite Studio/Express is a third-party tool developed by Raize Software (<a href="http://www.raize.com/">http://www.raize.com</a>), an US enterprise directed by Ray Konopka. When you have questions, the support is fast, reactive and competent. The express version is available when you bought Delphi; it’s a third party tool integrated since Delphi XE. Usually when Embarcadero/Borland says “express” edition from, you must hear limited version. It’s a sort of Trial without time restriction but with fewer functions.</p>
<p>Let’s look at the description:</p>
<blockquote><p>“The CodeSite Logging System gives developers deeper insight into how their code is executing, which enables them to locate problems more quickly and ensure their application is running correctly. CodeSite&#8217;s logging classes let developers capture all kinds of information while their code executes and then send that information to a live display or to a log file. Furthermore, both styles of logging, live logging and file logging, can be performed locally or remotely.”</p></blockquote>
<p>So in order to use CodeSite logging system, you need two things:</p>
<ol>
<li>Adding CodesiteLogging unit to your project. In fact when you will add it, some methods will be accessible.</li>
<li>Running a “Dispatcher” (I will explain just after) in background! Even if you are the customer! It’s needed, it’s not an option!</li>
</ol>
<p><strong>How CodeSite is working?</strong></p>
<p>When you add CodeSiteLogging.pas in uses, a TCodeSiteLogger Object is created in initialization section. This object is accessible with the variable CodeSite in your unit Implementation.</p>
<p>&nbsp;</p>
<div id="attachment_305" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/2.png"><img class="size-medium wp-image-305" title="2" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/2-300x231.png" alt="" width="300" height="231" /></a><p class="wp-caption-text">Don&#39;t forget to add CodeSiteLogging.pas</p></div>
<p>&nbsp;</p>
<div id="attachment_303" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/Shema.png"><img class="size-medium wp-image-303" title="Shema" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/Shema-300x103.png" alt="" width="300" height="103" /></a><p class="wp-caption-text">How CodeSite works ?</p></div>
<p>This CodeSite object will send all the log-informations using SendMessage (<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms632590%28v=vs.85%29.aspx">http://msdn.microsoft.com/en-us/library/windows/desktop/ms632590%28v=vs.85%29.aspx</a>) to send the information to the dispatcher. The goal of the dispatcher will be to “dispatch” the data to the log viewer, to a remote computer (Tcp/ip using Indy) or to a log file….</p>
<p>That’s why you NEED to have the dispatcher running!</p>
<p><strong>About the dispatcher:</strong></p>
<p>It’s an app provided by Raize (you don’t have sources). It’s redistributable and free for your users. So if a user wants to have logging features working on his computer he will need to Install the software from Raize…</p>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/3.png"><img class="aligncenter  wp-image-304" title="3" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/3.png" alt="" width="150" height="149" /></a><strong>Here you see what are the command line option of this redistribuable packages :</strong></p>
<pre>“// The CodeSite Tools can be installed silently by specifying some
// command line options when executing the CS4_Tools.exe program.
//
// To run CS4_Tools in silent mode, use the following options:
//
//     CS4_Tools /s
//
// The above statement will install the CodeSite Tools using default settings.
// Specifically,
//
// 1. All Tools are installed (Dispatcher, Controller, File Viewer, Live Viewer)
// 2. NO program group is created for the installed Client Tools
// 3. The Dispatcher runs in Stealth mode
//
//
// If you would like to change any of the defaults, you can run the setup
// program with the following options:
//
//     CS4_Tools /s /m=CodeSiteToolsSetup.txt
//
// The above statement also runs the setup program silently, but also allows
// the various setup options to be customized.  By specifying this file, in
// the /m parameter, the following settings can be customized as needed.

// Set to NO to prevent the CodeSite Controller from being installed
INSTALL_CONTROLLER=YES

// Set to NO to prevent the CodeSite File Viewer from being installed
INSTALL_FILE_VIEWER=YES

// Set to NO to prevent the CodeSite Live Viewer from being installed
INSTALL_LIVE_VIEWER=YES

// Set to YES to create a program group for installed client tools
CREATE_PROGRAM_GROUP=NO

// Set to STEALTH, RESTRICTED, or UNRESTRICTED
DISPATCHER_MODE=RESTRICTED”</pre>
<p>Personally I don’t like this. It’s not “<em>cool</em>” to force the user to install software from another company to use all the capability of yours. Silent installation is not a great choice for the user (I don’t want to force them to install third-party tool! It could be problematic in the futur…). Finally I don’t know if Raize gives the sources for the dispatcher, I think it’s a minimum (I hope). If I could recompile it, and adapt the gui to integrate it in my software suite it could be great. But it’s not.</p>
<p>Now it’s time to log:</p>
<p>If you want to trace your CodeSource you will need to add a lot of lines of code (like always)! What are the CodeSite procedures to send log?</p>
<p>Please look at the example below, you will understand very fast.</p>
<pre>procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
// When you want to send a simple message
CodeSite.SendMsg(csmWarning, 'Message');
// If you want to send the published property of a TObject by example
CodeSite.Send(csmYellow, 'The form !', Form1);
// If you want to send an exception
CodeSite.SendException(Exception.Create('It''s an exception'));
// If you want to send a Color
CodeSite.SendColor('A color', clred);
// If you want to send a warning
CodeSite.SendWarning('Blablabla');

// Add a separator
CodeSite.AddSeparator;

for i := 0 to 5 do
begin
// Add a checkpoint
CodeSite.AddCheckPoint;
end;

// Add a separator
CodeSite.AddSeparator;

// Another great thing is to indent log in order to have a clearer view
CodeSite.EnterMethod('A METHOD');
try
// Send a screenshot of the form
CodeSite.SendScreenShot('ScreenShot', self.Handle);

CodeSite.EnterMethod('Imbricated Method');
try
// Send Version info
CodeSite.SendVersionInfo(csmInfo);
finally
CodeSite.ExitMethod('End of it');
end;

finally
CodeSite.ExitMethod('End of A METHOD');
end;

end;</pre>
<p>Let&#8217;s see the result on the live viewer :</p>
<div id="attachment_307" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/4.png"><img class="size-medium wp-image-307" title="4" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/4-300x175.png" alt="" width="300" height="175" /></a><p class="wp-caption-text">The CodeSite log viewer</p></div>
<p>There is a way to integrate faster Codesite loc : the templates.</p>
<div id="attachment_311" class="wp-caption aligncenter" style="width: 214px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/5.png"><img class="size-medium wp-image-311" title="Codesite Templates" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/5-204x300.png" alt="" width="204" height="300" /></a><p class="wp-caption-text">Templates</p></div>
<p>You have a lot more functionality like creating different levels for entry, changing color, add separator, reminder etc&#8230; I&#8217;am not using daily CodeSite so my judgement is surely subjective&#8230; But this is the list of the pro and cons for me.</p>
<p><span style="color: #003300;"><strong>Pros:</strong></span></p>
<p>-       VERY EASY TO USE !!!!!<br />
-       Price! The express edition is free in Delphi XE/XE2&#8230;<br />
-       With &#8220;<em>CodeSite Method Tracer expert</em>&#8221; you could insert in every method (code) the EnterMethode and LeaveMethod lines of code.<br />
-       It&#8217;s really reliable, you don&#8217;t have to reinvent the wheel.<br />
-       Great Support !<br />
-       Viewer is great. You could filter, search, add breakpoint and a lot of other stuffs.<br />
-       Ability to log TObject, to indent method, to send to a remote machine, etc&#8230;<br />
-       Plugins could be added.<br />
-       Communication with Messages is great and fast (too much messages slowdown Windows). (No Firewall is triggered). You could use TCP/IP if you want.<br />
-       It&#8217;s pretty easy to log multiple software. If you are developing a Suite ?</p>
<p><span style="color: #ff0000;"><strong>Cons:</strong></span></p>
<p>-       The express edition is limited&#8230;<br />
-       The price !! 400$ !<br />
-       The dispatcher is not the best solution for me. I don&#8217;t want to add several tools for every functionality of my software.<br />
-       If there is a bug and Raize don&#8217;t want to correct it, you will be in trouble.<br />
-       I don&#8217;t think the dispatcher source is available. You are launching a blackbox on customer computer&#8230;</p>
<p>Rate : <img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_481.png" alt="" width="48" height="48" /></p>
<h2>SmartInspect by Gurok :</h2>
<p>The last but not the least : SmartInspect by Gurok. It&#8217;s a German product. This is my favorite one and the solution I choose for my software. Don&#8217;t forget it&#8217;s just a point of view. Please keep in mind that I&#8217;am not a Delphi Guru.</p>
<h4>Log what you want, in the format you want :</h4>
<p>Smartinspect is providing as much Codesite provide but with small differences. I will detail the ones I have found. And show you how it works in my application.</p>
<p>One thing I love is the ability to easily change at runtime/designtime the way of SmartInspect is managing the log. Gurok is providing a tool named &#8220;SmartInspect Configuration Builder&#8221; which is designed to help you to create &#8220;configuration file&#8221;. Don&#8217;t worry you are not forced to use theses.</p>
<div id="attachment_318" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/1.png"><img class="size-medium wp-image-318" title="SmartInspect Configuration Builder" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/1-300x230.png" alt="Configuration Builder Main Form" width="300" height="230" /></a><p class="wp-caption-text">Main Form of SmartInspect Configuration Builder</p></div>
<p>In the first tab named<em><strong> &#8220;general&#8221;</strong></em>, you can enable the login, set the application name, the level of logging and the default level of logging.  The second tab is named <strong><em>&#8220;Connections&#8221;</em></strong> you could choose what sort of protocol you would like to use to store/send the log. Please see below :</p>
<div id="attachment_319" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/21.png"><img class="size-medium wp-image-319" title="Choose the protocol" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/21-300x132.png" alt="" width="300" height="132" /></a><p class="wp-caption-text">Protocol Combobox of SmartInspect Configuration Builder</p></div>
<blockquote><p><em>Info : The pipe protocol is used to log directly to a local SmartInspect Console over a named pipe.</em></p></blockquote>
<p>After you add it, you could configure a lot of things : please see the example for File Logging :</p>
<div id="attachment_320" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/31.png"><img class="size-medium wp-image-320" title="3" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/31-300x240.png" alt="" width="300" height="240" /></a><p class="wp-caption-text">File logging option - SmartInspect Configuration Builder</p></div>
<p>The last tab is <strong><em>&#8220;Sessions&#8221;</em></strong>, it permits to configure new &#8220;sessions&#8221;, you could change the name, color, level of logging for each one. If no entry session is found, SmartInspect will use the default one.</p>
<h4>Adding SmartInspect to your app :</h4>
<p>Like CodeSite you need to add units to your code : <strong><em>SiAuto, SmartInspect</em></strong>.</p>
<div id="attachment_321" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/41.png"><img class="size-medium wp-image-321" title="" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/41-300x277.png" alt="" width="300" height="277" /></a><p class="wp-caption-text">Add SmartInspect units to the uses section.</p></div>
<p>Now, the TSmartInspect <em><strong>Si</strong></em> TObject is created and will help you to handle log. If you would like to Load a configuration file use :</p>
<pre> Si.LoadConfiguration('configuration.sic'); </pre>
<p>I prefer in my app not using Configuration Builder. I use my own solution and avoid the multiplicity of configuration files in main directory. So I created a special tab in the configuration Form of my app, in this tab I let the user change logging conf and save them to an INIFile.</p>
<div id="attachment_322" class="wp-caption aligncenter" style="width: 250px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/51.png"><img class="size-medium wp-image-322" title="" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/51-240x300.png" alt="" width="240" height="300" /></a><p class="wp-caption-text">My own logging configuration builder</p></div>
<p>A first version of my unit which is dedicated to load SmartInspect is available below :</p>
<pre>

{$REGION 'Informations'}
{
Auteur : Rémi MEVAERE (OnKeySoft)
---------------------------------
Date de création : 30 Mars 2012
Description : Le log est important ici...
Version : 0.0.0.1
Dernière modification : 30 Mars 2012
---------------------------------
Historique :
0.0.0.1 : Création du fichier
}
{$ENDREGION}

// Load the log
function Load_the_log: boolean;
var
INI_File: TIniFile;
Chemin_Ini: String;
// Variables_Utiles
Config: TConfiguration;
Con_config: string;
Buffer: string;
begin
result := False;
si.Enabled := False;

// Ou se trouve le fichier de configuration
Chemin_Ini := extractfilepath(Application.ExeName) + Nom_P_Filename + '.ini';
try
// On charge le INI et l'objet conteneur
INI_File := TIniFile.Create(Chemin_Ini);
Config := TConfiguration.Create(False);

try
with Config do
begin
{$IFDEF DEBUG}
Log_Enable := INI_File.ReadBool(Ini_Log, Ini_Log_Enable, true);
{$ELSE}
Log_Enable := Conf.ReadBool(Ini_Log, Ini_Log_Enable, False);
{$ENDIF}
if Log_Enable then
begin
// On Charge le reste
Log_EnableRemote := INI_File.ReadBool(Ini_Log, Ini_Log_EnableRemote, False);
Log_EnableText := INI_File.ReadBool(Ini_Log, Ini_Log_EnableText, False);
Log_TextPattern := INI_File.ReadString(Ini_Log, Ini_Log_TextPattern, '[%timestamp%] %level%: %title%');
Log_Path := INI_File.ReadString(Ini_Log, Ini_Log_Path, GetRoamingUserAppDataPath + Path_App_Data + Path_Log_Dir);
ForceDirectories(Log_Path); // Creation du repertoire
Log_IPRemote := INI_File.ReadString(Ini_Log, Ini_Log_IPRemote, '127.0.0.1');
{$IFDEF DEBUG}
Log_Level := TLog_Level(INI_File.ReadInteger(Ini_Log, Ini_Log_Level, 0));
{$ELSE}
Log_Level := TLog_Level(Conf.ReadInteger(Ini_Log, Ini_Log_Level, 1));
{$ENDIF}
Log_MaxFiles := INI_File.ReadInteger(Ini_Log, Ini_Log_MaxFiles, Log_Default_Files);
Log_MaxSize := INI_File.ReadInteger(Ini_Log, Ini_Log_MaxSize, Log_Default_Size);
Log_Rotate := TLog_Rotate(INI_File.ReadInteger(Ini_Log, Ini_Log_Rotate, 3));

// Création des parametres du log

// 1 - Direct PIPE
{$IFDEF LOCAL}
Buffer := 'pipe(reconnect=true, reconnect.interval=1s, level="debug")';
if (Con_config &lt;&gt; '') then
Con_config := Con_config + ',' + Buffer
else
Con_config := Buffer;
{$ENDIF}
// 2 - Le fichier ISL
Buffer := 'file(append="true"';
Buffer := Buffer + ', filename="' + Log_Path + 'log.sil' + '"';

if Log_MaxFiles &lt;&gt; 0 then
Buffer := Buffer + ', maxparts="' + inttostr(Log_MaxFiles) + '"';

if Log_MaxSize &lt;&gt; 0 then
Buffer := Buffer + ', maxsize="' + inttostr(Log_MaxSize * 1024) + '"';

case Log_Rotate of
LOG_HOURLY:
Buffer := Buffer + ', rotate="hourly"';
LOG_DAILY:
Buffer := Buffer + ', rotate="daily"';
LOG_WEEKLY:
Buffer := Buffer + ', rotate="weekly"';
LOG_MONTLY:
Buffer := Buffer + ', rotate="monthly"';
end;

case Log_Level of
LOG_DEBUG:
Buffer := Buffer + ', level="debug"';
LOG_VERBOSE:
Buffer := Buffer + ', level="verbose"';
LOG_MESSAGE:
Buffer := Buffer + ', level="message"';
LOG_WARNING:
Buffer := Buffer + ', level="warning"';
LOG_ERROR:
Buffer := Buffer + ', level="error"';
LOG_FATAL:
Buffer := Buffer + ', level="fatal"';
end;

Buffer := Buffer + ', encrypt="true", key="' + Pass_LOG + '"';
Buffer := Buffer + ', reconnect="true", reconnect.interval=1s)';

if (Con_config &lt;&gt; '') then
Con_config := Con_config + ',' + Buffer
else
Con_config := Buffer;

// 3 - Le fichier Text

if Log_EnableText then
begin

Buffer := 'text(append="true"';
Buffer := Buffer + ', filename="' + Log_Path + 'log.txt' + '"';

if Log_MaxFiles &lt;&gt; 0 then
Buffer := Buffer + ', maxparts="' + inttostr(Log_MaxFiles) + '"';

if Log_MaxSize &lt;&gt; 0 then
Buffer := Buffer + ', maxsize="' + inttostr(Log_MaxSize * 1024) + '"';

case Log_Rotate of
LOG_HOURLY:
Buffer := Buffer + ', rotate="hourly"';
LOG_DAILY:
Buffer := Buffer + ', rotate="daily"';
LOG_WEEKLY:
Buffer := Buffer + ', rotate="weekly"';
LOG_MONTLY:
Buffer := Buffer + ', rotate="monthly"';
end;

case Log_Level of
LOG_DEBUG:
Buffer := Buffer + ', level="message"';
LOG_VERBOSE:
Buffer := Buffer + ', level="message"';
LOG_MESSAGE:
Buffer := Buffer + ', level="message"';
LOG_WARNING:
Buffer := Buffer + ', level="warning"';
LOG_ERROR:
Buffer := Buffer + ', level="error"';
LOG_FATAL:
Buffer := Buffer + ', level="fatal"';
end;

Buffer := Buffer + ', pattern="' + Log_TextPattern + '"';
Buffer := Buffer + ', reconnect="true", reconnect.interval=1s)';

if (Con_config &lt;&gt; '') then
Con_config := Con_config + ',' + Buffer
else
Con_config := Buffer;

end;
{$IFDEF REMOTE}
// 4 - Le Remote
if Log_EnableRemote then
begin
Buffer := 'tcp(';

Buffer := Buffer + ', host="' + Log_IPRemote + '"';
Buffer := Buffer + ', level="debug"';
Buffer := Buffer + ', reconnect="true", reconnect.interval=1s)';

if (Con_config &lt;&gt; '') then
Con_config := Con_config + ',' + Buffer
else
Con_config := Buffer;
end;

{$ENDIF REMOTE}
si.Connections := Con_config;
si.Enabled := true;
si.DefaultLevel := lvDebug;
// Debut du Logging
siMain.ResetCallstack;
SiMain.LogSystem;
SiMain.LogMemoryStatistic;
SiMain.LogMessage('Log is loaded');
SiMain.LogObject(lvDebug, 'Starting the Log : ' + Con_config, Config);

end;
end;
result := true;
finally
INI_File.Free;
Config.Free;
end;
except

end;

end;</pre>
<p>So as you can see, SmartInspect is flexible and you could change everything in Runtime (and at anytime). Don&#8217;t forgive here you don&#8217;t have to install blackbox or third party exe.</p>
<h4>Lets log begin :</h4>
<p>After adding correct units, you could use the <strong><em>SiMain</em></strong> or any else Sesssions (see on top) which are both <em><strong>TSiSession</strong></em> Object. <strong><em>SiMain</em></strong> is exposing all the function to log string, object, color, screenshot, memory&#8230;.</p>
<div id="attachment_325" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/6.png"><img class="size-medium wp-image-325" title="" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/6-300x212.png" alt="" width="300" height="212" /></a><p class="wp-caption-text">Some methods exposed by TSiSession</p></div>
<p>I will not describe everything it&#8217;s very close to CodeSite. Use the adapted methods to log the things you want.</p>
<p>To help you, SmartInspect is providing templates (like CS) : (here you can see the Method LeaveThread which will permit to separate all Threads in the Viewer).</p>
<div id="attachment_326" class="wp-caption aligncenter" style="width: 260px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/7.png"><img class="size-medium wp-image-326" title="7" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/7-250x300.png" alt="" width="250" height="300" /></a><p class="wp-caption-text">Code Templates</p></div>
<p>SmartInspect also provide Delphi Expert to assist you when you want to EnterMethod and LeaverMethod (you know, like with CS when you want to have a better visibility).</p>
<div id="attachment_328" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/8+.png"><img class="size-medium wp-image-328" title="8+" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/8+-300x174.png" alt="" width="300" height="174" /></a><p class="wp-caption-text">Open SmartInspect Delphi Expert, Menu -&gt; SmartInspect -&gt; Instrument Unit</p></div>
<h4>Now opening the Log Viewer :</h4>
<p>And start the app to begin logging.</p>
<div id="attachment_329" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/9.png"><img class="size-medium wp-image-329" title="9" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/9-300x196.png" alt="" width="300" height="196" /></a><p class="wp-caption-text">Main Screen of Log Viewing</p></div>
<p>I will not spend time to details &#8220;standard&#8221; functions like searching, copying, moving into log entries, adding breakpoints&#8230; I will just show you why I&#8217;am prefering SmartInspect Console.</p>
<div id="attachment_330" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/04/91.png"><img class="size-medium wp-image-330" title="" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/91-300x173.png" alt="" width="300" height="173" /></a><p class="wp-caption-text">Why the SmartInspect Console is better !</p></div>
<p><span style="color: #ff0000;"><strong>1 : </strong><span style="color: #000000;">As you can see you could create different categories, in each categories you could add views. And each view gives you the opportunity to have a more clear and more precise idea of the log to understand problems and correct them.</span></span></p>
<p><span style="color: #ff0000;"><strong>2 : </strong></span>As CodeSite you could see the Call Stack, it&#8217;s a precious information.</p>
<p><strong><span style="color: #ff0000;">3 : </span></strong>As in Delphi Debuggers, you could watch/track some variables. It&#8217;s useful when you want to remote debugging and understand in what conditions your program are running (How much thread ? How much dbb ? How much data ?)&#8230; This value is change when you are using this code :</p>
<pre>{$IFDEF DEBUG} SiMain.IncCounter('#Open DBB'); {$ENDIF}</pre>
<p><span style="color: #ff0000;"><strong>4 :</strong></span> Just imagine you have 5 beta testers currently running your software, you are running it on your own computer&#8230; To avoid headache you could use this list to view where the processes are running and use it to filter the one you wants !</p>
<p><span style="color: #ff0000;"><strong>5 :</strong></span> As in CodeSite you could track TObject, Pictures and other data. It&#8217;s terribly useful.</p>
<p><span style="color: #ff0000;"><strong>6 :</strong></span>  Each Tab is a view. In a view you could filter data and accept only some things. Highlight stuff with Regular Expression (In the screenshot I&#8217;am highlighting each lines with &#8220;Create&#8221;).</p>
<p><span style="color: #ff0000;"><strong>7 :</strong></span> The main Window, it&#8217;s fast and clear. You could see indentation, highlighting and other things.</p>
<p><span style="color: #ff0000;"><strong> 8 :</strong></span> A reason why i&#8217;am choosing SmartInspect is this Watches Graph. You could draw graph with Watches data to see the evolution. Here I&#8217;am tracking the number of databases opened. If someone have a problem I will see in one second if there is too much DBB opened !</p>
<p>For me the SmartInspect Console is better. In conclusion :</p>
<p><span style="color: #008000;"><strong>Pros:</strong></span></p>
<p>-       Easy to use and much faster.<br />
-       More complete than CodeSite.<br />
-       Work with .NET (C# VB.Net), Java, Delphi.<br />
-       More affordable : 200 €<br />
-       Don&#8217;t add a blackbox to customer computer.<br />
-       A lot of communication ways available. File, Memory, Pipe, TCP, Text.<br />
-       On the fly configuration.<br />
-       Maximum log files, encryption, log rotation, log level, backlog, asynchronous !<br />
-       It&#8217;s really reliable, you don&#8217;t have to reinvent the wheel.<br />
-       Great Support, Gurok brothers are very kind.<br />
-       Viewer is really great. Better than CodeSite. Powerful filters to manage multiple &#8220;sources&#8221; of log (If you are tracking several beta-testers)<br />
-       Watch and Monitor resources and trace graphs.<br />
-       Ability to log TObject, Screenshot, Memory information and everything you want.<br />
-       It&#8217;s pretty easy to log multiple software.<br />
-       Fully ThreadSafe, Synchronized and support a lot of threads.<br />
-       Redistribuable Console for your users.<br />
-       Library for PHP/Python and adapter for Log4j, Log4net, PostSharp<br />
-       SDK available to access log.</p>
<p><span style="color: #ff0000;"><strong>Cons:</strong></span></p>
<p>-      Can&#8217;t add plugin !<br />
-      The price : it&#8217;s not free.<br />
-      Not full sources.<br />
-      Need to pay update every year (50€)</p>
<p>Rate : <img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /><img title="polygon_48" src="http://blog.onkeysoft.com/wp-content/uploads/2012/04/polygon_48.png" alt="" width="48" height="48" /></p>
<p>&nbsp;</p>
<h1>Conclusion :</h1>
<p>I know, I haven&#8217;t describe every features of this two tools but I have just bought the second one. It&#8217;s just a point of view. In my app I&#8217;am combining the power of TEurekaLog with TSmartInspect in that way when there is an exception I&#8217;ve got usefull information from the Exception Manager and the log is automatically send so I hope I will not have as much problem as in the past when a user get a problem. I will not use anymore the trick :</p>
<pre> showmessage('First thing'); </pre>
<p>Which is really time hunger and very frustrating. CodeSite is a great tool, directly integrated in Delphi Third Party bundle and the author is really kind. It could maybe be more adapted in several situations but I prefer the freedom of SmartInspect.</p>
<p>You could also code your own tool but it will cost you time and maybe more money cause it will not be operational at beginning (unless you are a Genius coder (but i&#8217;am not)).</p>
<p>I hope this article will be useful for you, if you want to add some things don&#8217;t hesitate to add a comment I know you are reading this !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.onkeysoft.com/2012/04/24/delphi-add-log-to-your-software-with-codesite-smartinspect-your-own-method/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Update SubVersion expert in Delphi XE, XE2</title>
		<link>http://blog.onkeysoft.com/2012/03/28/update-subversion-expert-in-delphi-xe-xe2/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=update-subversion-expert-in-delphi-xe-xe2</link>
		<comments>http://blog.onkeysoft.com/2012/03/28/update-subversion-expert-in-delphi-xe-xe2/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 14:40:58 +0000</pubDate>
		<dc:creator>remixtech</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[delphi ide]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[expert]]></category>
		<category><![CDATA[suversion]]></category>
		<category><![CDATA[tortoise]]></category>
		<category><![CDATA[update]]></category>
		<category><![CDATA[upgrade]]></category>

		<guid isPermaLink="false">http://blog.onkeysoft.com/?p=267</guid>
		<description><![CDATA[Yesterday I was working on my project and I decided to change my old backup system (which was a crazy thing in 2012, backing up every 2h which was filling up slowly but surely my drive). So I tried to replace this “system” with SubVersion. Introduction So I installed Tortoise 64bits (Win64 here), I create [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I was working on my project and I decided to change my old backup system (which was a crazy thing in 2012, backing up every 2h which was filling up slowly but surely my drive). So I tried to replace this “system” with SubVersion.<br />
<span id="more-267"></span></p>
<h2>Introduction</h2>
<p>So I installed Tortoise 64bits (Win64 here), I create a repository and I started to use this fabulous tool directly in the Explorer. But I remembered something ? Is there any tool directly integrated in Delphi IDE ? I checked the features chart :</p>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V0.png"><img class="aligncenter size-full wp-image-269" title="V0" src="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V0.png" alt="" width="631" height="217" /></a></p>
<p>And tried to use it (just tried)…</p>
<p>&nbsp;</p>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V11.png"><img class="aligncenter size-full wp-image-271" title="V1" src="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V11.png" alt="" width="624" height="297" /></a></p>
<p>Subversion is really great, but it’s a pain in the ass to use it directly in Delphi IDE. I always have some mystical and strange errors/bugs/warnings when I’am using it. I will try to help you to beat this one:</p>
<blockquote><p><em>“The path ‘blablabla’ appears to be part of a SubVersion 1.7 or greate corking copy rooted at ‘blablabla’. Please upgrade your SubVersion Client to use this working copy.”</em></p></blockquote>
<p>I will explain you how to upgrade it simply and fastly.</p>
<h2>Uninstalling Embarcadero SubVersion Integration</h2>
<ul>
<li>Delete the Expert, directly in the IDE (Component -&gt; Install Packages)<a href="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V2.png"><img class="aligncenter size-full wp-image-272" title="V2" src="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V2.png" alt="" width="639" height="434" /></a></li>
<li>Delete the Subversion directory in Embarcadero Rad Studio Folder (\Embarcadero\Rad Studio\X.0\bin\subversion<a href="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V3.png"><img class="aligncenter size-full wp-image-273" title="V3" src="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V3.png" alt="" width="470" height="190" /></a></li>
<li>Delete the BPL (Search *svn* files in Explorer)<a href="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V4.png"><img class="aligncenter size-full wp-image-274" title="V4" src="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V4.png" alt="" width="520" height="197" /></a></li>
<li>It&#8217;s done, SubVersion Integration is removed</li>
</ul>
<h2>Installing SubVersion updated</h2>
<p>Be careful,  Delphi IDE is a Win32 application, so it can load just 32bits DLL. We need to install last version of SubVersion but in 32 bits (If you are using Win64, download Win32 version !!)</p>
<p style="text-align: center;"><a href="http://sourceforge.net/projects/win32svn/">http://sourceforge.net/projects/win32svn/</a></p>
<p style="text-align: left;">Remember in which directory you are installing SubVersion</p>
<h2>Installing Subversion Insight</h2>
<p>Now we must install the IDE expert, there are several versions. I&#8217;am actually using Uwe&#8217;s Expert (Version Insight Plus Beta 8), but may be it&#8217;s better to use the last version. You can download it here.</p>
<p style="text-align: center;"><a href="http://www.bitcommander.de/blog/index.php/downloads/">http://www.bitcommander.de/blog/index.php/downloads/</a></p>
<h2>Linking the expert to the right DLL</h2>
<p>We have destroyed the subversion Dll when we deleted the subversion directory in embarcadero setup folder. We must tell the IDE to watch for the DLL in the updated subversion folder.</p>
<p>Open the registry editor (cmd -&gt; regedit) And go to the key <code>HKEY_CURRENT_USER\Software\Embarcadero\BDS\9.0\Subversion</code></p>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V41.png"><img class="aligncenter size-medium wp-image-275" title="V41" src="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V41-300x123.png" alt="" width="300" height="123" /></a></p>
<p>Create the key Subversion and the Value (string) :</p>
<p style="text-align: center;"><span style="color: #000080;"><strong>SvnDllDir &#8220;D:\Program Files (x86)\Subversion\bin\&#8221;</strong></span></p>
<h2 style="text-align: left;">Now restart IDE and test !</h2>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V5.png"><img class="aligncenter size-full wp-image-276" title="V5" src="http://blog.onkeysoft.com/wp-content/uploads/2012/03/V5.png" alt="" width="466" height="564" /></a></p>
<p>As you can see, you will have a new version, updated, corrected ! And Working fine.</p>
<p>I hope it will help some peoples.</p>
<p>Rémi</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.onkeysoft.com/2012/03/28/update-subversion-expert-in-delphi-xe-xe2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get the MD5 of strings with Delphi (Unicode and Ansi)</title>
		<link>http://blog.onkeysoft.com/2012/03/27/get-the-md5-of-strings-with-delphi-unicode-and-ansi/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=get-the-md5-of-strings-with-delphi-unicode-and-ansi</link>
		<comments>http://blog.onkeysoft.com/2012/03/27/get-the-md5-of-strings-with-delphi-unicode-and-ansi/#comments</comments>
		<pubDate>Tue, 27 Mar 2012 18:22:48 +0000</pubDate>
		<dc:creator>remixtech</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://blog.onkeysoft.com/?p=263</guid>
		<description><![CDATA[Since Delphi 2007, an unit is dedicated to get the Md5 of a string (Unicode or Not). You could find it in the Embarcadero Rad Studio directory, sources : D:\Program Files (x86)\Embarcadero\RAD Studio\9.0\source\soap\wsdlimporter\MessageDigest_5.pas Just add this unit to the uses and declare this two functions. function GetMd5(const Value: AnsiString): string; overload; var hash: MessageDigest_5.IMD5; begin hash [...]]]></description>
			<content:encoded><![CDATA[<p>Since Delphi 2007, an unit is dedicated to get the Md5 of a string (Unicode or Not). You could find it in the Embarcadero Rad Studio directory, sources :</p>
<blockquote>
<p style="text-align: center;"><em><strong><span style="color: #008000;">D:\Program Files (x86)\Embarcadero\RAD Studio\9.0\source\soap\wsdlimporter\MessageDigest_5.pas</span></strong></em></p>
</blockquote>
<p style="text-align: left;"><span style="text-align: left;">Just add this unit to the <em><strong><span style="color: #003366;">uses</span></strong></em> and declare this two functions.</span></p>
<pre>
function GetMd5(const Value: AnsiString): string; overload;
var
hash: MessageDigest_5.IMD5;
begin
hash := MessageDigest_5.GetMD5();
hash.Update(Value);
Result := hash.AsString();
end;

function GetMd5(const Value: UnicodeString): string; overload;
var
hash: MessageDigest_5.IMD5;
begin
hash := MessageDigest_5.GetMD5();
hash.Update(Value);
Result := hash.AsString();
end;
</pre>
<p>That&#8217;s all folks !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.onkeysoft.com/2012/03/27/get-the-md5-of-strings-with-delphi-unicode-and-ansi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qualité audio des Smartphones en 2011</title>
		<link>http://blog.onkeysoft.com/2011/10/23/qualite-audio-des-smartphones-en-2011/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=qualite-audio-des-smartphones-en-2011</link>
		<comments>http://blog.onkeysoft.com/2011/10/23/qualite-audio-des-smartphones-en-2011/#comments</comments>
		<pubDate>Sat, 22 Oct 2011 23:46:42 +0000</pubDate>
		<dc:creator>remixtech</dc:creator>
				<category><![CDATA[Audio]]></category>
		<category><![CDATA[Smartphones]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[audio]]></category>
		<category><![CDATA[beats]]></category>
		<category><![CDATA[cowon]]></category>
		<category><![CDATA[dac]]></category>
		<category><![CDATA[Diaphonie stéréo]]></category>
		<category><![CDATA[Distorsion intermodulation]]></category>
		<category><![CDATA[dynamic range]]></category>
		<category><![CDATA[Galaxy]]></category>
		<category><![CDATA[gamme dynamique]]></category>
		<category><![CDATA[htc]]></category>
		<category><![CDATA[IMD]]></category>
		<category><![CDATA[IOS]]></category>
		<category><![CDATA[MiniDisc]]></category>
		<category><![CDATA[niveau de bruit]]></category>
		<category><![CDATA[noise level]]></category>
		<category><![CDATA[quality]]></category>
		<category><![CDATA[réponse en fréquence]]></category>
		<category><![CDATA[Samsung]]></category>
		<category><![CDATA[sensation xe]]></category>
		<category><![CDATA[Sony]]></category>
		<category><![CDATA[stereo crosstalk]]></category>
		<category><![CDATA[Taux de distorsion harmonique]]></category>
		<category><![CDATA[THD]]></category>

		<guid isPermaLink="false">http://blog.onkeysoft.com/?p=130</guid>
		<description><![CDATA[Depuis quelques années les smartphones prétendent rivaliser avec les baladeurs PMP. Nous verrons dans cet article si ils peuvent prétendre les remplacer. Introduction Ce petit article n’a pas la prétention d’être exempt d’erreurs, il est écrit par un physicien audiophile et non un ingénieur du son. Le but de celui-ci est avant tout de vulgariser [...]]]></description>
			<content:encoded><![CDATA[<p>Depuis quelques années les smartphones prétendent rivaliser avec les baladeurs PMP. Nous verrons dans cet article si ils peuvent prétendre les remplacer.<br />
<span id="more-130"></span></p>
<h2>Introduction</h2>
<p>Ce petit article n’a pas la prétention d’être exempt d’erreurs, il est écrit par un physicien audiophile et non un ingénieur du son. Le but de celui-ci est avant tout de vulgariser des concepts qui peuvent sembler obscurs aux néophytes. Vous trouverez des informations bien plus précises sur des sites spécialisés et notamment sur GenerationMp3.</p>
<p>Le problème avec la mesure de la qualité audio d’un appareil, c’est qu’elle est très subjective. Chacun perçoit la musique de manière différente car nous n’avons pas la même éducation musicale, la même oreille et les mêmes attentes en ce qui concerne la musique. Difficile donc de juger si un son est « bon » ou bien s&#8217;il est « mauvais » . Parler de <em>&#8220;mauvais son&#8221;</em> et de <em>&#8220;bon son&#8221;</em> est un abus de langage, il vaut mieux parler de qualité de la sortie audio, c’est d&#8217;ailleurs le sujet de cet article</p>
<p>Pour les appareils électroniques, on considère que le signal n’est globalement pas abimé en étant stocké, ni même décompressé par le processeur (vers 44100Hz, 16Bit, Stereo). Le principal responsable de l&#8217;altération du signal est le composant DAC (le convertisseur digital vers analogique) qui contient aussi un amplificateur sur ce type d&#8217;appareil.</p>
<blockquote><p>Actuellement sur les Smartphones haut de gamme le son est de bonne qualité, on comparera le son avec un lecteur MP3 IAudio d’excellente facture : le Cowon IAudio 9.</p>
<div id="attachment_134" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/MIIFTRACKPRO_Connectivity2.jpg"><img class="size-medium wp-image-134" title="Fast Track Pro " src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/MIIFTRACKPRO_Connectivity2.jpg" alt="" width="300" height="214" /></a><p class="wp-caption-text">Fast Track Pro est le système utilisé.</p></div></blockquote>
<div class="mceTemp mceIEcenter">
<p style="text-align: left;">Donc pour juger la qualité d’une sortie audio on cherche à vérifier comment retranscrit le lecteur, un signal que l’on a créé et que l’on connait. Par là j’entends que l’on crée un fichier contenant un signal audio codé en numérique. On lit ce fichier avec le lecteur et en sortie on récupère le signal analogique soit :</p>
<ul>
<li>directement avec la prise jack (20000 Ohm)</li>
<li>avec un casque (ici AKG 32 Ohm) directement avec un microphone de très bonne qualité si l’on veut tenir compte de l&#8217;impédance ajoutée par celui-ci.</li>
</ul>
<p style="text-align: left;">Les tests suivants ont été réalisés à volume maximum ce qui permet d’accentuer la distorsion que l’appareil inflige au signal. En effet, certains lecteurs détériorent grandement le signal à volume max.</p>
<blockquote><p>Pour le test, le casque utilisé est de 32 Ohm, l’intensité est plus importante qu’un casque avec une plus haute impédance. L’amplificateur est plus sollicité donc travaille moins bien. De plus, on pousse le son à fond pour avoir une plus grande intensité. Ces tests sont réalisés par des professionnels. Vous trouverez à la fin de cette article les sources. Le logiciel utilisé est RightMark Audio.</p></blockquote>
<p style="text-align: left;">En comparant le signal donné et le signal que nous renvoit le casque on peut discuter quantitativement de la qualité d’une sortie audio. Les résultats doivent être reproductibles et comparables sinon cela n&#8217;a pas d’intérêt.</p>
<h2 style="text-align: left;">La réponse en fréquence</h2>
<p style="text-align: left;">Cette mesure ne permet pas de dire si le son est agréable, mais uniquement si le son qui sort des écouteurs est le son tel qu’il est enregistré sur le fichier audio. Pour comprendre cette partie, il faut savoir ce qu’est un signal audio. Très rapidement, un signal audio est une information provenant d’un émetteur et attendant un récepteur composé d’une multitude de signaux sinusoïdaux purs avec des fréquences différentes.</p>
<h3>Rappel sur la fréquence :</h3>
<p style="text-align: left;">Une fonction sinusoïdale est décrite par sa phase ϕ (&#8220;<em>décalage par rapport à l&#8217;origine</em>&#8220;), son amplitude Ĝ et sa fréquence (ici pulsation ω). On peut l&#8217;écrire de cette manière.</p>
<p style="text-align: left;"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/676d694b78ade3e5d1e3a3374248bf19.png"><img class="aligncenter size-full wp-image-142" title="676d694b78ade3e5d1e3a3374248bf19" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/676d694b78ade3e5d1e3a3374248bf19.png" alt="" width="177" height="24" /></a></p>
<blockquote>
<p style="text-align: left;">Ici, ce terme contient toutes les fonctions sinusoïdales, que ce soit un cosinus ou un sinus. Le cosinus étant juste un sinus déphasé. Mais c&#8217;est vrai que l&#8217;on s&#8217;en fiche, continuons&#8230;</p>
</blockquote>
<p style="text-align: left;">Voila deux signaux sinusoïdaux mais de fréquences différentes.</p>
<div id="attachment_144" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/40lx3-frequence.jpg"><img class="size-medium wp-image-144" title="40lx3-frequence" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/40lx3-frequence-300x182.jpg" alt="" width="300" height="182" /></a><p class="wp-caption-text">Au-dessus fréquence basse (son grave), au-dessous fréquence élevée (son aiguë)</p></div>
<p style="text-align: left;">Un signal quelconque peut être décomposé en une somme de signaux sinusoïdaux. Par exemple : ci-dessous avec le signal audio composé en <strong>noir</strong> qui est en fait la somme pondérée des signaux en <span style="color: #008000;">vert</span>, <span style="color: #ff00ff;">rose</span>, <span style="color: #0000ff;">bleu</span>, <span style="color: #ff0000;">rouge</span> etc… Ainsi notre oreille perçoit le signal comme une somme de signaux sinusoïdaux de fréquences différentes.</p>
<div id="attachment_145" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/400px-Fourier_dun_carr%C3%A9.svg_.png"><img class="size-medium wp-image-145" title="400px-Fourier_d'un_carré.svg" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/400px-Fourier_dun_carr%C3%A9.svg_-300x300.png" alt="" width="300" height="300" /></a><p class="wp-caption-text">Le signal noir est la somme pondérée des autres signaux...</p></div>
<p>&nbsp;</p>
<blockquote><p><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/FFT.png"><img class="aligncenter size-medium wp-image-146" title="FFT" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/FFT-300x211.png" alt="" width="300" height="211" /></a></p>
<p>Grâce à un outil mathématique appelé &#8220;transformée de Fourier&#8221; on peut décomposer le signal du dessous en une somme de sinus de fréquences différentes avec une intensité différente. C’est ce qu’on voit au-dessus (à chaque pic correspond une intensité particulière pour une certaine fréquence). Plus le pic est grand plus la fréquence correspondante est &#8220;présente&#8221;.</p></blockquote>
<p style="text-align: left;">Revenons à nos moutons, on cherche à déterminer par rapport à un signal envoyé si toutes les fréquences sont bien restituées et dans les mêmes proportions. Si j’envoie un signal « plat »  et que les basses sont plus intenses que les aiguës c’est que le lecteur ne restitue pas correctement le son. C’est mauvais ou alors un équaliseur altère le signal.</p>
<p style="text-align: left;">Les limites de perception de l’oreille humaine se situent entre 20Hz et 20Khz. Mais globalement on se fiche de cette bande passante car la plupart des appareils électroniques sont capables de restituer un signal dans cette gamme de fréquence et puis l’oreille humaine ni verra que du feu même si l’on est entre 30 Hz et 19 KHz. Non ce qui nous intéresse c’est si la restitution est « uniforme ».</p>
<h4 style="text-align: left;">A propos de l&#8217;unité Décibel :</h4>
<p style="text-align: left;">Partout dans le monde, pour mesurer la puissance d’une onde sonore (ou plutôt pour comparer deux puissances) on utilise une unité appelée Décibel. C’est un nom un peu barbare en l’honneur de Mr Bell et inventé par les ingénieurs des laboratoires Bell pour quantifier l’atténuation d’un signal Audio sur une liaison téléphonique. C’est une fonction logarithmique (pourquoi, parce que notre oreille est un récepteur logarithmique !!) de rapport de puissance (ce que l’on envoie par rapport à ce que l’on reçoit). On multiplie enfin par <strong>10</strong> pour avoir une unité plus pratique (d’où le nom <strong>déci</strong>-bel).</p>
<div id="attachment_151" class="wp-caption aligncenter" style="width: 184px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/b8f61cfcf6de49974ba046af0e41c847.png"><img class="size-full wp-image-151" title="b8f61cfcf6de49974ba046af0e41c847" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/b8f61cfcf6de49974ba046af0e41c847.png" alt="" width="174" height="44" /></a><p class="wp-caption-text">Gain en décibel, permettant de comparer deux puissances P1 et P0</p></div>
<p style="text-align: left;">Si la puissance du signal de sortie est égale au signal de puissance de l’entrée, le logarithme vaut 0 (en effet log(1)=0) et donc pas d’atténuation. Si la puissance du signal de sortie est 10 fois plus faible (log(10) = 1) donc on aura une atténuation de 10 dB (-10dB) et s’il est 100 fois plus faible -20dB, 1000 fois -30 dB.</p>
<p style="text-align: left;">Pour mesurer la réponse en fréquence on envoie donc un signal et on mesure l’atténuation (ou l’amplification) de certaines fréquences. On note [+ x dB, – y dB].</p>
<p style="text-align: left;"><strong>Exemple :</strong></p>
<div id="attachment_154" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/gsmarena_a001.png"><img class="size-medium wp-image-154" title="gsmarena_a001" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/gsmarena_a001-300x187.png" alt="" width="300" height="187" /></a><p class="wp-caption-text">Pour le HTC Sensation, directement sur le jack (en blanc) et avec un casque (en vert)</p></div>
<p style="text-align: left;">On s’intéresse d’abord à la courbe blanche. Sur celle-ci nous voyons que la réponse en fréquence est plutôt bonne (attention c’est une échelle logarithmique) entre 40Hz et 15 Khz. +0.05 dB,-0.34dB au bord. Par contre quand on rajoute la résistance du casque c’est un peu moins bon +0.71 dB (pour les basses), -0.15 dB pour les aiguës. Comme on l’a vu c’est normal le courant augmente et l’amplificateur souffre.</p>
<p style="text-align: left;">Voici l’évolution de la réponse en fréquence pour quelques Smartphones :</p>
<table width="407" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="132" />
<col width="92" />
<col width="103" />
<col width="80" /> </colgroup>
<tbody>
<tr>
<td style="text-align: center;" width="132" height="20"><strong>Sans casque</strong></td>
<td style="text-align: center;" width="92"><strong>Réponse en fréquence (dB)</strong></td>
<td width="103"></td>
<td style="text-align: center;" width="80"><strong>Étendue<br />
</strong></td>
</tr>
<tr>
<td height="20">HTC Desire HD</td>
<td>0,09</td>
<td>-0,44</td>
<td>0,53</td>
</tr>
<tr>
<td height="20">HTC Sensation XE</td>
<td>0,05</td>
<td>-0,34</td>
<td>0,39</td>
</tr>
<tr>
<td height="20">Cowon IAudio 9</td>
<td>0,03</td>
<td>-0,16</td>
<td>0,19</td>
</tr>
<tr>
<td height="20">Apple IPhone 4S</td>
<td>0,02</td>
<td>-0,11</td>
<td>0,13</td>
</tr>
<tr>
<td height="20">Samsung Galaxy S II</td>
<td>0,04</td>
<td>-0,09</td>
<td>0,13</td>
</tr>
<tr>
<td height="20">Apple IPhone 4</td>
<td>0,01</td>
<td>-0,07</td>
<td>0,08</td>
</tr>
<tr>
<td height="20">LG Optimus 2X</td>
<td>0,01</td>
<td>-0,03</td>
<td>0,04</td>
</tr>
</tbody>
</table>
<div class="mceTemp mceIEcenter">
<div id="attachment_156" class="wp-caption aligncenter" style="width: 482px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/etendue.png"><img class="size-full wp-image-156 " title="etendue" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/etendue.png" alt="" width="472" height="285" /></a><p class="wp-caption-text">Plus l&#39;étendue est faible plus la réponse en fréquence est bonne.  Les HTC sont les moins bons ici.</p></div>
</div>
<p style="text-align: left;">En charge les résultats sont tout de suite différents mais bien plus intéressants :</p>
<table width="407" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="132" />
<col width="92" />
<col width="103" />
<col width="80" /> </colgroup>
<tbody>
<tr>
<td style="text-align: center;" width="132" height="20"><strong>Avec casque</strong></td>
<td style="text-align: center;" width="92"><strong>Réponse en fréquence (dB)</strong></td>
<td width="103"></td>
<td style="text-align: center;" width="80"><strong>Étendue<br />
</strong></td>
</tr>
<tr>
<td height="20">Samsung Galaxy S II</td>
<td>1,05</td>
<td>-0,22</td>
<td>1,27</td>
</tr>
<tr>
<td height="20">HTC Sensation XE</td>
<td>0,71</td>
<td>-0,15</td>
<td>0,86</td>
</tr>
<tr>
<td height="20">HTC Desire HD</td>
<td>0,09</td>
<td>-0,44</td>
<td>0,53</td>
</tr>
<tr>
<td height="20">LG Optimus 2X</td>
<td>0,14</td>
<td>-0,04</td>
<td>0,18</td>
</tr>
<tr>
<td height="20">Apple IPhone 4S</td>
<td>0,05</td>
<td>-0,1</td>
<td>0,15</td>
</tr>
<tr>
<td height="20">Apple IPhone 4</td>
<td>0,01</td>
<td>-0,07</td>
<td>0,08</td>
</tr>
</tbody>
</table>
<div class="mceTemp mceIEcenter">
<div id="attachment_157" class="wp-caption aligncenter" style="width: 482px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/etendeue-2.png"><img class="size-full wp-image-157 " title="etendeue 2" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/etendeue-2.png" alt="" width="472" height="266" /></a><p class="wp-caption-text">Le Samsung Galaxy S II est le moins bon. Je suis désolé je n&#39;ai pas de valeur pour le Cowon IAudio 9 avec un casque. Les téléphones d&#39;Apple se comportent très bien !</p></div>
</div>
<h2 style="text-align: left;">Le niveau de bruit :</h2>
<p style="text-align: left;">Quand le son sort de l’appareil celui-ci peut être perturbé par des signaux parasites qui peuvent venir par exemple du champ Électromagnétique environnant (le téléphone communique) si le blindage de l’appareil n’est pas terrible, cela peut venir aussi du processeur etc… (Rendez vous ici pour écouter ce bruit sur le Samsung Galaxy S II <a href="http://soundcloud.com/anandtech/galaxysii-cpu-edge-noise">http://soundcloud.com/anandtech/galaxysii-cpu-edge-noise</a> )<br />
Ici la mesure se fait en dB (A), c&#8217;est l&#8217;unité retenue pour représenter les niveaux sonores en tenant compte de la sensibilité (selon la fréquence) de l’oreille humaine (l&#8217;humain entend moins bien les graves que les aiguës). Alors on fixe comme origine 40 dB au dessus du seuil d&#8217;audibilité. C&#8217;est à dire qu&#8217;à 0 dB(A) on est 40 dB au dessus du seuil où l&#8217;on entend plus rien.</p>
<p style="text-align: left;">On classe ci-dessous  les appareils en fonction de leur niveau de bruit.</p>
<table width="224" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="132" />
<col width="92" /> </colgroup>
<tbody>
<tr>
<td style="text-align: center;" width="132" height="20"><strong>Sans casque</strong></td>
<td style="text-align: center;" width="92"><strong>Noise Level (dB(A))</strong></td>
</tr>
<tr>
<td height="20">Samsung Galaxy S II</td>
<td align="right">-91,4</td>
</tr>
<tr>
<td height="20">Apple IPhone 4S</td>
<td align="right">-91,2</td>
</tr>
<tr>
<td height="20">HTC Desire HD</td>
<td align="right">-90,6</td>
</tr>
<tr>
<td height="20">Cowon IAudio 9</td>
<td align="right">-90,5</td>
</tr>
<tr>
<td height="20">HTC Sensation XE</td>
<td align="right">-90,2</td>
</tr>
<tr>
<td height="20">Apple IPhone 4</td>
<td align="right">-90,1</td>
</tr>
<tr>
<td height="20">LG Optimus 2X</td>
<td align="right">-90,1</td>
</tr>
</tbody>
</table>
<div id="attachment_161" class="wp-caption aligncenter" style="width: 411px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/niv-bruit.png"><img class="size-full wp-image-161 " title="niv bruit" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/niv-bruit.png" alt="" width="401" height="259" /></a><p class="wp-caption-text">Le Samsung Galaxy S II est ici le meilleur dans cette catégorie en tout cas sans charge. C&#39;est à dire sans casque.</p></div>
<table width="224" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="132" />
<col width="92" /> </colgroup>
<tbody>
<tr>
<td style="text-align: center;" width="132" height="20"><strong>Sans casque</strong></td>
<td style="text-align: center;" width="92"><strong>Noise Level (dB(A))</strong></td>
</tr>
<tr>
<td height="20">HTC Desire HD</td>
<td align="right">-93,2</td>
</tr>
<tr>
<td height="20">Apple IPhone 4S</td>
<td align="right">-91,3</td>
</tr>
<tr>
<td height="20">Apple IPhone 4</td>
<td align="right">-90,4</td>
</tr>
<tr>
<td height="20">Samsung Galaxy S II</td>
<td align="right">-90</td>
</tr>
<tr>
<td height="20">LG Optimus 2X</td>
<td align="right">-89,8</td>
</tr>
<tr>
<td height="20">HTC Sensation XE</td>
<td align="right">-89,1</td>
</tr>
</tbody>
</table>
<div id="attachment_165" class="wp-caption aligncenter" style="width: 461px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/niv-bruit2.png"><img class="size-full wp-image-165 " title="niv bruit2" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/niv-bruit2.png" alt="" width="451" height="274" /></a><p class="wp-caption-text">Le HTC desire HD est roi. Et le HTC Sensation XE le moins bon.</p></div>
<p style="text-align: left;">Je tiens à modérer ces résultats, soyons honnêtes le HTC Sensation XE à un rapport signal bruit de -89 dB ce qui signifie que le bruit est 77 000 fois trop faible pour être entendu par l&#8217;être humain. Pour le Desire HD, c&#8217;est 200 000 fois&#8230;</p>
<h2 style="text-align: left;">La gamme dynamique :</h2>
<p style="text-align: left;">C’est la capacité qu’a un appareil à reproduire en même temps un son peu intense et très intense. Pour éviter la triche, on mesure uniquement les signaux qui ne subissent pas de distorsion (grossièrement de déformation). Par exemple si un appareil est capable de produire des sons pour une fréquence donnée de 9 dB(A) à 1 dB(A), la gamme dynamique vaut 8 dB(A). Plus cette gamme (dynamic range) est grande et mieux c’est !</p>
<table width="384" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="264" />
<col width="120" /> </colgroup>
<tbody>
<tr>
<td style="text-align: center;" width="264" height="21"><strong>Nom</strong></td>
<td style="text-align: center;" width="120"><strong>Dynamic Range (dB(A))</strong></td>
</tr>
<tr>
<td width="264" height="21">HTC Desire HD (Casque)</td>
<td align="right" width="120">92,90</td>
</tr>
<tr>
<td width="264" height="21">Samsung Galaxy S II</td>
<td align="right" width="120">91,90</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4S (Casque)</td>
<td align="right" width="120">91,30</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4S</td>
<td align="right" width="120">91,20</td>
</tr>
<tr>
<td width="264" height="21">Cowon Iaudio 9</td>
<td align="right" width="120">90,50</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4 (Casque)</td>
<td align="right" width="120">90,40</td>
</tr>
<tr>
<td width="264" height="21">HTC Desire HD</td>
<td align="right" width="120">90,40</td>
</tr>
<tr>
<td width="264" height="21">Samsung Galaxy S II (Casque)</td>
<td align="right" width="120">90,20</td>
</tr>
<tr>
<td width="264" height="21">HTC Sensation</td>
<td align="right" width="120">90,20</td>
</tr>
<tr>
<td width="264" height="21">HTC Sensation (Casque)</td>
<td align="right" width="120">90,10</td>
</tr>
<tr>
<td width="264" height="21">LG Optimus 2X</td>
<td align="right" width="120">90,10</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4</td>
<td align="right" width="120">90,00</td>
</tr>
<tr>
<td width="264" height="20">LG Optimus 2X (Casque)</td>
<td align="right" width="120">89,90</td>
</tr>
</tbody>
</table>
<div id="attachment_168" class="wp-caption aligncenter" style="width: 480px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Gamme-dynamique1.png"><img class="size-full wp-image-168 " title="Gamme dynamique" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Gamme-dynamique1.png" alt="" width="470" height="368" /></a><p class="wp-caption-text">Avec un casque le HTC Desire HD est encore une fois le meilleur suivi des IPhone et du Samsung. Le HTC Sensation semble à la traine...</p></div>
<h2 style="text-align: left;">Le taux de distorsion harmonique :</h2>
<p style="text-align: left;">La distorsion harmonique, notée THD est une spécificité des amplificateurs (ou préamplificateurs). Comme nous l’avons vu tout à l’heure on peut décomposer n’importe quel signal audio sous forme de signaux sinusoïdaux. Le signal prépondérant est le fondamental (ce signal donne la hauteur de la note), les autres les harmoniques (elles donnent le timbre, la note LA du piano ne s&#8217;entend pas comme le LA d&#8217;une clarinette). En fait plus la quantité d’harmoniques est grande plus le signal est précis :</p>
<div id="attachment_172" class="wp-caption aligncenter" style="width: 482px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Synthesis_square.gif"><img class="size-full wp-image-172" title="Synthesis_square" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Synthesis_square.gif" alt="" width="472" height="200" /></a><p class="wp-caption-text">Plus le nombre d&#39;harmoniques augmente plus le signal reconstitué est proche du signal carré.</p></div>
<p style="text-align: left;">Pour conclure le taux de distorsion harmonique est le résultat d’un calcul mathématique ayant pour but de comparer le signal de sortie (ce qui sort du jack) et le signal d’entrée (le fichier audio). Plus ce taux est important plus la différence est importante et donc plus l’amplificateur est médiocre.</p>
<table width="384" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="264" />
<col width="120" /> </colgroup>
<tbody>
<tr>
<td style="text-align: center;" width="264" height="21"><strong>Nom</strong></td>
<td style="text-align: center;" width="120"><strong>THD (%)</strong></td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4S</td>
<td align="right" width="120">0,002</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4 (Casque)</td>
<td align="right" width="120">0,0036</td>
</tr>
<tr>
<td width="264" height="21">Samsung Galaxy S II</td>
<td align="right" width="120">0,0042</td>
</tr>
<tr>
<td width="264" height="21">Cowon Iaudio 9</td>
<td align="right">0,0048</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4S (Casque)</td>
<td align="right" width="120">0,0068</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4</td>
<td align="right" width="120">0,0068</td>
</tr>
<tr>
<td width="264" height="21">LG Optimus 2X (Casque)</td>
<td align="right" width="120">0,0098</td>
</tr>
<tr>
<td width="264" height="21">LG Optimus 2X</td>
<td align="right" width="120">0,011</td>
</tr>
<tr>
<td width="264" height="21">HTC Sensation</td>
<td align="right" width="120">0,012</td>
</tr>
<tr>
<td width="264" height="21">Samsung Galaxy S II (Casque)</td>
<td align="right" width="120">0,013</td>
</tr>
<tr>
<td width="264" height="21">HTC Desire HD</td>
<td align="right" width="120">0,014</td>
</tr>
<tr>
<td width="264" height="21">HTC Sensation (Casque)</td>
<td align="right" width="120">0,019</td>
</tr>
<tr>
<td width="264" height="20">HTC Desire HD (Casque)</td>
<td align="right" width="120">0,02</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<div id="attachment_170" class="wp-caption aligncenter" style="width: 528px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Gamme-dynamique2.png"><img class="size-full wp-image-170 " title="Distorsion Harmonique" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Gamme-dynamique2.png" alt="" width="518" height="358" /></a><p class="wp-caption-text">On remarque que cette fois ci le Desire HD est en retrait en ayant le plus haut THD. Le HTC Sensation ne brille toujours pas. Par contre les IPhones sont vraiment bons.</p></div>
<h2 style="text-align: left;">Distorsion d&#8217;intermodulation + bruit :</h2>
<p style="text-align: left;">C’est un phénomène complexe qui est la conséquence de la non linéarité du DAC. Si on a un signal avec deux fréquences différentes en entrée nous n’obtenons pas deux fréquences en sortie mais une multitude de signaux. Au premier ordre on voit bien ci-dessous deux pics secondaires en plus des deux pics de base ) gauche et à droite.</p>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/783px-RF_Intermodulation_at_280_MHz.jpg"><img class="aligncenter size-medium wp-image-173" title="783px-RF_Intermodulation_at_280_MHz" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/783px-RF_Intermodulation_at_280_MHz-300x229.jpg" alt="" width="300" height="229" /></a></p>
<p style="text-align: left;">C’est ce phénomène qui est mesuré par l&#8217;IMD. Plus ce nombre est faible moins la distorsion est importante, mieux c’est.</p>
<table width="384" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="264" />
<col width="120" /> </colgroup>
<tbody>
<tr>
<td style="text-align: center;" width="264" height="21"><strong>Nom</strong></td>
<td style="text-align: center;" width="120"><strong>IMD (%)</strong></td>
</tr>
<tr>
<td width="264" height="21">Cowon Iaudio 9</td>
<td align="right">0,0094</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4S</td>
<td align="right" width="120">0,012</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4</td>
<td align="right" width="120">0,012</td>
</tr>
<tr>
<td width="264" height="21">LG Optimus 2X</td>
<td align="right" width="120">0,016</td>
</tr>
<tr>
<td width="264" height="21">HTC Sensation</td>
<td align="right" width="120">0,021</td>
</tr>
<tr>
<td width="264" height="21">Samsung Galaxy S II</td>
<td align="right" width="120">0,066</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4S (Casque)</td>
<td align="right" width="120">0,071</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4 (Casque)</td>
<td align="right" width="120">0,092</td>
</tr>
<tr>
<td width="264" height="21">LG Optimus 2X (Casque)</td>
<td align="right" width="120">0,111</td>
</tr>
<tr>
<td width="264" height="21">HTC Desire HD</td>
<td align="right" width="120">0,517</td>
</tr>
<tr>
<td width="264" height="21">HTC Sensation (Casque)</td>
<td align="right" width="120">0,522</td>
</tr>
<tr>
<td width="264" height="21">Samsung Galaxy S II (Casque)</td>
<td align="right" width="120">0,647</td>
</tr>
<tr>
<td width="264" height="20">HTC Desire HD (Casque)</td>
<td align="right" width="120">0,728</td>
</tr>
</tbody>
</table>
</div>
<div class="mceTemp mceIEcenter">
<div id="attachment_174" class="wp-caption aligncenter" style="width: 490px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Gamme-dynamique3.png"><img class="size-full wp-image-174 " title="Dispersion intermodale" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Gamme-dynamique3.png" alt="" width="480" height="318" /></a><p class="wp-caption-text">Le HTC Desire HD a encore de grandes difficultés ici. Le Samsung Galaxy S II galère aussi (c&#39;est relatif). L&#39;IPhone 4 est encore une fois très très bon.</p></div>
</div>
<div class="mceTemp mceIEcenter">
<h2 style="text-align: left;">Diaphonie Stéréo :</h2>
<p style="text-align: left;">Si on envoie un signal dans l&#8217;oreille droite. Le signal passe t’il aussi à gauche ? Et bien oui ! On compare dans ce test la puissance du signal à gauche par rapport à celui à droite. Plus ce rapport est faible, plus la stéréo est bonne !</p>
<table width="384" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="264" />
<col width="120" /> </colgroup>
<tbody>
<tr>
<td style="text-align: center;" width="264" height="21"><strong>Nom</strong></td>
<td style="text-align: center;" width="120"><strong>Stereo crosstalk (dB)</strong></td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4S</td>
<td align="right" width="120">-93</td>
</tr>
<tr>
<td width="264" height="21">HTC Desire HD</td>
<td align="right" width="120">-92,6</td>
</tr>
<tr>
<td width="264" height="21">HTC Sensation</td>
<td align="right" width="120">-91,1</td>
</tr>
<tr>
<td height="21">Cowon Iaudio 9</td>
<td align="right">-90,3</td>
</tr>
<tr>
<td width="264" height="21">Samsung Galaxy S II</td>
<td align="right" width="120">-89,7</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4</td>
<td align="right" width="120">-89,6</td>
</tr>
<tr>
<td width="264" height="21">LG Optimus 2X</td>
<td align="right" width="120">-89,2</td>
</tr>
<tr>
<td width="264" height="21">HTC Sensation (Casque)</td>
<td align="right" width="120">-70,6</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4 (Casque)</td>
<td align="right" width="120">-68,4</td>
</tr>
<tr>
<td width="264" height="21">Apple iPhone 4S (Casque)</td>
<td align="right" width="120">-66,7</td>
</tr>
<tr>
<td width="264" height="21">Samsung Galaxy S II (Casque)</td>
<td align="right" width="120">-49,4</td>
</tr>
<tr>
<td width="264" height="21">LG Optimus 2X (Casque)</td>
<td align="right" width="120">-35,1</td>
</tr>
<tr>
<td width="264" height="20">HTC Desire HD (Casque)</td>
<td align="right" width="120">-17,9</td>
</tr>
</tbody>
</table>
</div>
<div class="mceTemp mceIEcenter" style="text-align: left;">
<dl id="attachment_176" class="wp-caption aligncenter" style="width: 487px;">
<dt class="wp-caption-dt"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Gamme-dynamique4.png"><img class="size-full wp-image-176 " title="Stereo Crosstalk" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Gamme-dynamique4.png" alt="" width="477" height="438" /></a></dt>
<dd class="wp-caption-dd">Le HTC Sensation est une fois n&#8217;est pas coutume devant tout les autres ! Le HTC Desire HD par contre est bien plus mauvais. Le Samsung Galaxy S II est aussi en retrait.</dd>
</dl>
</div>
<div class="mceTemp mceIEcenter" style="text-align: left;">
<h2>Conclusion</h2>
<p>Pour finir comparons deux smartphones haut de gamme avec trois appareils (sans casque) :</p>
<ul>
<li>La Nintendo DS Lite réputée pour avoir un son très mauvais.</li>
<li>Le lecteur Mini Disc Sony MZ-R3 représentant le haut de gamme&#8230; Il y a 15 ans.</li>
<li>Le Cowon IAudio 9, un excellent lecteur contemporain.</li>
</ul>
<table width="641" border="0" cellspacing="0" cellpadding="0">
<colgroup>
<col width="122" />
<col span="2" width="80" />
<col width="119" />
<col span="3" width="80" /> </colgroup>
<tbody>
<tr>
<td width="122" height="21"></td>
<td width="80">Etendue réponse en Fréquence (dB)</td>
<td width="80">Noise level (dB(A))</td>
<td width="119">Dynamic Range (dB(A))</td>
<td width="80">THD (%)</td>
<td width="80">IMD + Noise (%)</td>
<td width="80">Stereo CrossTalk (dB)</td>
</tr>
<tr>
<td height="21">Sensation</td>
<td align="right">0,39</td>
<td align="right">-90,2</td>
<td align="right">90,2</td>
<td align="right">0,012</td>
<td align="right">0,021</td>
<td align="right">-91,1</td>
</tr>
<tr>
<td height="21">IPhone 4S</td>
<td align="right">0,13</td>
<td align="right">-91,2</td>
<td align="right">91,2</td>
<td align="right">0,002</td>
<td align="right">0,012</td>
<td align="right">-93</td>
</tr>
<tr>
<td height="21">Nintendo DS Lite</td>
<td align="right">8,78</td>
<td align="right">-66</td>
<td align="right">64,5</td>
<td align="right">1,8</td>
<td align="right">3,836</td>
<td align="right">-69,1</td>
</tr>
<tr>
<td height="21">Mini Disc Sony MZ-R3</td>
<td align="right">1</td>
<td align="right">-86</td>
<td align="right">86,1</td>
<td align="right">1,658</td>
<td align="right">2,128</td>
<td align="right">-67,1</td>
</tr>
<tr>
<td height="21">Cowon Iaudio 9</td>
<td align="right">0,12</td>
<td align="right">-79</td>
<td align="right">79</td>
<td align="right">0,0058</td>
<td align="right">0,032</td>
<td align="right">-79,4</td>
</tr>
</tbody>
</table>
<div id="attachment_183" class="wp-caption aligncenter" style="width: 605px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Comparaison1.png"><img class="size-full wp-image-183 " title="Comparaison" src="http://blog.onkeysoft.com/wp-content/uploads/2011/10/Comparaison1.png" alt="" width="595" height="354" /></a><p class="wp-caption-text">Comparaison de deux smartphones avec trois autres appareils. Les unités sont modifiées pour être représentées sur le même graphique.</p></div>
<p>On voit sur ce graphique que relativement à la DS et au MiniDisc, les smartphones et le lecteur MP3 sont relativement proches. Globalement la qualité audio est là et je doute que l’oreille humaine avec un casque à moins de 500 € puisse y voir quelque chose. Ce n’est pas avec les écouteurs Beats de Dr. Dre que l’on verra une différence flagrante.</p>
<p>On a vu que la qualité Audio évolue avec l’impédance du casque. Plus l’impédance est faible, plus l&#8217;ampli abime le signal.</p>
<p>Comme je l’expliquais en introduction, la qualité audio dépend beaucoup de chacun et l&#8217;objectif principal est de se faire plaisir. Ce matériel n&#8217;est de toute manière pas adapté aux professionnels et il n&#8217;a même pas été conçu pour ça. Vous pouvez adapter le signal à vos goûts : si vous aimez les basses vous pouvez régler l’équaliseur en conséquence (c’est d’ailleurs ce que fait la technologie Beats de HTC) ou acheter des écouteurs favorisant les basses.</p>
<p>La qualité audio dépend aussi de beaucoup d&#8217;autres éléments que nous n&#8217;avons pas pris en compte, par exemple :</p>
<ul>
<li>Écoutez vous la musique dans un endroit bruyant ? Si vous êtes dans le métro, mais avec un casque très isolant, le bruit extérieur sera audible. Le Noise Level avec ses -80 dB(A) semble ridicule à côté&#8230;</li>
<li>Que vaut votre casque ? Si votre casque force sur les basses, la réponse en fréquence sera totalement différente&#8230;</li>
<li>Quelle est la qualité de vos fichiers musicaux ? Peut être écoutez vous du streaming ? La compression est souvent destructrice (lossy).</li>
<li>Avez vous une très bonne oreille ? Plus on vieillit, malheureusement, plus notre oreille perd en sensibilité. C&#8217;est un fait&#8230;</li>
<li><em>etc</em>&#8230;</li>
</ul>
<p>L&#8217;autre question à se poser est : êtes vous un puriste ?</p>
<ul>
<li>Avez vous un casque valant plusieurs centaines d&#8217;euros ou des intras à 500 € et un MP3 d&#8217;une très grand marque (souvent cher et moche <em>&#8216;Je rigole&#8217;</em>) ?</li>
<li>Écoutez vous constamment de la musique compressée en FLAC (lossless) et avez vous mis tout vos MP3 (lossy) à la corbeille ?</li>
</ul>
<p>Peut être que la qualité audio n&#8217;est pas l&#8217;élément principal à prendre en compte lors de l&#8217;achat de votre smartphone vu le peu de différences entre-eux. En tout cas cela ne semble pas être une question prépondérante lors de l&#8217;achat d&#8217;un téléphone.</p>
<h3>Sources :</h3>
<p><a href="http://www.gsmarena.com">GSMArena</a></p>
<p><a href="http://stereos.about.com/">About Stereos</a></p>
<p><a href="http://www.wikipedia.com">Wikipedia</a></p>
<p><a href="http://www.engadget.com">Engadget</a></p>
<p><a href="http://rmaa.elektrokrishna.com/">ElectroKrishna</a></p>
<p><a href="http://www.anandtech.com">ArnandTech</a></p>
<h2>Remarques :</h2>
<p>Si vous avez des remarques n&#8217;hésitez pas, je suis toujours à l&#8217;écoute. Je suis audiophile mais pas professionnel, les informations présentes ici sont donc à remettre dans leur contexte.</p>
<blockquote>
<p style="text-align: center;">Rémi MEVAERE</p>
</blockquote>
<p><img class="alignnone" title="Creative Commons" src="http://www.tetedequenelle.fr/wp-content/uploads/2009/06/cclogolarge1-300x71.png" alt="" width="153" height="36" /></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.onkeysoft.com/2011/10/23/qualite-audio-des-smartphones-en-2011/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Detecting a Delphi executable, DVCLAL, Manifest and PackageInfo</title>
		<link>http://blog.onkeysoft.com/2011/06/07/detecting-a-delphi-executable-dvclal-manifest-and-packageinfo/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=detecting-a-delphi-executable-dvclal-manifest-and-packageinfo</link>
		<comments>http://blog.onkeysoft.com/2011/06/07/detecting-a-delphi-executable-dvclal-manifest-and-packageinfo/#comments</comments>
		<pubDate>Tue, 07 Jun 2011 12:09:21 +0000</pubDate>
		<dc:creator>remixtech</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[detection delphi]]></category>
		<category><![CDATA[DVCLAL]]></category>
		<category><![CDATA[manifest]]></category>
		<category><![CDATA[packageinfo]]></category>

		<guid isPermaLink="false">http://blog.onkeysoft.com/?p=119</guid>
		<description><![CDATA[In this post I will try to expose several ways to detect a Delphi application. I will try to improve my English in this post. I understand that I must work on it! First Part DVCLAL and licensing information Yesterday I was asking me a question. What information could we extract from a Delphi executable [...]]]></description>
			<content:encoded><![CDATA[<p>In this post I will try to expose several ways to detect a Delphi application.<br />
<span id="more-119"></span><br />
I will try to improve my English in this post. I understand that I must work on it! </p>
<h1>First Part DVCLAL and licensing information</h1>
<p>Yesterday I was asking me a question. What information could we extract from a Delphi executable about the compiler, the license and all these things?</p>
<p>First thing I done was just compiling a simple application form (Delphi XE) and watch if there is something in it.</p>
<p>I have three Executable:</p>
<ol>
<li>With a valid license</li>
<li>With the same valid license</li>
<li>With another valid license from a friend</li>
<li>Without license</li>
</ol>
<p><strong><span style="text-decoration: underline;">MD5</span></strong></p>
<ol>
<li>aa937b519d3dc7748658339d74beab71</li>
<li>3a052680d1baa16b53a7376e94d88bb6</li>
<li>eb66631ce3aa2ab2bfeb27779164dfa1</li>
<li>35f29fbcbf468dc1a683f742893d54b1</li>
</ol>
<p>The files are different, even the first and second (which are compiled with the same license in less than 2 minutes). Something is added in the file, like a date or a time.</p>
<p><strong><span style="text-decoration: underline;">DVCLAL – Resource Name for RC_DATA</span></strong></p>
<ol>
<li>000DEF00  26 3D 4F 38 C2 82 37 B8 F3 24 42 03 17 9B 3A      &amp;=O8Â‚7¸ó$B••›:</li>
<li>000DEF00  26 3D 4F 38 C2 82 37 B8 F3 24 42 03 17 9B 3A      &amp;=O8Â‚7¸ó$B••›:</li>
<li>000DEF00  26 3D 4F 38 C2 82 37 B8 F3 24 42 03 17 9B 3A      &amp;=O8Â‚7¸ó$B••›:</li>
<li>000DEF00  26 3D 4F 38 C2 82 37 B8 F3 24 42 03 17 9B 3A      &amp;=O8Â‚7¸ó$B••›:</li>
</ol>
<p>DVCLAL (Delphi Visual Component Library Access License) are the same for the three files, this is pretty strange.</p>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/06/DVCLAL.png"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/06/DVCLAL.png"><img class="aligncenter size-full wp-image-120" title="DVCLAL" src="http://blog.onkeysoft.com/wp-content/uploads/2011/06/DVCLAL.png" alt="" width="546" height="170" /></a></a></p>
<p>To detect the change between file I am using the command line tool “compare” included in Windows. So as you can see the differences between file are exactly at the same offset and are equal. It is unbelievable to store huge license information in 16 bytes (word) or 32 bytes (dword).</p>
<p>In green this is the beginning of the executable (low offset). In MSDN documentation you can find info about PE (Portable Header which is the structure of executable files).</p>
<p>If we open it in Hex Edit.</p>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/06/hexedit.png"><img class="aligncenter size-full wp-image-121" title="hexedit" src="http://blog.onkeysoft.com/wp-content/uploads/2011/06/hexedit.png" alt="" width="687" height="38" /></a></p>
<p>The PE chars follow by two null values are signature of the beginning of the executable. After that we have IMAGE_FILE_HEADER.</p>
<blockquote><p><strong>Syntax</strong></p>
<p>typedef struct _IMAGE_FILE_HEADER {</p>
<p>WORD  Machine;</p>
<p>WORD  NumberOfSections;</p>
<p>DWORD TimeDateStamp;</p>
<p>DWORD PointerToSymbolTable;</p>
<p>DWORD NumberOfSymbols;</p>
<p>WORD  SizeOfOptionalHeader;</p>
<p>WORD  Characteristics;</p>
<p>} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;</p></blockquote>
<p>&nbsp;</p>
<p>We have in HexEdit the first word which is 4C01, and the second one NumberOfSections 0A00. The DatetimeStamp is 14DEE84D. Clearly it’s the time information of the build.</p>
<blockquote><p>&nbsp;</p>
<p><strong>TimeDateStamp</strong></p>
<p>The low 32 bits of the time stamp of the image. This represents the date and time the image was created by the linker. The value is represented in the number of seconds elapsed since midnight (00:00:00), January 1, 1970, Universal Coordinated Time, according to the system clock.</p></blockquote>
<p>So let’s return to DVCLAL, and see when it is used by Delphi. So I search the string DVCLAL in Embarcadero folder. And the only file which is return is Sysutils.pas. (For copyright reasons I can’t share the code of the function in Delphi main pascal files)</p>
<p>The ALR function returns a pointer handle that can be used to obtain a pointer to the first byte of the specified resource in memory. Here the string DVCLAL.<br />
The GDAL function is testing the value of the DVCLAL and if there is a problem, the exe raise an exception.</p>
<p>The RPR function is testing the validity of DVCLAL and if there is a problem, raises an exception.</p>
<p>I don’t know if RPR is used in the last version of Delphi but in older version, when the exe was loading module he was launching the procedure RPR.</p>
<p>So in conclusion, just understand that DVCLAL is one way to detect Delphi app, but it is not secure, you could easily delete this value and nothing will appear.</p>
<h1>Manifest file attached to the executable and PackageInfo</h1>
<p>In the RC_DATA resource of Delphi executable you could find a Resource named PackageInfo. You will find more information in sysutils.pas. (Function GetPackageInfo)</p>
<blockquote><p>A variable of type <strong>PackageInfoTable</strong> provides information about initializing or finalizing a series of package units.</p></blockquote>
<p>The manifest file is in the resource type RC_Manifest with the name 1036 could help you to detect if the compiler is Delphi. (CodeGear Rad Studio in Assembly Name)</p>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/06/ResHacker.png"><img src="http://blog.onkeysoft.com/wp-content/uploads/2011/06/ResHacker.png" alt="" title="ResHacker" width="453" height="358" class="aligncenter size-full wp-image-124" /></a></p>
<pre>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
&lt;assembly xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot; manifestVersion=&quot;1.0&quot;&gt;
  &lt;assemblyIdentity
    type=&quot;win32&quot;
    name=&quot;CodeGear RAD Studio&quot;
    version=&quot;15.0.3953.35171&quot;
    processorArchitecture=&quot;*&quot;/&gt;
  &lt;dependency&gt;
    &lt;dependentAssembly&gt;
      &lt;assemblyIdentity
        type=&quot;win32&quot;
        name=&quot;Microsoft.Windows.Common-Controls&quot;
        version=&quot;6.0.0.0&quot;
        publicKeyToken=&quot;6595b64144ccf1df&quot;
        language=&quot;*&quot;
        processorArchitecture=&quot;*&quot;/&gt;
    &lt;/dependentAssembly&gt;
  &lt;/dependency&gt;
  &lt;trustInfo xmlns=&quot;urn:schemas-microsoft-com:asm.v3&quot;&gt;
    &lt;security&gt;
      &lt;requestedPrivileges&gt;
        &lt;requestedExecutionLevel
          level=&quot;asInvoker&quot;
          uiAccess=&quot;false&quot;/&gt;
        &lt;/requestedPrivileges&gt;
    &lt;/security&gt;
  &lt;/trustInfo&gt;
&lt;/assembly&gt;
 </pre>
<p>So I hope it will help you if you need to detect Delphi application. But the Application could be crypt, the resource could be easily modified and the DVCLAL deleted.</p>
<p>Have a nice day <img src='http://blog.onkeysoft.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.onkeysoft.com/2011/06/07/detecting-a-delphi-executable-dvclal-manifest-and-packageinfo/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Listing, Adding, Editing, Deleting resources of EXE, DLL &#8230; Using Win32 API with Delphi</title>
		<link>http://blog.onkeysoft.com/2011/06/03/listing-adding-editing-deleting-resources-of-exe-dll-using-win32-api-with-delphi/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=listing-adding-editing-deleting-resources-of-exe-dll-using-win32-api-with-delphi</link>
		<comments>http://blog.onkeysoft.com/2011/06/03/listing-adding-editing-deleting-resources-of-exe-dll-using-win32-api-with-delphi/#comments</comments>
		<pubDate>Fri, 03 Jun 2011 00:39:52 +0000</pubDate>
		<dc:creator>remixtech</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[BeginUpdateReSource]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[DLL]]></category>
		<category><![CDATA[EndUpdateReSource]]></category>
		<category><![CDATA[EnumResNameProc]]></category>
		<category><![CDATA[EnumResourceTypes]]></category>
		<category><![CDATA[EXE]]></category>
		<category><![CDATA[LoadLibraryEx]]></category>
		<category><![CDATA[resource]]></category>
		<category><![CDATA[resourcetype]]></category>
		<category><![CDATA[UpdateResource]]></category>
		<category><![CDATA[Win32 Api]]></category>

		<guid isPermaLink="false">http://blog.onkeysoft.com/?p=107</guid>
		<description><![CDATA[Today, I tried to work with resources included in a File. The file is an executable like DLL or EXE. There are some useful functions in the Win32 API that could help us, you don&#8217;t need to fully understand PE_FILE and how work an executable to change the resources. I would like to show you [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I tried to work with resources included in a File. The file is an executable like DLL or EXE. There are some useful functions in the Win32 API that could help us, you don&#8217;t need to fully understand PE_FILE and how work an executable to change the resources.</p>
<p><span id="more-107"></span></p>
<p>I would like to show you how to use it in Delphi.</p>
<h2>First Step : Listing all the resources</h2>
<p>How to open an executable file ?</p>
<p>LoadLibraryEx is described on this page of <a href="http://msdn.microsoft.com/en-us/library/ms684179%28v=vs.85%29.aspx" target="_blank">MSDN</a></p>
<pre>
var
hinstance: HMODULE;
begin
hinstance := LoadLibraryEx(PChar('c:\the_file.exe'), 0, LOAD_LIBRARY_AS_DATAFILE);

//HERE code with hinstance

FreeLibrary(hinstance);
</pre>
<p>To list all the resources we will use the EnumResourceTypes (function also described in MSDN) which is calling the function <a href="http://msdn.microsoft.com/en-us/library/ms648041%28v=vs.85%29.aspx" target="_blank">CallbackEnumResTypes</a>.</p>
<blockquote>
<h3>EnumResourceTypes Function</h3>
<p>Enumerates resource types within a binary module.</p>
<h4>Syntax</h4>
<div>
<div>
<div id="CodeSnippetContainerCode0">
<div>
<pre>BOOL WINAPI EnumResourceTypes(
  __in_opt  HMODULE hModule,
  __in      ENUMRESTYPEPROC lpEnumFunc,
  __in      LONG_PTR lParam
);</pre>
</div>
</div>
</div>
</div>
<h4>Parameters</h4>
<dl>
<dt><em>hModule</em> [in, optional]</dt>
<dd>Type: <strong>HMODULE</strong> </dd>
<dt><em>lpEnumFunc</em> [in]</dt>
<dd>Type: <strong>ENUMRESTYPEPROC</strong>A pointer to the callback function to be called for each enumerated resource type. For more information, see the <a href="http://msdn.microsoft.com/en-us/library/ms648041%28v=vs.85%29.aspx"><strong>EnumResTypeProc</strong></a> function.</p>
</dd>
<dt><em>lParam</em> [in]</dt>
<dd>Type: <strong>LONG_PTR</strong>An application-defined value passed to the callback function.</p>
</dd>
</dl>
<h4>Return Value</h4>
<p>Type: <strong>BOOL</strong></p>
<p>Returns TRUE if successful; otherwise, FALSE. To get extended error information, call <a href="http://msdn.microsoft.com/en-us/library/ms679360%28v=vs.85%29.aspx"><strong>GetLastError</strong></a>.</p>
<h4>Remarks</h4>
<p>For each resource type found, <strong>EnumResourceTypes</strong> calls an application-defined callback function <em>lpEnumFunc</em>, passing each resource type it finds, as well as the various other parameters that were passed to <strong>EnumResourceTypes</strong>.</p></blockquote>
<pre> EnumResourceTypes(hinstance, @CallbackEnumResTypes, Integer(ListBox1.Items));

//The first parameter is the Hinstance of the Executable, the second one is pointing on a function which will received the result of EnumResourceTypes and the last one is what you want !! Here a pointer to Listbox1.Items </pre>
<p>The ResType parameter is described by <a href="http://msdn.microsoft.com/en-us/library/ms648029%28v=vs.85%29.aspx" target="_blank">MSDN</a></p>
<dl>
<dd>
<blockquote>
<h4>Type: <strong>LPTSTR</strong></h4>
<p>The type of resource for which the type is being enumerated. Alternately, rather than a pointer, this parameter can be <a href="http://msdn.microsoft.com/en-us/library/ms648029%28v=vs.85%29.aspx"><strong>MAKEINTRESOURCE</strong></a>(ID), where ID is the integer identifier of the given resource type. For standard resource types, see <a href="http://msdn.microsoft.com/en-us/library/ms648009%28v=vs.85%29.aspx">Resource Types</a>. For more information, see the Remarks section below.</p>
<p>The return value is the specified value in the low-order word and zero in the high-order word.</p></blockquote>
</dd>
</dl>
<p>What is stdcall ?  I have forgotten ! <img src='http://blog.onkeysoft.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<blockquote><p>When you declare a procedure or function, you can specify a calling convention using one of the directives register, pascal, cdecl, stdcall, and safecall. Calling conventions determine the order in which parameters are passed to the routine. They also affect the removal of parameters from the stack, the use of registers for passing parameters, and error and exception handling. The default calling convention is register.</p>
<ul>
<li>register Left-to-right Routine Yes</li>
<li>pascal Left-to-right Routine No</li>
<li>cdecl Right-to-left Caller No</li>
<li>stdcall Right-to-left Routine No</li>
<li>safecall Right-to-left Routine No</li>
</ul>
</blockquote>
<pre>
function CallbackEnumResTypes(HInstance: HMODULE; ResType: PChar; OutList: TStrings): Integer; stdcall;
begin

if HiWord(Cardinal(ResType)) &lt;&gt; 0 then
OutList.Add(ResType) // The HighWord &lt;&gt; 0 This is strange MSDN explain us that hi-order word must be zero
else
OutList.Add(Format('Resource Number %d: Description %s', [loword(Cardinal(ResType)), StockResourceType(ResType)]));

EnumResourceNames(HInstance, ResType, @enumResNamesProc, Integer(OutList));  // Enum all the Resources

Result := 1;   // Continue The enumeration
end;
</pre>
<p>So we have used a function name StockResourceType wich are giving us a String describing the Type of the <a href="http://msdn.microsoft.com/en-us/library/ms648009%28v=vs.85%29.aspx" target="_blank">Resource</a> (All the information on this page)</p>
<pre>

Function StockResourceType(ResType: PChar): string;
const
ResTypeNames: Array [1 .. 24] of String = ('RT_CURSOR',
'RT_BITMAP',
'RT_ICON',
'RT_MENU',
'RT_DIALOG',
'RT_STRING',
'RT_FONTDIR',
'RT_FONT',
'RT_ACCELERATOR',
'RT_RCDATA',
'RT_MESSAGETABLE',
'RT_GROUP_CURSOR',
'UNKNOWN',
'RT_GROUP_ICON',
'UNKNOWN',
'RT_VERSION',
'RT_DLGINCLUDE',
'UNKNOWN', 'RT_PLUGPLAY',
'RT_VXD',
'RT_ANICURSOR',
'RT_ANIICON',
'RT_HTML',
'RT_MANIFEST'
);
var
ResID: Cardinal absolute ResType;
begin
if ResID in [1 .. 24] then
Result := ResTypeNames[ResID]
else
Result := 'UNKNOWN';
end;
</pre>
<p>What is absolute directive ?  I have forgotten ! <img src='http://blog.onkeysoft.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<blockquote><p>You can create a new variable that resides at the same address as another variable. To do so, put the directive absolute after the type name in the declaration of the new variable, followed by the name of an existing (previously declared) variable. We can here use Restype which is a Pchar in a particular address in a ResId function which is a Cardinal.</p></blockquote>
<p>For the Callback function EnumResourceNames, this is the same thing.</p>
<blockquote>
<div id="CodeSnippetContainerCode0">
<div>
<pre>BOOL CALLBACK EnumResNameProc(
  __in_opt  HMODULE hModule,
  __in      LPCTSTR lpszType,
  __in      LPTSTR lpszName,
  __in      LONG_PTR lParam
);</pre>
</div>
</div>
<h4>Parameters</h4>
<dl>
<dt><em>lpszType</em> [in]</dt>
<dd>
<h4>Type: <strong>LPCTSTR</strong></h4>
<p>The type of resource for which the name is being enumerated. Alternately, rather than a pointer, this parameter can be <code>MAKEINTRESOURCE(ID)</code>, where ID is an integer value representing a predefined resource type. For standard resource types, see <a href="http://msdn.microsoft.com/en-us/library/ms648009%28v=vs.85%29.aspx">Resource Types</a>. For more information, see the Remarks section below.</p>
</dd>
<dt><em>lpszName</em> [in]</dt>
<dd>
<h4>Type: <strong>LPTSTR</strong></h4>
<p>The name of a resource of the type being enumerated. Alternately, rather than a pointer, this parameter can be <code>MAKEINTRESOURCE(ID)</code>, where ID is the integer identifier of the resource. For more information, see the Remarks section below.</p>
</dd>
</dl>
</blockquote>
<pre>

function EnumResNamesProc(module: HMODULE; ResType, ResName: PChar; list: TStrings): Integer; stdcall;
begin
if HiWord(Cardinal(ResName)) &lt;&gt; 0 then
list.Add('  ' + ResName)
else
list.Add(Format('  #%d', [loword(Cardinal(ResName))]));
Result := 1; // Continue !
end;
</pre>
<h2>Second Step : Adding, Editing, Deleting resources</h2>
<blockquote>
<h3>UpdateResource Function</h3>
<p>Adds, deletes, or replaces a resource in a portable executable (PE) file. There are some restrictions on resource updates in files that contain Resource Configuration (RC Config) data: <a href="http://msdn.microsoft.com/en-us/library/dd319070%28v=vs.85%29.aspx">language-neutral</a> (LN) files and language-specific resource (.mui) files.</p>
<h4>Syntax</h4>
<div>
<div>
<div id="CodeSnippetContainerCode0">
<div>
<pre>BOOL WINAPI UpdateResource(
  __in      HANDLE hUpdate,
  __in      LPCTSTR lpType,
  __in      LPCTSTR lpName,
  __in      WORD wLanguage,
  __in_opt  LPVOID lpData,
  __in      DWORD cbData
);</pre>
</div>
</div>
</div>
</div>
<h3>Parameters</h3>
<dl>
<dt><em>hUpdate</em> [in]</dt>
<dd>Type: <strong>HANDLE</strong>A module handle returned by the <a href="http://msdn.microsoft.com/en-us/library/ms648030%28v=vs.85%29.aspx"><strong>BeginUpdateResource</strong></a> function, referencing the file to be updated.</p>
</dd>
<dt><em>lpType</em> [in]</dt>
<dd>Type: <strong>LPCTSTR</strong>The resource type to be updated. Alternatively, rather than a pointer, this parameter can be <a href="http://msdn.microsoft.com/en-us/library/ms648029%28v=vs.85%29.aspx"><strong>MAKEINTRESOURCE</strong></a>(ID), where ID is an integer value representing a predefined resource type. If the first character of the string is a pound sign (#), then the remaining characters represent a decimal number that specifies the integer identifier of the resource type. For example, the string &#8220;#258&#8243; represents the identifier 258.</p>
<p>For a list of predefined resource types, see <a href="http://msdn.microsoft.com/en-us/library/ms648009%28v=vs.85%29.aspx">Resource Types</a>.</p>
</dd>
<dt><em>lpName</em> [in]</dt>
<dd>Type: <strong>LPCTSTR</strong>The name of the resource to be updated. Alternatively, rather than a pointer, this parameter can be <a href="http://msdn.microsoft.com/en-us/library/ms648029%28v=vs.85%29.aspx"><strong>MAKEINTRESOURCE</strong></a>(ID), where ID is a resource ID. When creating a new resource do not use a string that begins with a &#8216;#&#8217; character for this parameter.</p>
</dd>
<dt><em>wLanguage</em> [in]</dt>
<dd>Type: <strong>WORD</strong>The <a href="http://msdn.microsoft.com/en-us/library/dd318691%28v=vs.85%29.aspx">language identifier</a> of the resource to be updated. For a list of the primary language identifiers and sublanguage identifiers that make up a language identifier, see the <a href="http://msdn.microsoft.com/en-us/library/dd373908%28v=vs.85%29.aspx"><strong>MAKELANGID</strong></a> macro.</p>
</dd>
<dt><em>lpData</em> [in, optional]</dt>
<dd>Type: <strong>LPVOID</strong>The resource data to be inserted into the file indicated by <em>hUpdate</em>. If the resource is one of the predefined types, the data must be valid and properly aligned. Note that this is the raw binary data to be stored in the file indicated by <em>hUpdate</em>, not the data provided by <a href="http://msdn.microsoft.com/en-us/library/ms648072%28v=vs.85%29.aspx"><strong>LoadIcon</strong></a>, <a href="http://msdn.microsoft.com/en-us/library/ms647486%28v=vs.85%29.aspx"><strong>LoadString</strong></a>, or other resource-specific load functions. All data containing strings or text must be in Unicode format. <em>lpData</em> must not point to ANSI data.</p>
<p>If <em>lpData</em> is NULL and <em>cbData</em> is 0, the specified resource is deleted from the file indicated by <em>hUpdate</em>.</p>
</dd>
<dt><em>cbData</em> [in]</dt>
<dd>Type: <strong>DWORD</strong>The size, in bytes, of the resource data at <em>lpData</em>.</p>
</dd>
</dl>
<h4>Return Value</h4>
<p>Type: <strong>BOOL</strong></p>
<p>Returns TRUE if successful or FALSE otherwise. To get extended error information, call <a href="http://msdn.microsoft.com/en-us/library/ms679360%28v=vs.85%29.aspx"><strong>GetLastError</strong></a>.</p></blockquote>
<h3>Adding</h3>
<pre>var
FileHandle: THandle;
Filebuffer: ShortString;
Test: PChar;</pre>
<pre>

Filebuffer := 'Something to add this is a string ! Not Unicode here <img src='http://blog.onkeysoft.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  ! ';
FileHandle := BeginUpdateReSource(PChar('c:\the_exe.exe'), False); // begin updating our resource
UpdateReSource(FileHandle, RT_RCDATA, 'THE_NAME_OF_THE_RESOURCE', 0, @Filebuffer[1], Length(Filebuffer));  // Updating the resource
EndUpdateReSource(FileHandle, False); // End of the update
</pre>
<h3>Editing</h3>
<pre>
UpdateReSource(FileHandle, RT_RCDATA, 'EXIST_NAME', 0, @Filebuffer[1], Length(Filebuffer));  // Updating the resource, the EXIST_NAME resource exist !
</pre>
<h3>Removing</h3>
<pre>

Filebuffer := ''; // To delete just create something empty or clear !
UpdateReSource(FileHandle, RT_RCDATA, 'EXIST_NAME', 0, @Filebuffer[1], Length(Filebuffer));  // Updating the resource, the EXIST_NAME resource exist !
</pre>
<h2>Third Step : And for a bitmap ?</h2>
<p>This is a small piece of code which will give you an example of how to add a bitmap in resource&#8230; After that you will now how to add Cursor, Song etc&#8230;</p>
<pre>

var
HInstance: THandle;
bitmap: Pointer;
FS: TFILESTREAM;
dwSize: DWORD;
begin
HInstance:= BeginUpdateResource(THE_EXECUTABLE_PATH, false);

FS := TFileStream.Create(THE_BITMAP_PATH, fmOpenRead or fmShareDenyWrite); // Opening a TFileStream
GetMem(bitmap, FS.Size + 1); // Get memory to add the Bitmap in memory
FS.ReadBuffer(bitmap^, FS.Size); // Full this part of the Memory with Bitmap DATA
dwSize := FS.Size; // Size of the Bitmap
FS.Free; // Closing the TFileStream

UpdateResource(HInstance, PWideChar(RT_BITMAP), '6805'  , LANG_SYSTEM_DEFAULT, bitmap, dwSize); // 6805 is the name, and the language is the default of my system

EndUpdateResourceW(HInstance, false);
end;
</pre>
<p>I hope it will help you to use Resources.</p>
<p>Have a good week,</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.onkeysoft.com/2011/06/03/listing-adding-editing-deleting-resources-of-exe-dll-using-win32-api-with-delphi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Help Science with your computer : Folding@Home</title>
		<link>http://blog.onkeysoft.com/2011/05/29/help-science-with-your-computer-foldinghome/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=help-science-with-your-computer-foldinghome</link>
		<comments>http://blog.onkeysoft.com/2011/05/29/help-science-with-your-computer-foldinghome/#comments</comments>
		<pubDate>Sat, 28 May 2011 23:58:31 +0000</pubDate>
		<dc:creator>remixtech</dc:creator>
				<category><![CDATA[Geek things]]></category>
		<category><![CDATA[fah]]></category>
		<category><![CDATA[folding@home]]></category>

		<guid isPermaLink="false">http://blog.onkeysoft.com/?p=101</guid>
		<description><![CDATA[Folding@home is the most powerful distributed computing cluster in the world, according to Guinness,and one of the world&#8217;s largest distributed computing projects. The goal of the project is &#8220;to understand protein folding, misfolding, and related diseases.&#8221; I would like to share my experience about this program of distributed computing. First I have one powerful computer [...]]]></description>
			<content:encoded><![CDATA[<p>Folding@home is the most powerful distributed computing cluster in the world, according to Guinness,and one of the world&#8217;s largest distributed computing projects. The goal of the project is &#8220;to understand protein folding, misfolding, and related diseases.&#8221;</p>
<p>I would like to share my experience about this program of distributed computing. First I have one powerful computer (Quad Core CPU and 2 GPU) and one server (okay it&#8217;is not a powerfull one, but it is enough for me and my several websites).<br />
<span id="more-101"></span></p>
<div id="attachment_102" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/05/fah_2.png"><img class="size-medium wp-image-102" title="fah_2" src="http://blog.onkeysoft.com/wp-content/uploads/2011/05/fah_2-300x141.png" alt="" width="300" height="141" /></a><p class="wp-caption-text">New software of Folding@Home V7</p></div>
<p>When I am coding, I am using a small part of the power of my system and my server is not overload <img src='http://blog.onkeysoft.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> . So my computers could be useful to help science and research like all the servers of Google which are also supporting this project ! In only two months, I am  in the top five percent position. Let&#8217;s see the graph.</p>
<div id="attachment_103" class="wp-caption aligncenter" style="width: 310px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/05/fah.png"><img class="size-medium wp-image-103" title="fah" src="http://blog.onkeysoft.com/wp-content/uploads/2011/05/fah-300x190.png" alt="" width="300" height="190" /></a><p class="wp-caption-text">My rank in Folding@Home</p></div>
<p>Actually I am student and I can&#8217;t give money to charity association, and I don&#8217;t like this, I think this is the job of government. But I prefer being active on a global and worldwide project with a lot of peoples (1552132 peoples at this time, number of registration). This is, in my opinion, a form of donation !</p>
<p>Like me you could be a part of this adventure, don&#8217;t wait just click <a title="Folding @ Home" href="http://folding.stanford.edu/" target="_blank">here</a> !</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.onkeysoft.com/2011/05/29/help-science-with-your-computer-foldinghome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some functions and properties of TIDPop3</title>
		<link>http://blog.onkeysoft.com/2011/05/11/some-functions-et-properties-of-tidpop3/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=some-functions-et-properties-of-tidpop3</link>
		<comments>http://blog.onkeysoft.com/2011/05/11/some-functions-et-properties-of-tidpop3/#comments</comments>
		<pubDate>Wed, 11 May 2011 00:25:16 +0000</pubDate>
		<dc:creator>remixtech</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Indy components]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[indy]]></category>
		<category><![CDATA[pop3]]></category>
		<category><![CDATA[pop3 server]]></category>
		<category><![CDATA[source code]]></category>
		<category><![CDATA[tidpop3]]></category>

		<guid isPermaLink="false">http://blog.onkeysoft.com/?p=95</guid>
		<description><![CDATA[In the last post which was dealing with Indy. We have seen how to configure TIDPop3. Let’s see how to use this component. In the uses dont forget to add the IDPop3 file which contains all the information for TIDPop3. uses Idpop3; type POP3Client: TIdPOP3; The first thing I do is write a procedure to [...]]]></description>
			<content:encoded><![CDATA[<p>In the last post which was dealing with Indy. We have seen how to configure TIDPop3. Let’s see how to use this component.</p>
<p>In the uses dont forget to add the IDPop3 file which contains all the information for TIDPop3.</p>
<pre>
uses
Idpop3;
type
POP3Client: TIdPOP3;
</pre>
<p><span id="more-95"></span></p>
<p>The first thing I do is write a procedure to retrieve the <strong>status </strong>from the TIDPop3 :</p>
<pre>
procedure Thread_POP3.POP3Status(ASender: TObject; const AStatus: TIdStatus; const AStatusText: string);
begin
Synchronize
( procedure begin
// USE AStatusText
end);
end;

// After the creation of POP3Client we can assign this event
POP3Client          := TIdPOP3.Create(nil);
POP3Client.OnStatus := POP3Status;
</pre>
<p>To connect to the server just use the procedure <strong>Connect</strong>, lets see other methods :</p>
<pre>
POP3Client.Connect; // Connection
POP3Client.login; // Use it to Connect
</pre>
<p>If you want to get the number of mails just use the function <strong>CheckMessages</strong>, and to get the mail the mail number I <strong>RetrieveMsgSize(I)</strong> :</p>
<pre>
FNbrMailsOnline := POP3Client.CheckMessages; // Retrieve the number of mails on the server
FTailleDernierMail := POP3Client.RetrieveMsgSize(FNbrMailsOnline); // Retrieve the size of the Last Mail
</pre>
<p>To delete a mail just do this :</p>
<pre>
POP3Client.Delete(I); // The mail will only be delete when you will disconnect
// If you want to cancel the deletion just use the
POP3Client.Reset; // Cancel the deletion
</pre>
<h2>Now let&#8217;s see how to retrieve mails :</h2>
<p>Tell Delphi where to find the TIDMessage class</p>
<pre>
uses
IDMessage;
type
Message: TIDMessage;
</pre>
<p>If you want to retrieve only the header of a mail (not the all mail, just the basics information) :</p>
<pre>
POP3Client.RetrieveHeader(Position_Mail, Message); // Retrieve only the header
POP3Client.Retrieve(Position_Mail, Message); // Retrieve the all mail
</pre>
<p>To retrieve a Raw Mail (the text without processing the mail in TIDMessage MIME parser) :</p>
<pre>
POP3Client.RetrieveRaw(Position_Mail, Down_MemStream);
</pre>
<p>And in conclusion, disconnection :</p>
<pre>
POP3Client.Disconnect; // Disconnection
</pre>
<p>Bye,</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.onkeysoft.com/2011/05/11/some-functions-et-properties-of-tidpop3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Peganza, Pascal Analyser 5 review</title>
		<link>http://blog.onkeysoft.com/2011/04/29/peganza-pascal-analyser-5-review/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=peganza-pascal-analyser-5-review</link>
		<comments>http://blog.onkeysoft.com/2011/04/29/peganza-pascal-analyser-5-review/#comments</comments>
		<pubDate>Fri, 29 Apr 2011 01:02:08 +0000</pubDate>
		<dc:creator>remixtech</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Reviews]]></category>
		<category><![CDATA[analysing]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[metrics]]></category>
		<category><![CDATA[pa]]></category>
		<category><![CDATA[pascal]]></category>
		<category><![CDATA[pascal analyser]]></category>
		<category><![CDATA[quality]]></category>
		<category><![CDATA[reports]]></category>
		<category><![CDATA[review]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://blog.onkeysoft.com/?p=39</guid>
		<description><![CDATA[I’m in really good move since several days, I have never written so much in a blog. So let’s go for a new post about a fabulous tool named Pascal Analyser… Is this tool in Rad Studio IDE? &#160; When you are developing software and you want to build a solid code like a rock. [...]]]></description>
			<content:encoded><![CDATA[<p>I’m in really good move since several days, I have never written so much in a blog. So let’s go for a new post about a fabulous tool named Pascal Analyser…</p>
<p><span id="more-39"></span></p>
<h2>Is this tool in Rad Studio IDE?</h2>
<p>&nbsp;</p>
<p>When you are developing software and you want to build a solid code like a rock. You need some tools to give you “Metrics”. Metrics give you answers to the following questions:</p>
<ul>
<li>How much files in your project? How much modules, lines, constants, class, variables?</li>
<li>Give you information about complexity of your code. How much Comments/Total lines in your code? What is the complexity of functions or procedures? About objects programming: What is the complexity of methods per class, the number of children and lot of other things?</li>
</ul>
<p>To introduce the tool, let’s see what Delphi IDE offer in the feature Matrix :</p>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/04/inDelphi.png"><img class="aligncenter size-large wp-image-40" title="Delphi Matrix" src="http://blog.onkeysoft.com/wp-content/uploads/2011/04/inDelphi-1024x214.png" alt="" width="1024" height="214" /></a></p>
<p>As you can see, this is not cool for the professional Delphi customers. Ok I think these functions are totally essential when you are developing software in a Team or when you are project manager. But this is also cool when you are independent developer and you want to keep a watch on the quality of the code. I hate Embarcadero for this; they are giving you ersatz of softwares, ersatz of Intraweb, AQTime, FinalBuilder… Why they aren’t reduce the price of Delphi and give a total liberty for their users to buy the tools they need… I hate this! Haaaaaa! So what is the solution for analyzing our code? Buying an extension of Delphi for 1300 €! Not sure, you could get really more in buying Peganza Analyser for only 120 € (see coupon at the end). But this is not the exact same software! Peganza Pascal Analyser is far more complete than Delphi IDE cause it don’t give only metrics it gives you a lot of other things. The goal is not the same, so now I will stop to compare original tool include in Delphi and Peganza Analyser.</p>
<h2>Review and tutorial of Peganza Pascal Analyser 5 :</h2>
<p>&nbsp;</p>
<p>To introduce and review this tool I will use the example of my software. After having setup my project and click <span style="text-decoration: underline;"><em>Analysis-&gt; Run!</em></span></p>
<h3><span style="text-decoration: underline;"><em><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/04/pascalanalyser.png"><img class="aligncenter size-full wp-image-42" title="Pascal Analyser 5" src="http://blog.onkeysoft.com/wp-content/uploads/2011/04/pascalanalyser.png" alt="" width="817" height="460" /></a></em></span></h3>
<h3 style="padding-left: 30px;"><span style="text-decoration: underline;"><em><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/04/pascalanalyser.png"></a></p>
<p></em></span></p>
<p>Reports – General</h3>
<p><em><strong>Status: </strong></em> This report presents important facts about the current analysis, e.g. selected compiler directives and search paths.</p>
<p><em><strong>Strong Warning: </strong></em>In this report you will see severe errors; they will often cause failures or erroneous results. (Property access in read/write methods or Ambiguous unit references). Sorry I haven’t this kind of problem in my software (It’s pretty good news), so no example. But sometimes it could happen if you are a bit dizzy !</p>
<p><strong><em>Warning reports: </em></strong>It will give you some advises to improve your code:</p>
<blockquote><p>Interfaced identifiers that are used, but not outside of unit (3, was 0):</p>
<p>TMailIMAPAccount = Class       Type, Interfaced        obj_mailaccount (98)</p></blockquote>
<p>If I double click on the line, it opens me Delphi IDE and I see directly what the problem is.</p>
<pre>

// -----------------------

// TMailAccount  IMAP4

// -----------------------

TMailIMAPAccount = class(TMailAccount)

private

public

procedure Assign(Source: TObject); override;

end;
</pre>
<p>I don&#8217;t use this Class, but I wrote it to be use in a near future. So it&#8217;s a false positive <img src='http://blog.onkeysoft.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ! When you have false positive you could delete them in adding
<pre> //PALOFF </pre>
<blockquote><p>Interfaced class identifiers that are public/published, but not used outside of unit (5, was 5):</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>Colonnes : Array (static)      Property                listview_tools\TList_Colonne (61)</p></blockquote>
<pre>

// Liste Colonne

TList_Colonne = class(TObjectList)

private

function GetColonne(Index: Integer): TColonne;

procedure SetColonne(Index: Integer; const Value: TColonne);

public

function NewOnlineColonne(TypeC: TColumnOnline; Position: Integer; Visible: Boolean; Size: Integer): TColonne_Online;

property Colonnes[index: integer]: TColonne read GetColonne write SetColonne; // PROBLEM HERE, the Class is public but not used...

end;
</pre>
<p>The problem is very simple to correct, the visibility of the property Colonnes is too high. The best way to correct it is to transfer it in private section.</p>
<blockquote><p>Variables that are set, but never referenced (9, was 9):</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>con_sasl_encours : tidsasl     ClassField              Thread_POP\Thread_POP3 (89)</p></blockquote>
<pre>

Thread_POP3 = class(tthread)

private

FProcessName: string;

con_sasl_encours:   tidsasl; // What is the problem...

// FThread origine

FThread_IM: TIMThread;

//...

protected

// ...

public

// ...

end;
</pre>
<p>If I delete the con_sasl_encours, the program can’t compile. The only time con_sasl_encours is used it is for :</p>
<pre>con_sasl_encours   := nil; </pre>
<p>So this object is totally useless, I can delete it. As you can see Peganza Analyser could help me to delete some objects totally useless. Maybe when I code it I had something in mind, but now, I dont know what it was&#8230; On my 22467 lines of code it is hard to find. Pascal Analyser could help you to clean your code.</p>
<p>Another one :</p>
<blockquote><p>Variables that are set, but never referenced (8, was 9):</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>Created : TDateTime            Var, Local              database_running\TDBB_RUN\Load_Main_Database (111)</p></blockquote>
<pre> function TDBB_RUN.Load_Main_Database(const Path_BDD: String; const Ident: String): boolean;

var

Created: TDateTime;

begin

Created    := sqlite3_column_double(Stmt, 1);

//....
</pre>
<p>Created is a double that is never used ! It is set but never used. So I could delete it (or not if it is planned to be used in the future but this is not probable, I can&#8217;t remember a variable that is declared two years ago lool) !</p>
<p>I will not give you an example for ALL the reports in the Warning reports. But we have seen that this tab could really help use to find useless code, or strange code. Sometimes we do some very strange thing like:</p>
<blockquote><p>for-loop variables read after loop (1, was 1):</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>I : Integer                    Var, Local              Thread_POP\Thread_POP3\Execute\delete_mails (991)</p></blockquote>
<pre>

try

for I := 0 to Liste_de_Mail.Count - 1 do

begin

// blablablblalaalal

end;

except

// Using of I

end;
</pre>
<p>This is an error from me, I was maybe drunk… The try except must be inside the loop and must be abort. So the code must be correct in :</p>
<pre>

for I := 0 to Liste_de_Mail.Count - 1 do

try

begin

// blablablblalaalal

except

Abort;

// Using of I

end;

end;
</pre>
<p>And the last one I would like to show you :</p>
<blockquote><p>Functions called as procedures (37, was 37):</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>configuration.sauvegarder_config at frm_principale (199)</p></blockquote>
<pre>

procedure Tfrm_main.FormDestroy(Sender: TObject);

begin

sauvegarder_config;

// ....

end;

// The function

function sauvegarder_config: boolean;

begin

// ....

end;
</pre>
<p>As you can see, Pascal Analyser gives us a good way to find which part of the software is missing. When I developed <em><strong>Sauvegarder_Config </strong></em>it was designed to give true if the function works properly and false if there is a problem. So it&#8217;s totally useless to code a function if I don&#8217;t use the result and use it like a Procedure. Here PA could really improves my software if I use it correctly, I&#8217;m forced to consider the result of the function.</p>
<p><em><strong>Optimization:</strong></em> By example the compiler of Delphi is optimized to work differently with constants and variables. So if you need speed and you are using variable for data which will not be modified it’s highly recommended to use constant instead. There are some other tricks to speed up your software. Pascal Analyser will help you to fix some leaks. Let’s see some examples:</p>
<blockquote><p>Missing &#8220;const&#8221; for unmodified string parameter (3, was 3):</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>BDD_Pass : String              ValParam                Thread_POP\Thread_POP3\Execute\Retrieve_Mails (594)</p></blockquote>
<pre> // Procedure pour télécharger des mails

procedure Retrieve_Mails(BDD_Path: String; BDD_Pass: String);

var </pre>
<p>Here it&#8217;s not a variable that I would communicate to the function but a constant. This value will not be modified.</p>
<blockquote><p>Array properties that are referenced/set within methods (1, was 0):</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>Accounts : Array (static)      Property                obj_mailaccount\TList_MailAccount (123)</p>
<p>Referenced/set (1):</p>
<p>Assign                         Proc, Method            obj_mailaccount\TList_MailAccount (121)</p></blockquote>
<p>For performance reasons it is faster to directly access the private array field.  However, if the Get- or Set-method performs side effects, it makes sense to  access the property.</p>
<pre>

// -----------------------

// TList_MailAccount

// -----------------------

TList_MailAccount = class(TObjectList)

private

function GetAccount(Index: integer): TMailAccount;

procedure SetAccount(Index: integer; const Value: TMailAccount);

public

procedure Assign(Source: TObject);

function NewPOPAccount: TMailPOPAccount;

property Accounts[index: integer]: TMailAccount read GetAccount write SetAccount;

end;

// Here Assign details

procedure TList_MailAccount.Assign(Source: TObject);

var //...

begin

//...

POPA.Assign(From.Accounts[I]); // THe problem is here

//...

end;
</pre>
<p>Must be change to</p>
<pre>

POPA.Assign(TMailPOPAccount(From.Items[I]));
</pre>
<p>And for the last example :</p>
<blockquote><p>Local subprograms with references to outer local variables (6, was 6):</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<p>GetIndex                       Proc, Local             frmpnl_show_offline_mail_\Tfrmpnl_show_offline_mail\offline_gridGetDisplText (368)</p></blockquote>
<pre>

procedure Tfrmpnl_show_offline_mail.offline_gridGetDisplText(Sender: TObject; ACol, ARow: Integer; var Value: string);

var

Mail_Offline: TMail_Offline;

Index:        Integer;

procedure GetIndex;

begin

Index        := strtoint(offline_grid.AllCells[1, ARow]);

Mail_Offline := TMail_Offline(Data_Liste.Objets[Index].Data);

end;
</pre>
<p>Using some local variables in inner routines cost a bit CPU cause the compiler need to do special stacks manipulation.</p>
<p>I change it in :</p>
<pre>

procedure Tfrmpnl_show_offline_mail.offline_gridGetDisplText(Sender: TObject; ACol, ARow: Integer; var Value: string);

var

Mail_Offline: TMail_Offline;

procedure GetIndex(Mail: TMail_Offline);

var Index:Integer;

begin

Index        := strtoint(offline_grid.AllCells[1, ARow]);

Mail := TMail_Offline(Data_Liste.Objets[Index].Data);

end;
</pre>
<p>I&#8217;m not an expert on this subject, I hope this is not totally stupid. If someone could tell me if the solution is correct&#8230;</p>
<p><em><strong>Memory:</strong></em></p>
<p class="MsoNormal"><span lang="EN-US">It allows you to manage all the objects you are creating in the memory; Pascal Analyser could make some test. Like telling you if you are making unprotected calls to free (Use Finally end) on local or non-local object. It will also count number of Create and Free and tell you if there is something strange… </span></p>
<p class="MsoNormal"><span lang="EN-US">It’s you work to interpret all the reports <img src='http://blog.onkeysoft.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  </span></p>
<p><em><strong>Code Reduction:</strong></em></p>
<p>This report pinpoints unnecessary code that could be deleted, resulting in a  smaller amount of code to maintain and search for errors.</p>
<p><em><strong>Convention Compliance/Inconsistent Case/Prefix:</strong></em></p>
<p class="MsoNormal"><span lang="EN-US">When you are coding in Delphi, there is some convention (not exhaustive):</span></p>
<ul>
<li><span lang="EN-US">Like user-define type names start with the letter T (TForm_Tool), pointer by P, Exception by E… </span></li>
<li><span lang="EN-US">Classfields must be declared in private section.</span></li>
<li><span lang="EN-US">Get, Set exposed by properties (write/read).</span></li>
<li><span lang="EN-US">Unsuitable names, numerals etc.</span></li>
<li><span lang="EN-US">Not the same name for different identifiers.</span></li>
<li><span lang="EN-US">Not too much long identifiers.</span></li>
</ul>
<ul></ul>
<p class="MsoNormal"><span lang="EN-US">Pascal Analyser gives you two other report one for inconsistent case (in fact when you are writing Buffer and bUFfer it is the same identifiers but it is most hard to read!). You could also detect which objects have not the right prefix.</span></p>
<h3 style="padding-left: 30px;">Reports – Metrics</h3>
<p>The next report is dedicated to Metrics. We have talk about this in the first part of this review/tutorial. The total metrics give you a rapid count of files, modules, lines and all kind of identifiers in Total/Local/Global/Interfaced/Unused. You could have this information for each module.</p>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/04/metrics.png"><img class="aligncenter size-large wp-image-71" title="Pascal Analyser complexity" src="http://blog.onkeysoft.com/wp-content/uploads/2011/04/metrics-1024x549.png" alt="" width="575" height="308" /></a></p>
<p><em>Extract from the manual:</em></p>
<ol>
<li><em>Start with a value of 1 for the normal flow through a subprogram. </em></li>
<li><em>Add 1 for each of these keywords: IF, WHILE, REPEAT, FOR, AND, OR, XOR, GOTO. Note that PAL always counts AND, OR, XOR, even if they are used as arithmetic operators in the actual code.</em></li>
<li><em>Add 1 for each case label in a CASE statement. When the CASE does not have an ELSE, add 1 more.</em></li>
</ol>
<p>DP (Decision Point equivalent to McCabe’s metric) is a way to quantify the hardness to understand a function. If the subprogram or module has a DP &gt; 10 it is a kind complex subprogram, with PA you could see easily what are the most hardcore to understand function. But sometimes you need to work with long function, which will give you a high DP. You can consider the result with DP/LOC (Lines of Code), if the DP/LOC is too high it is not good. After you need to see if the function is commented enough (if you have a high DP/LOC but a high Cmt(Comment)/LOC this is not a real problem, cause you are documenting enough your function (this is a subjective view).</p>
<p>There is a lot of other statistics with metrics. The metrics here are not a lot, but enough to understand your program if you are self-developer.</p>
<p>Let’s compare with Delphi Metrics  :</p>
<p><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/04/metricx-delphi.png"><img class="aligncenter size-medium wp-image-72" title="Delphi Metrics" src="http://blog.onkeysoft.com/wp-content/uploads/2011/04/metricx-delphi-300x228.png" alt="" width="300" height="228" /></a></p>
<p>This is really more complex and complete, I think this is not totally useful when your are independent developer. But if you are directing a project you will need more information, and this tool is great. But like every tool there are some limitations, by example in this particular situation Delphi Audits tell me that this code is never execute ! But this is an error, this code is always performed ! Sometimes just rewriting differently the code correct the problem.</p>
<pre>

Synchronize( procedure begin

// ...

end);
</pre>
<p>Personally I prefer Pascal Analyser. It&#8217;s more easy to find problem and to optimize my code. Pascal Analyser gives you also Object Oriented Metrics :</p>
<ul>
<li>Weighted Methods per Class (WMC)</li>
<li>Depth of Inheritance Tree (DIT)</li>
<li>Number of children (NOC)</li>
<li>Coupling between Object Classes (CBO)</li>
<li>Response for a Class (RFC)</li>
<li>Loack of Cohesion in Methods (LCOM)</li>
</ul>
<p>With all these metrics, without directly watching the code, you could know if your code is great, just ok or really bad ! Just test the software and open the manual to learn more about these metrics.</p>
<h3 style="padding-left: 30px;">And a lot of other tools !</h3>
<p>Pascal Analyser comes with a lot of other tools. It could give you some infos about Modules, Identifiers, Duplicate Identifiers name (yes it&#8217;s not good to give the same name to different variables, most hard to read), similarity. This software could also list :</p>
<ul>
<li>The Subprogram Index</li>
<li>Bindings</li>
<li>Third-party dependencies</li>
<li>Most called subprograms</li>
<li>Call Tree/ Reverse Call Tree/ Call Index</li>
<li>All the exceptions</li>
<li>All the todos</li>
<li>All the directives</li>
<li>All the conditional Symbols</li>
<li>The Brief Cross-reference</li>
<li>Interfaced identifiers that are used outside their units</li>
<li>And lof of other things !</li>
</ul>
<p>Just before conclusion, I will give a last function that I like a lot on this Analyser. In pascal you need to tell the compiler which files you want to include into your program with the <strong><em>uses</em></strong>, but sometimes you have some useless units in <strong><em>uses</em></strong> and it takes time to compiler to test if it useful or not. Here PA tells me directly which units I could delete easily. Example :</p>
<blockquote><p><span style="text-decoration: underline;"><em>Program ClientMail uses:</em></span></p>
<p>Used units:</p>
<p>sysutils in implementation</p>
<p>==&gt; ExceptionLog unnecessary</p>
<p>Forms in implementation</p>
<p>dateutils in implementation</p>
<p>frm_principale in implementation</p>
<p>==&gt; memstreamini unnecessary</p>
<p>==&gt; database unnecessary (has initialization)</p>
<p>==&gt; ressourcestrings unnecessary (used by unit with init)</p>
<p>==&gt; imail_type unnecessary</p>
<p>==&gt; obj_mailaccount unnecessary</p>
<p>==&gt; database_online unnecessary</p>
<p>==&gt; chemins unnecessary</p>
<p>==&gt; tools_strings unnecessary</p>
<p>==&gt; constantes unnecessary</p>
<p>==&gt; msgbox_tools unnecessary</p>
<p>==&gt; database_cfg unnecessary</p>
<p>==&gt; listview_tools unnecessary</p>
<p>==&gt; configuration unnecessary</p>
<p>frm_configuration in implementation</p>
<p>==&gt; Thread_Manager unnecessary</p>
<p>==&gt; database_mails unnecessary</p>
<p>==&gt; database_maj unnecessary</p>
<p>==&gt; frm_update_database unnecessary</p>
<p>==&gt; load_skin unnecessary</p>
<p>==&gt; combobox_tools unnecessary</p>
<p>==&gt; database_running unnecessary</p>
<p>==&gt; database_log unnecessary</p>
<p>==&gt; obj_standard unnecessary</p>
<p>==&gt; Thread_POP unnecessary</p>
<p>==&gt; Interface_manager unnecessary</p>
<p>==&gt; Treeview_tools unnecessary</p>
<p>==&gt; menu_tools unnecessary</p>
<p>==&gt; affichage unnecessary</p>
<p>==&gt; frmpnl_log_ unnecessary</p>
<p>==&gt; frmpnl_show_online_mail_ unnecessary</p>
<p>==&gt; frmpnl_threads_ unnecessary</p>
<p>==&gt; frmpnl_show_offline_mail_ unnecessary</p>
<p>==&gt; crypt_decrypt unnecessary</p>
<p>==&gt; frm_status unnecessary</p>
<p>==&gt; reinit unnecessary</p>
<p>frm_splashscreen in implementation</p>
<p>==&gt; frm_lecture_mail unnecessary</p></blockquote>
<h3 style="padding-left: 30px;">Conclusion !</h3>
<p>In conclusion this is a really valuable tool, you will save a lot of precious time if you maintain a high quality and reliable code. Maybe it will takes some hours to decrypt all the tools and use it correctly in your project (and correct some strange things), but after some times it will be automatic and you will do this naturally. You will write better code with less effort ! For me Pascal Analyser is a must have if you just have the professional version of Delphi.</p>
<p>I have negotiated a reduction just for you, use the coupon code &#8220;<span style="font-size: 11pt; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;;">PALBLOG&#8221; when ordering and you will get 10% of reduction.</span></p>
<p style="text-align: center;"><span style="font-size: 11pt; font-family: &quot;Calibri&quot;,&quot;sans-serif&quot;;"> <a href="http://peganza.com/">Click here to go to Peganza Website</a></p>
<p></span></p>
<p>&nbsp;</p>
<p><em><strong> </strong></em></p>
<div id="_mcePaste" class="mcePaste" style="position: absolute; left: -10000px; top: 3261px; width: 1px; height: 1px; overflow: hidden;">
<h3 style="padding-left: 30px;">Reports – General</h3>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.onkeysoft.com/2011/04/29/peganza-pascal-analyser-5-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Is Delphi dead ? (And why it&#8217;s not !)</title>
		<link>http://blog.onkeysoft.com/2011/04/22/if-delphi-is-dead-and-why-its-not/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=if-delphi-is-dead-and-why-its-not</link>
		<comments>http://blog.onkeysoft.com/2011/04/22/if-delphi-is-dead-and-why-its-not/#comments</comments>
		<pubDate>Fri, 22 Apr 2011 15:49:05 +0000</pubDate>
		<dc:creator>remixtech</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[dead]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[fruityloops]]></category>
		<category><![CDATA[installaware]]></category>
		<category><![CDATA[kaspersky]]></category>
		<category><![CDATA[mediamonkey]]></category>

		<guid isPermaLink="false">http://blog.onkeysoft.com/?p=75</guid>
		<description><![CDATA[Then &#160; &#160; &#160; &#160; &#160; &#160; are compiled by a ghost !]]></description>
			<content:encoded><![CDATA[<h1 style="text-align: center;">
<p>Then</h1>
<p>&nbsp;</p>
<div id="attachment_76" class="wp-caption aligncenter" style="width: 240px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/04/k.jpg"><img class="size-medium wp-image-76" title="Kaspersky" src="http://blog.onkeysoft.com/wp-content/uploads/2011/04/k-230x300.jpg" alt="" width="230" height="300" /></a><p class="wp-caption-text">Kaspersky protection softwares</p></div>
<p><span id="more-75"></span><br />
&nbsp;</p>
<div id="attachment_77" class="wp-caption aligncenter" style="width: 277px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/04/s1301809141737.jpeg"><img class="size-medium wp-image-77" title="Rad Studio XE" src="http://blog.onkeysoft.com/wp-content/uploads/2011/04/s1301809141737-267x300.jpg" alt="" width="267" height="300" /></a></dt>
<dt> <p class="wp-caption-text">Delphi and C++ Builder IDE</p></div>
<p>&nbsp;</p>
<div id="attachment_78" class="wp-caption aligncenter" style="width: 250px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/04/fruity-loops-9.jpg"><img class="size-full wp-image-78" title="fruity-loops-9" src="http://blog.onkeysoft.com/wp-content/uploads/2011/04/fruity-loops-9.jpg" alt="" width="240" height="233" /></a><p class="wp-caption-text">Fruity Loops audio producing tools</p></div>
<p>&nbsp;</p>
<div id="attachment_79" class="wp-caption aligncenter" style="width: 238px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/04/gI_InstallAwareStudioAdmin.png.jpg"><img class="size-full wp-image-79" title="gI_InstallAwareStudioAdmin.png" src="http://blog.onkeysoft.com/wp-content/uploads/2011/04/gI_InstallAwareStudioAdmin.png.jpg" alt="" width="228" height="250" /></a><p class="wp-caption-text">The great installer InstallAware</p></div>
<p>&nbsp;</p>
<div id="attachment_80" class="wp-caption aligncenter" style="width: 271px"><a href="http://blog.onkeysoft.com/wp-content/uploads/2011/04/mediamonkey_6523.jpg"><img class="size-medium wp-image-80" title="mediamonkey_6523" src="http://blog.onkeysoft.com/wp-content/uploads/2011/04/mediamonkey_6523-261x300.jpg" alt="" width="261" height="300" /></a><p class="wp-caption-text">Audio library manager MediaMonkey</p></div>
<p>&nbsp;</p>
<h1 style="text-align: center;">are compiled by a ghost !</p>
</h1>
]]></content:encoded>
			<wfw:commentRss>http://blog.onkeysoft.com/2011/04/22/if-delphi-is-dead-and-why-its-not/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
