<?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>VCL Developer &#187; Tips &amp; Tricks</title>
	<atom:link href="http://vcldeveloper.com/category/tips-tricks/feed/" rel="self" type="application/rss+xml" />
	<link>http://vcldeveloper.com</link>
	<description>Ali Keshavarz&#039;s Website</description>
	<lastBuildDate>Fri, 04 Nov 2011 23:40:16 +0000</lastBuildDate>
	<language>fa</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Boolean and BOOL</title>
		<link>http://vcldeveloper.com/tips-tricks/boolean-and-bool/</link>
		<comments>http://vcldeveloper.com/tips-tricks/boolean-and-bool/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 23:40:16 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Boolean]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=530</guid>
		<description><![CDATA[It took me an hour to fix an Access Violation in one of my source codes tonight. The AV caught my eyes when I thought everything was done correctly, and it is ready for committing changes and hit the bed! It was a vague AV, giving me just a few NT OS functions in call [...]]]></description>
			<content:encoded><![CDATA[<p>It took me an hour to fix an Access Violation in one of my source codes tonight. The AV caught my eyes when I thought everything was done correctly, and it is ready for committing changes and hit the bed!</p>
<p>It was a vague AV, giving me just a few NT OS functions in call stack trace, and stopping on any line containing Result (as the return value for a property getter). I reviewed the code several times, everything seemed OK, and I had only changed tens of lines of code, so I was really confused where the hell this AV came from; I mean, I knew which property getter method was causing the error, and the method was not lengthy or complicated, but I had no clue how come it was causing such an AV  &gt;-(</p>
<p>Eventually while I was reviewing the changed codes again and again, I noticed something; there was a Windows API call which required a PBOOL parameter, and I had called it twice in the function code. One call was written a while ago, and the other was written tonight. The problem was, for the second call I had defined the parameter as Boolean rather than defining it as BOOL (passing its address using @ operator). That&#8217;s a shame!</p>
<p>So here&#8217;s a personal note for myself: Do not code at 2 AM, specially when you are kinda sleepy. If you did, make sure your eyes can distinguish between BOOL, and Boolean <img src='http://vcldeveloper.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/tips-tricks/boolean-and-bool/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Enumerating Windows services</title>
		<link>http://vcldeveloper.com/tips-tricks/enumerating-windows-services/</link>
		<comments>http://vcldeveloper.com/tips-tricks/enumerating-windows-services/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 14:30:28 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi XE2]]></category>
		<category><![CDATA[Services]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[دلفی]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=504</guid>
		<description><![CDATA[A while ago, I had to enumerate all Windows services for a project. I was browsing the source code today, and thought maybe it would be a good idea to talk about this matter in a blog post, and publish a sample source code to achieve this. The easiest way to enumerate Windows services is [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">A while ago, I had to enumerate all Windows services for a project. I was browsing the source code today, and thought maybe it would be a good idea to talk about this matter in a blog post, and publish a sample source code to achieve this.</p>
<p style="text-align: justify;">The easiest way to enumerate Windows services is using WMI. Of course using WMI requires some basic knowledge of MS COM technology which is tricky, but thanks to the great tool. <a href="http://code.google.com/p/delphi-wmi-class-generator/" target="_blank">Delphi WMI Class Generator</a> by <a href="http://www.theroadtodelphi.wordpress.com/" target="_blank">Rodrigo Ruz</a>, you can have a ready Delphi class for obtaining information about installed services on a Windows machine without even writing a single line of code. All you have to know is that WMI class for Windows services is Win32_Service under root\CIMV2 namespace. Delphi WMI Class Generator will generate a unit named uWin32_Service.pas which contains a class named TWin32_Service. This class returns info about a single service for you. If you need to enumerate all installed services, you need to write a couple of codes to call its GetCollectionCount to retrieve number of available services, and SetCollectionIndex to set current item index for the class. Here is a sample code to retrieve names of all installed services on the local machine using TWin32_Service class:</p>
<pre class="brush: delphi; title: ; notranslate">
var
  i: Integer;
begin
  with TWin32_Service.Create do
  try
    for i := 0 to GetCollectionCount - 1 do
    begin
      Writeln(DisplayName);
      SetCollectionIndex(i);
    end;
  finally
    Free;
  end;
end;
</pre>
<p style="text-align: justify;">However, WMI is slow, and it relays on WMI service. If you need a faster way to enumerate Windows services, or if for whatever reason WMI service is disabled or not working on your target machine; then you have to relay on Windows API. Using Windows API for this purpose is not as easy as using the automatically generated TWin32_Service class. I am not aware of a single Windows API function that can enumerate Windows services for you and give you all the detailed information which WMI returns for each service. You have to call roughly a dozen of API functions to enumerate Windows services and retrieve some nice information for each service.</p>
<p style="text-align: justify;">First you need to open a handle to service manager on the target machine by calling <a href="http://msdn.microsoft.com/en-us/library/ms684323%28v=vs.85%29.aspx" target="_blank">OpenSCManager</a> function, then you should call <a href="http://msdn.microsoft.com/en-us/library/ms682640%28VS.85%29.aspx" target="_blank">EnumServicesStatusEx</a> function to enumerate available services, and retrieve their names and status. If you just need service names and status, you are done, but if you need to retrieve description and configuration for each service too, then you should open a handle for each service using <a href="http://msdn.microsoft.com/en-us/library/ms684330%28v=vs.85%29.aspx" target="_blank">OpenService </a>function by giving it service name which you obtain through EnumServicesStatusEx call , and then call <a href="http://msdn.microsoft.com/en-us/library/ms684932%28v=vs.85%29.aspx" target="_blank">QueryServiceConfig</a> and <a href="http://msdn.microsoft.com/en-us/library/ms684935%28v=vs.85%29.aspx" target="_blank">QueryServiceConfig2</a> functions to get the required configurations. At the end you should make sure you free all the allocated buffers, and close all handles. Delphi installation does not provide header translation for some of these API functions (particularly EnumServicesStatusEx and QueryServiceConfig2), but they are translated and available for Delphi by well-known Project JEDI, and their JEDI Windows API Headers which contain the majority of Windows headers. If you are a Delphi developer and have not heard about them yet (That would be weird!!), you can download the package from <a title="JEDI Windows API Header" href="http://blog.delphi-jedi.net/jedi-api-headers/" target="_blank">this link</a>.</p>
<p style="text-align: justify;">Anyways, in the source code below, I wrapped all of those API calls into a class named TAkServices. This class holds an internal list containing information for each Windows service installed on a given machine. I tested it on both Delphi 2010 (Win32) and Delphi XE2 (Win64):</p>
<p style="text-align: justify;"><span id="more-504"></span></p>
<pre class="brush: delphi; title: ; notranslate">
{*******************************************************************************
/// &lt;author&gt; Ali Keshavarz (vcldeveloper@gmail.com) &lt;/author&gt;
/// &lt;date&gt; 09/13/2011 &lt;/date&gt;
/// &lt;license&gt;
///  This work is licensed under the Creative Commons Attribution 3.0 Unported
///  License. To view a copy of this license, visit
///  http://creativecommons.org/licenses/by/3.0/
///  or send a letter to Creative Commons, 171 Second Street, Suite 300,
///  San Francisco, California, 94105, USA.
/// &lt;/license&gt;
*******************************************************************************}

unit uAkServices;

interface

uses
 Generics.Collections;

type
 /// Service status values; these items are defined in Windows SDK. For more
 /// info refer to MSDN.
 TAkServiceState = (SERVICE_STOPPED          = $۰۰۰۰۰۰۰۱,
 SERVICE_START_PENDING    = $۰۰۰۰۰۰۰۲,
 SERVICE_STOP_PENDING     = $۰۰۰۰۰۰۰۳,
 SERVICE_RUNNING          = $۰۰۰۰۰۰۰۴,
 SERVICE_CONTINUE_PENDING = $00000005,
 SERVICE_PAUSE_PENDING    = $۰۰۰۰۰۰۰۶,
 SERVICE_PAUSED           = $۰۰۰۰۰۰۰۷ );

 /// Service startup mode values; these items are defined in Windows SDK. For
 /// more info refer to MSDN.
 TAkServiceStartMode = (SERVICE_BOOT_START,
 SERVICE_SYSTEM_START,
 SERVICE_AUTO_START,
 SERVICE_DEMAND_START,
 SERVICE_DISABLED );

 /// &lt;summary&gt;
 /// Service information structure. This structure is used by TAkServiceList
 /// class to save info for each individual service.
 /// &lt;/summary&gt;
 TAkServiceInfo = record
 public
 /// A path to service executable file.
 BinaryPath : string;
 /// Current service state.
 CurrentState : TAkServiceState;

 Description : string;
 /// User-friendly name of service
 DisplayName : string;
 /// Service flags. It can be either zero or SERVICE_RUNS_IN_SYSTEM_PROCESS.
 Flags : Integer;
 /// Actual name of service which is also used as service key name in Registry.
 Name : string;
 /// Process identifier for a running service. If the service is not running
 /// or it is running in System process, then ProcessID will be zero.
 ProcessID : Cardinal;
 /// Startup mode of service.
 StartMode : TAkServiceStartMode;
 /// Username by which service logged into system.
 StartName : string;
 end;

 /// Holds a list of TAkServiceInfo reccords as the list of Windows services.
 TAkServiceList = TList&lt;TAkServiceInfo&gt;;

 TAkServiceInfoEnumerator = TEnumerator&lt;TAkServiceInfo&gt;;

 /// &lt;summary&gt;
 /// Provides a list of installed Windows services on a given machine.
 /// &lt;/summary&gt;
 TAkServices = class
 private
 FLastUpdateTime : TDateTime;
 FList : TAkServiceList;
 FMachineName : string;
 function GetCount: Integer;
 function GetItem(Index: Integer): TAkServiceInfo;
 procedure GetServiceConfig(hSCManager: Cardinal; var Service: TAkServiceInfo);
 procedure SetMachineName(const Value: string);
 protected
 procedure InitializeList; virtual;
 procedure InternalRefresh; virtual;
 public
 /// &lt;summary&gt;
 /// Constructor for TAkServices.
 /// &lt;/summary&gt;
 /// &lt;param name=&quot;AMachineName&quot;&gt;
 ///  (in) Name of the machine which its services should be listed. Default = ''
 /// &lt;/param&gt;
 /// &lt;param name=&quot;.&quot;&gt;&lt;/param&gt;
 constructor Create(const AMachineName: string = '');
 destructor Destroy; override;
 function GetEnumerator: TAkServiceInfoEnumerator;
 /// &lt;summary&gt; Updates list of services. &lt;/summary&gt;
 procedure Refresh;
 /// &lt;summary&gt;
 /// Indicates number of services. If the list is not updated yet, it will be
 /// updated first.
 /// &lt;/summary&gt;
 property Count: Integer read GetCount;
 /// &lt;summary&gt;
 /// Returns item at the Index position of the list of services.
 /// If the list is not updated yet, it will be updated first.
 /// &lt;/summary&gt;
 property Item[Index: Integer]: TAkServiceInfo read GetItem; default;
 /// &lt;summary&gt;
 /// Indicates last update time for the list. It will be updated each time
 /// Refresh method is called.
 /// &lt;/summary&gt;
 property LastUpdateTime: TDateTime read FLastUpdateTime;
 /// &lt;summary&gt;Name of the machine which its services should be listed. &lt;/summary&gt;
 property MachineName: string read FMachineName write SetMachineName;
 end;

implementation

uses
 SysUtils,
 Windows,
 JwaWinNT,
 JwaWinType,
 JwaWinSvc,
 JwaWinError;

{ TAkServices }

constructor TAkServices.Create(const AMachineName: string);
begin
 inherited Create;
 FMachineName := AMachineName;
end;

destructor TAkServices.Destroy;
begin
 System.TMonitor.Enter(Self);
 try
 FList.Free;
 FList := nil;
 finally
 System.TMonitor.Exit(Self);
 end;

 inherited;
end;

function TAkServices.GetCount: Integer;
begin
 InitializeList;
 Result := FList.Count;
end;

function TAkServices.GetEnumerator: TAkServiceInfoEnumerator;
begin
 InitializeList;
 Result := FList.GetEnumerator;
end;

function TAkServices.GetItem(Index: Integer): TAkServiceInfo;
begin
 InitializeList;
 Result := FList[Index];
end;

procedure TAkServices.InitializeList;
begin
 if not Assigned(FList) then
 begin
 System.TMonitor.Enter(Self);
 try
 FList := TAkServiceList.Create;
 InternalRefresh;
 finally
 System.TMonitor.Exit(Self);
 end;
 end;
end;

procedure TAkServices.GetServiceConfig(hSCManager: Cardinal; var Service: TAkServiceInfo);
var
 dwBufNeeded: Cardinal;
 dwBufSize: Cardinal;
 hService : Cardinal;

 /// &lt;summary&gt;
 /// Retrieves service binary path, start mode, and user name.
 /// &lt;/summary&gt;
 procedure GetRequiredConfig(var Service: TAkServiceInfo);
 var
 lpServiceConfig : LPQUERY_SERVICE_CONFIG;
 begin
 dwBufSize := 0;
 dwBufNeeded := 0;
 /// Retrieve required buffer size.
 QueryServiceConfig(hService, nil, dwBufSize, dwBufNeeded);
 if GetLastError &lt;&gt; ERROR_INSUFFICIENT_BUFFER then
 RaiseLastOSError;

 /// Alocate enough buffer size.
 dwBufSize := dwBufNeeded;
 lpServiceConfig := AllocMem(dwBufSize);
 try
 /// Get service configuration
 if not QueryServiceConfig(hService, lpServiceConfig, dwBufSize, dwBufNeeded) then
 RaiseLastOSError;

 /// Save configuration data in the record.
 Service.BinaryPath := lpServiceConfig.lpBinaryPathName;
 Service.StartMode := TAkServiceStartMode(lpServiceConfig.dwStartType);
 Service.StartName := lpServiceConfig.lpServiceStartName;
 finally
 FreeMem(lpServiceConfig);
 end;
 end;

 /// &lt;summary&gt;
 /// Retrieves service description.
 /// &lt;/summary&gt;
 procedure GetOptionalConfig(var Service: TAkServiceInfo);
 var
 lpServiceDescBuff : LPSERVICE_DESCRIPTION;
 begin
 dwBufSize := 0;
 dwBufNeeded := 0;
 /// Retrieve required buffer size.
 QueryServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, nil, dwBufSize, dwBufNeeded);
 if GetLastError &lt;&gt; ERROR_INSUFFICIENT_BUFFER then
 RaiseLastOSError;

 /// Alocate enough buffer size.
 dwBufSize := dwBufNeeded;
 lpServiceDescBuff := AllocMem(dwBufSize);
 try
 /// Retrieve service description
 if not QueryServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION,
                            PByte(lpServiceDescBuff), dwBufSize, dwBufNeeded) then
   RaiseLastOSError;
  /// Save service description in the record.
  if Assigned(lpServiceDescBuff.lpDescription) then
   SetString(Service.Description,
             lpServiceDescBuff.lpDescription,
             StrLen(lpServiceDescBuff.lpDescription));
   finally
     FreeMem(lpServiceDescBuff);
   end;
 end;

begin
  Assert(hSCManager &gt; 0, 'Service manager is not initialized.');

  /// Open a service handle to be used by QueryServiceConfig() and QueryServiceConfig2() functions.
  hService := OpenService(hSCManager,PChar(Service.Name),SERVICE_QUERY_CONFIG);
  if hService = 0 then
    RaiseLastOSError;
  try
    GetRequiredConfig(Service);
    GetOptionalConfig(Service);
  finally
    CloseServiceHandle(hService);
  end;
end;

procedure TAkServices.InternalRefresh;
var
  dwBufNeeded: Cardinal;
  dwBufSize: Cardinal;
  dwNumOfServices: ULONG;
  hSCM: SC_HANDLE;
  lpResumeHandle: Cardinal;
  NewItem : TAkServiceInfo;
  pBuf: PBYTE;
  pInfo: LPENUM_SERVICE_STATUS_PROCESS;
  i: Integer;
begin
  Assert(Assigned(FList),'Internal list is not assigned yet!');

  System.TMonitor.Enter(FList);
  try
   dwBufSize := 0;
   dwBufNeeded := 0;
   dwNumOfServices := 0;
   lpResumeHandle := 0;
   FList.Clear;

   /// We need an open service manager handle to be able to enumerate services.
   hSCM := OpenSCManager(PChar(FMachineName), nil,
   SC_MANAGER_ENUMERATE_SERVICE or SC_MANAGER_CONNECT);
   if (hSCM = 0) then
     RaiseLastOSError;

   try
     /// First check how much buffer is needed by passing dwBufSize as zero,
     /// and pBuf as nil.
     EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
                          SERVICE_STATE_ALL, nil, dwBufSize, dwBufNeeded,
                          dwNumOfServices, lpResumeHandle, nil);
     if (dwBufNeeded &lt; 1) then
       RaiseLastOSError;

     /// Alocate enough space for the buffer.
     dwBufSize := dwBufNeeded;
     pBuf := AllocMem(dwBufSize);
     try
       /// Retrieve services list
       if not EnumServicesStatusEx(hSCM, SC_ENUM_PROCESS_INFO, SERVICE_WIN32,
                                   SERVICE_STATE_ALL, pBuf, dwBufSize, dwBufNeeded,
                                   dwNumOfServices, lpResumeHandle, nil) then
         RaiseLastOSError;

       /// Type casting pBuf to LPENUM_SERVICE_STATUS_PROCESS record is necessary
       ///  so that we can access each service info in the buffer as a record.
       pInfo := LPENUM_SERVICE_STATUS_PROCESS(pBuf);
       /// Write services list
       for i := 0 to dwNumOfServices-1 do
       begin
         NewItem.Name := pInfo.lpServiceName;
         NewItem.DisplayName := pInfo.lpDisplayName;
         NewItem.Flags := pInfo.ServiceStatusProcess.dwServiceFlags;
         NewItem.ProcessID := pInfo.ServiceStatusProcess.dwProcessId;
         NewItem.CurrentState := TAkServiceState(pInfo.ServiceStatusProcess.dwCurrentState);
         GetServiceConfig(hSCM, NewItem);
         FList.Add(NewItem);

         /// Go to next record in the buffer. Compiler will increment pInfo pointer
         ///  according to size LPENUM_SERVICE_STATUS_PROCESS record.
         Inc(pInfo);
       end;
       FLastUpdateTime := Now;
    finally
       FreeMem(pBuf);
    end;
  finally
    CloseServiceHandle(hSCM);
  end;
  finally
     System.TMonitor.Exit(FList);
  end;
end;

procedure TAkServices.Refresh;
begin
 /// If FList is not created yet, InitializeList will create it and calls InternalRefresh
 /// automatically, but if the list is already created, just calling InternalRefresh
 /// is enough.
 if not Assigned(FList) then
 InitializeList
 else
 InternalRefresh;
end;

procedure TAkServices.SetMachineName(const Value: string);
begin
 if not SameText(FMachineName, Value) then
 begin
    FMachineName := Value;
    Refresh;
  end;
end;

end.
</pre>
<p style="text-align: justify;">Here is also a demo Delphi application using TAkServices class to enumerate Windows services on the local machine, and show them in a ListView control. Download link for the source files (including uAkServices.pas and all required JEDI API header translations) is available at the end of this article:</p>
<div id="attachment_507" class="wp-caption aligncenter" style="width: 310px"><a href="/wp-content/uploads/2011/09/WinServicesDemo.png"><img class="size-medium wp-image-507" title="WinServicesDemo" src="http://vcldeveloper.com/wp-content/uploads/2011/09/WinServicesDemo-300x218.png" alt="" width="300" height="218" /></a><p class="wp-caption-text">Demo application in action; enumerating Windows services using Windows API</p></div>
<h3>Download:</h3>
<p class="download"><a href="/downloads/Enum_Win_Services_Demo.zip">Source code plus the demo app</a></p>
<p><strong>P.S.</strong> Oops, it seems my code highlighter is not keen on indentation in longer source codes. If you see the code without proper indentation, you can use <a href="http://pastebin.com/777VN9RU">this pastebin link</a> to see the source formatted properly, or download the source file. I&#8217;m sorry for the inconvenience.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/tips-tricks/enumerating-windows-services/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Implementing Singleton pattern in Delphi</title>
		<link>http://vcldeveloper.com/tips-tricks/implementing-singleton-pattern-in-delphi/</link>
		<comments>http://vcldeveloper.com/tips-tricks/implementing-singleton-pattern-in-delphi/#comments</comments>
		<pubDate>Fri, 03 Jun 2011 21:49:23 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Singleton]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=421</guid>
		<description><![CDATA[There are several ways to implement Singleton pattern in Delphi. Most of the publicly available source codes that I saw use old techniques to keep backward compatibility with older versions of Delphi (e.g. Delphi 7). In such techniques usually a global variable or a writable const is used to keep a reference to the singleton [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">There are several ways to implement <a title="Singleton pattern" href="http://en.wikipedia.org/wiki/Singleton_pattern" target="_blank">Singleton pattern</a> in Delphi. Most of the publicly available source codes that I saw use old techniques to keep backward compatibility with older versions of Delphi (e.g. Delphi 7). In such techniques usually a global variable or a writable const is used to keep a reference to the singleton instance; because in those old versions of Delphi, there were no way to define a class variable.</p>
<p style="text-align: justify;">Also many of them try to hide the constructor under protected visibility, assuming it would prohibit users from instantiating the class, and forcing them to use the defined method for accessing the singleton instance. I can’t realize what was the rationale behind hiding the constructor, because all Delphi classes are inherited from <a title="TObject" href="http://docwiki.embarcadero.com/VCL/en/System.TObject" target="_blank">TObject</a>, and it already has a default Create constructor defined as public, so a user can always call that Create method to instantiate a new object and getting around your singleton implementation.</p>
<p style="text-align: justify;">A few months ago when I was looking for a singleton implementation in Delphi which does not use old writable consts or global variables; I found <a title="Implementing the Singleton Design Pattern in Delphi without Global Variables" href="http://www.yanniel.info/2010/10/singleton-pattern-delphi.html" target="_blank">a blog post</a> by Yanniel Alvarez Alfonso, implementing Singleton pattern using class variables, but there was still the problem of hiding constructors, so I wrote a comment there, telling him that hiding the constructor is not a good idea; and instead of that, he should override TObject.NewInstance method. He appreciated the note, and changed his code to reflect that.</p>
<p style="text-align: justify;">Today I needed to implement Singleton again, but I was too lazy to write it, so I searched for it in my source codes, but didn’t find my own code! I tried my favorite modeling tool; <a title="ModelMaker" href="http://www.modelmakertools.com/modelmaker/index.html" target="_blank">ModelMaker</a>, but their Singleton pattern implementation was the same old-style writable const technique (even in the new ModelMaker 11). Eventually I decided to write it again, and save it as a code template in ModelMaker to use it later when I need it and I am not in the mood of writing it again and again <img class="wlEmoticon wlEmoticon-smile" style="border-style: none;" src="http://vcldeveloper.com/wp-content/uploads/2011/06/wlEmoticon-smile.png" alt="Smile" /></p>
<p><span id="more-421"></span></p>
<h2>Singleton Implementation</h2>
<p>Here is my implementation of a singleton class:</p>
<pre class="brush: delphi; title: ; notranslate">
unit uSingleton;

interface

uses
  Windows;

type
  TSingleton = class sealed(TObject)
  strict private
    class var
      _Instance: TSingleton;
    /// This lock assures us that our singleton instance will be
    /// created only once in a multi-threaded environment.
    CreationLock: RTL_CRITICAL_SECTION;
    class function GetInstance: TSingleton; static; inline;
  private
    procedure InitInstanceFields;
  public
    class constructor ClassCreate;
    constructor Create;
    class destructor ClassDestroy;
    destructor Destroy; override;
    class function NewInstance: TObject; override; final;
    class property Instance: TSingleton read GetInstance;
  end;

implementation

{ TSingleton }
class constructor TSingleton.ClassCreate;
begin
  InitializeCriticalSection(CreationLock);
end;

constructor TSingleton.Create;
begin
  inherited;

end;

class destructor TSingleton.ClassDestroy;
begin
  /// If singleton instance is not destroyed by user, destroy it automatically.
  if Assigned(_Instance) then
  begin
    _Instance.Free;
    _Instance := nil;
  end;
  DeleteCriticalSection(CreationLock);
end;

destructor TSingleton.Destroy;
begin
  /// Make the singleton instance nil before destroying it.
  /// This way, next time Instance property is accessed, a
  /// new instance will be created.
  _Instance := nil;
  inherited;
end;

class function TSingleton.GetInstance: TSingleton;
begin
  Result := Self.Create;
end;

procedure TSingleton.InitInstanceFields;
begin
  { TODO : Initialize your instance here}
end;

class function TSingleton.NewInstance: TObject;
begin
  /// New instance is called when a new instance is being created.
  /// We first check if the singleton instance is assigned, if
  /// it is not assigned yet, we let NewInstance assign a new
  /// instance; Otherwise, we make it to return our already assigned
  /// singleton object.
  /// This way we will always have a single instance of the class
  /// even if user calls Create() method of our class.
  if not Assigned(_Instance) then
  begin
    EnterCriticalSection(CreationLock);
    try
      _Instance := inherited NewInstance as Self;
      _Instance.InitInstanceFields;
    finally
      LeaveCriticalSection(CreationLock);
    end;
  end;

  Result := _Instance;
end;

end.
</pre>
<p style="text-align: justify;">The important piece of this code is overriding <a title="TObject.NewInstance" href="http://docwiki.embarcadero.com/VCL/XE/en/System.TObject.NewInstance" target="_blank">TObject.NewInstance</a> method. TObject.NewInstance is defined as a virtual class function. It is responsible for allocating memory for an instance of a class and returning a pointer to the allocated memory. NewInstance is called by all constructors automatically. So, if you override NewInstance method, you can control how instances of a class are allocated. What we do here is to make sure NewInstance allocates memory for our class instances only once, and if an instance is already created, it returns a pointer to that instance rather than allocating new memory. This way, we do not need to hide our constructors, because even if you call constructor of your class, it relays on NewInstance for its memory allocation, and will always return the same singleton instance.</p>
<blockquote>
<p style="padding-left: 30px; text-align: justify;"><span style="text-decoration: underline;"><strong>WARNING</strong></span>: Take note that if you have any initialization code in your constructor, calling it more than once will execute those initialization codes again, so you’d better take care of that in your constructor; otherwise, you might end up having memory leaks or losing the data stored in that singleton instance! To avoid that, I added a new method called InitInstanceFields which is called by NewInstance whenever the singleton instance is being assigned. You can put your initialization codes in that method.</p>
</blockquote>
<p style="text-align: justify;">As it is obvious, this code won’t compile in older version of Delphi, because we are using class constructor\destructor, strict private visibility, and class var.  You need Delphi 2010 or newer versions to compile this code. Class constructors and class destructors were introduced in Delphi 2010 as an object-oriented replacement for unit <a title="unit initialization" href="http://www.delphibasics.co.uk/RTL.asp?Name=Unit&amp;ExpandCode1=Yes" target="_blank">initialization</a> and <a title="unit finalization" href="http://www.delphibasics.co.uk/RTL.asp?Name=Unit&amp;ExpandCode1=Yes" target="_blank">finalization</a> sections. They work almost the same as initialization and finalization sections, but have a big advantage over those old unit sections; a unit initialization or finalization section is always executed, either you use the corresponding classes or not. On the other hand, a class constructor or destructor is executed only if you use a class or one of its instances in your code. If you do not use the class, its class constructor or destructors won’t execute. That is how (along with <a title="Libraries and Packages (Delphi)" href="http://docwiki.embarcadero.com/RADStudio/en/Libraries_and_Packages" target="_blank">DLL delay loading</a>) Delphi team added gesture support to existing Delphi controls without such a big overhead in Delphi 2010. You can read more about class constructors and destructors in <a title="Class Constructors. Popping the hood." href="http://blogs.embarcadero.com/abauer/2009/09/04/38899" target="_blank">this blog post</a> by Allen Bauer.</p>
<h2>ModelMaker Code Template</h2>
<p style="text-align: justify;">OK, now that we have the code, we can change it a little to turn it in to a <a title="ModelMaker" href="http://www.modelmakertools.com/modelmaker/index.html" target="_blank">ModelMaker</a> code templates. Code templates are custom patterns which can be defined by the user, and applied on an element in ModelMaker. Our template is simple, the only change we need to make is using <em>&lt;!ClassName!&gt;</em> macro. This macro will be expanded automatically to the actual class name by ModelMaker. Once our code is ready, we can open ModelMaker, go to <em>View | Patterns</em> menu (Shift + F7), and once Patterns dialog is open, right-click on an empty area of the dialog, and select <em>Register Code Template</em> from the context menu. ModelMaker will ask for the template source file. We will give it address of our template source file, and a template name (I used “<em>Singleton Class</em>”). That’s it! Now our new template is registered and available in <em>Templates</em> tab of Patterns dialog. Select a class in your model, and open Patterns dialog, go to <em>Templates</em> tab, and click on your template button. ModelMaker will automatically apply it to your class, making your class a singleton class.</p>
<p><img class="alignnone" title="Singleton class in ModelMaker" src="/wp-content/uploads/2011/06/Singleton.png" alt="Singleton class in ModelMaker" width="160" height="217" /></p>
<p>Here is my ModelMaker template:</p>
<pre class="brush: delphi; title: ; notranslate">
unit Singleton;

interface

uses Windows;

type
  TCodeTemplate = class sealed(TObject)
  strict private
    class var _Instance: &lt;!ClassName!&gt;;
    class var CreationLock : RTL_CRITICAL_SECTION;
    class function GetInstance: &lt;!ClassName!&gt;; static; inline;
  private
    procedure InitInstanceFields;
  public
    constructor Create;
    destructor Destroy; override;
    class constructor ClassCreate;
    class destructor ClassDestroy;
    class function NewInstance: TObject; override; final;
    class property Instance: &lt;!ClassName!&gt; read GetInstance;
  end;

implementation

constructor TCodeTemplate.Create;
begin
  inherited;

end;

destructor TCodeTemplate.Destroy;
begin
  _Instance := nil;
  inherited;
end;

class constructor TCodeTemplate.ClassCreate;
begin
  InitializeCriticalSection(CreationLock);
end;

class destructor TCodeTemplate.ClassDestroy;
begin
  if Assigned(_Instance) then
  begin
    _Instance.Free;
    _Instance := nil;
  end;
  DeleteCriticalSection(CreationLock);
end;

class function TCodeTemplate.GetInstance: &lt;!ClassName!&gt;;
begin
  Result := Self.Create;
end;

procedure TCodeTemplate.InitInstanceFields;
begin
  { TODO : Initialize your instance here}
end;

class function TCodeTemplate.NewInstance: TObject;
begin
  if not Assigned(_Instance) then
  begin
    EnterCriticalSection(CreationLock);
    try
      _Instance := inherited NewInstance as Self;
      _Instance.InitInstanceFields;
    finally
      LeaveCriticalSection(CreationLock);
    end;
  end;

  Result := _Instance;
end;

end.
</pre>
<p>Have fun</p>
<p><em><strong><span style="text-decoration: underline;">Update 1</span></strong></em>: <em>I added a critical section to make the implementation thread-safe  (refer to David&#8217;s comment). The code for creating a new singleton  instance is protected by a critical section to make sure multiple  threads will not create multiple instances of the class if they are  accessing Instance property for the first time simultaneously.</em></p>
<p><em><strong><span style="text-decoration: underline;">Update 2</span></strong></em>: <em>There were some flaws in the sample source code and a bug in initializing instance fields. I updated the source code to fix those issues (Refer to Arthur&#8217;s comment and my reply to him).</em></p>
<p><em><br />
</em></p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/tips-tricks/implementing-singleton-pattern-in-delphi/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>دانلود از مارکت آمازون برای اندروید</title>
		<link>http://vcldeveloper.com/tips-tricks/download-from-amazon-appstore-for-android/</link>
		<comments>http://vcldeveloper.com/tips-tricks/download-from-amazon-appstore-for-android/#comments</comments>
		<pubDate>Wed, 13 Apr 2011 15:21:06 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Amazon]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Farsi]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[فارسی]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=408</guid>
		<description><![CDATA[در این نوشته قصد دارم درباره چگونگی دانلود از مارکت آمازون برای اندروید بنویسم… حدود یک ماهی میشه که شرکت آمازون یک فروشگاه آنلاین برای نرم افزارهای سیستم عامل اندروید افتتاح کرده. هر چند این فروشگاه به اندازه فروشگاه اندروید مارکت گوگل نرم افزار نداره، و به اندازه اون هم همه گیر نیست، اما با [...]]]></description>
			<content:encoded><![CDATA[<div dir="rtl">
<p style="text-align: justify;" dir="rtl">در این نوشته قصد دارم درباره چگونگی دانلود از مارکت آمازون برای اندروید بنویسم…</p>
<p style="text-align: justify;" dir="rtl">حدود یک ماهی میشه که شرکت آمازون یک فروشگاه آنلاین برای نرم افزارهای سیستم عامل اندروید افتتاح کرده. هر چند این فروشگاه به اندازه فروشگاه اندروید مارکت گوگل نرم افزار نداره، و به اندازه اون هم همه گیر نیست، اما با توجه به عظمت شرکت آمازون، و تخصص آن در فروشگاه های آنلاین، و محتوای متنوعی که این شرکت ارائه میکنه، و توجه روز افزون این شرکت به تبلت ها؛ میشه امیدوار بود که این فروشگاه به زودی به عنوان رقیبی برای اندروید مارکت شرکت گوگل تبدیل بشه، و مانعی بر سر راه انحصار طلبی تدریجی گوگل در بازار اندروید بشه. در حال حاضر، آمازون هر روز یک نرم افزار تجاری را به طور رایگان در اختیار کاربرانش قرار میده، که همین خودش تبلیغ خوبی برای این سرویس هست.</p>
<p style="text-align: justify;" dir="rtl">مارکت آمازون از دو طریق وب سای و همچنین از طریق نرم افزار اختصاصی این شرکت در دسترس هست. کاربر میتونه از طریق وب سایت آمازون یا نرم افزار مارکت آمازون لیست نرم افزارها را مرور کنه، و نرم افزار دلخواه اش را خریداری کنه. در این حالت، نرم افزار مربوطه به لیست آنلاین نرم افزارهای کاربر در سایت آمازون افزوده میشه، و کاربر میتونه از طریق نرم افزار مارکت آمازون بر روی دستگاه اندروید خود، نرم افزار های خود را دانلود کرده و بر روی دستگاه نصب کنه. مارکت فعلی امکان جستجو در لیست نرم افزارها، مشاهده دسته بندی نرم افزار، مشاهده صد نرم افزار رایگان و تجاری برتر، ایجاد Wish List، و ارائه لیست نرم افزارهای پیشنهادی بر اساس علایق شما را فراهم میکنه. البته متاسفانه نرم افزار مارکت آمازون که بر روی دستگاه نصب میشه، امکان شناسایی نرم افزارهای نصب شده فعلی را نداره، و اگر بخواید نسخه جدیدی از یکی از نرم افزارهای فعلی تان را نصب کنید، آمازون قبل از نصب نسخه جدید، نسخه قبلی را حذف میکنه، اما بعد از اینکه یک بار نرم افزار مربوطه با مارکت آمازون نصب شد، دفعات بعد، می تونید بدون مشکل آن نرم افزار را توسط مارکت آمازون آپدیت کنید.</p>
<p style="text-align: justify;" dir="rtl"><span id="more-408"></span></p>
<p style="text-align: justify;" dir="rtl">
<h2 style="text-align: justify;" dir="rtl">محدودیت فعلی دانلود</h2>
<p style="text-align: justify;" dir="rtl">بزرگترین مشکل فعلی مارکت آمازون برای اندروید، محدود کردن کاربران آن به کاربران آمریکایی هست؛ یعنی فعلا به طور رسمی، مارکت آمازون فقط به کاربرانی که در آمریکا زندگی می کنند، سرویس ارائه میکنه، و کاربرانی که قصد دانلود از سایر نقاط جهان را داشته باشند، قادر نخواهند بود که از این مارکت دانلود کنند. در این حالت، برای ما کاربران ایرانی اندروید، فرق خاصی بین مارکت گوگل و آمازون وجود نخواهد داشت؛ در هر دو حالت، امکان دانلود نرم افزار برای ما فراهم نیست.</p>
<p style="text-align: justify;" dir="rtl">اما برخلاف گوگل، شرکت آمازون کنترل خاصی بر روی دستگاه های اندروید فروخته شده نداره، و به اندازه گوگل هم محدودیت برای کاربران ایجاد نمیکنه. در واقع دانلود نرم افزار مارکت آمازون برای اندروید توسط هر کاربری حتی ایرانی امکان پذیر هست، و ثبت نام در سایت آمازون هم آزاد هست؛ اما در هنگام دانلود، آمازون از شما میخواد که اطلاعات مربوط به بخش ۱-Click Purchase را در خصوصیات کاربری خودتان وارد کنید. این اطلاعات شامل آدرس شما، و اطلاعات کارت اعتباری شما میشه، و اگر اطلاعات معتبری برای کارت اعتباری وارد نکنید، یا آدرس شما خارج از ایالات متحده آمریکا باشه، امکان دانلود برای شما فراهم نخواهد شد.</p>
<p style="text-align: justify;" dir="rtl">
<h2 style="text-align: justify;" dir="rtl">چگونگی دور زدن محدودیت دانلود</h2>
<p style="text-align: justify;" dir="rtl">همانطور که گفتم، آمازون به اطلاعات معتبر یک کارت اعتباری، و یک آدرس معتبر در داخل آمریکا نیاز داره، تا به شما اجازه دانلود بده. خب اگر یک کارت اعتباری معتبر آمریکایی داشته باشید، مشکلی نیست؛ می تونید هم نرم افزارهای رایگان و هم نرم افزارهای تجاری را از مارکت آمازون دانلود کنید. اما اگر کارت اعتباری آمریکایی نداشته باشید، چطور؟</p>
<p style="text-align: justify;" dir="rtl">در واقع شرکت آمازون فقط اعتبار کارت اعتباری را با بررسی الگوی اعداد به کار رفته در شماره کارت اعتباری بررسی میکنه، و اگر شما الگویی از اعداد را به عنوان شماره کارت اعتباری وارد کنید که مشابه یکی از الگوهای استفاده شده توسط شرکت های معتبر کارت اعتباری باشه، آمازون شماره کارت اعتباری شما را قبول میکنه. البته این به معنی آن نیست که با همچین شماره کارت اعتباری می تونید از آمازون خرید کنید، بلکه در زمان خرید یک محصول تجاری، صحت اطلاعات کارت اعتباری شما بررسی میشه، و در اون صورت، شماره جعلی شما جواب نخواهد داد، اما این بررسی فقط برای دانلود نرم افزارهای تجاری صورت میگیره، پس اگر بخواید نرم افزارهای رایگان را دانلود کنید، با همین شماره کارت جعلی هم می تونید این کار را انجام بدید. البته دقت داشته باشید که اگر آمازون متوجه استفاده از شماره کارت جعلی بشه، حساب آمازون شما مسدود خواهد شد!</p>
<p style="text-align: justify;" dir="rtl">نرم افزارها و سایت هایی هستند که می تونند برای شما شماره های کارت اعتباری به ظاهر صحیح تولید کنند، یکی از این سایت ها، سایت fakenamegenerator.com هست، که میتونه برای شما نام، آدرس، شماره تلفن، و شماره کارت اعتباری به ظاهر معتبر، ولی در واقع جعلی تولید کنه. دقت داشته باشید که سئولیت استفاده از اینگونه ابزارها با خودتان خواهد بود.</p>
<p style="text-align: justify;" dir="rtl">بعد از به دست آوردن یک شماره کارت اعتباری و  آدرس، می تونید با این نام و آدرس در سایت آمازون ثبت نام کنید. بعد از ثبت نام در سایت آمازون، به صفحه مربوط به Appstore for Android برید، و در گوشه بالا سمت راست، در کادر Get Sarted، آدرس ایمیل خود را وارد کنید. و بر روی دکمه Go کلیک کنید. با این کار، لینک دانلود Appstore برای شما ایمیل میشه، و می تونید از طریق اون لینک، فایل apk مربوطه را دریافت، و در دستگاه خودتان نصب کنید.</p>
<p style="text-align: justify;" dir="rtl">بعد از نصب برنامه در دستگاه اندریود خود، به سایت آمازون برگردید؛ و به صفحه Your Account برید، و در بخش Settings، گزینه ۱-Click Settings را انتخاب کنید. در این صفحه، از شما اطلاعات کارت اعتباری، آدرس، و تلفن شما درخواست میشه. اطلاعات کارت اعتباری که از طریق سایت fakenamegenerator به دست آوردید را در فیلدهای مربوطه وارد کنید. آدرس خود، شامل کشور، ایالت، شهر، و نام خیابان، را در فیلدهای مربوطه وارد کنید. اگر پس از ثبت آدرس، آمازون از آدرس وارد شده برای خیابان ایراد گرفت، می تونید یک آدرس واقعی در همان شهر را به راحتی با جستجو برای نام آن شهر پیدا کنید، مثلا سایت های مشاور املاک متعددی وجود دارند که آدرس خانه ها و ویلاهای آماده فروش یا کرایه را درج می کنند، یا شرکت های مختلف حاضر در شهر، آدرس خود را در سایت شان درج می کنند. پس می توانید به راحتی یک آدرس معتبر در داخل شهر و ایالت مورد نظر پیدا کنید. اگر آمازون به شما پیشنهاد داد که شاید ZIP Code وارد شده، اشتباه باشه، و منظور شما فلان آدرس هست، همان آدرس پیشنهادی آمازون را  قبول کنید. شماره تلفن جعلی که در مرحله قبل به دست آوردید را هم در کادر مربوط به شماره تلفن وارد کنید، فقط دقت کنید که حتما در ابتدای شماره تلفن، عبارت ۱+ که کد تلفن کشور آمریکا هست، را قید کنید، وگرنه امکان دانلود برای شما فراهم نخواهد شد!</p>
<p style="text-align: justify;" dir="rtl">با ذخیره کردن تنظیمات بالا، می توانید در دستگاه اندروید خود برنامه Appstore را اجرا کرده، و در سایت آمازون لاگین کنید، و لیست نرم افزارها را مرور کنید. هر نرم افزاری <strong>رایگانی </strong>که مایل به دانلود آن هستید را انتخاب کرده، و گزینه Get app را کلیک کنید. با این کار، فرایند دریافت آن فایل شروع خواهد شد. ابتدا آمازون یک فاکتور خرید برای شما ایمیل می کند، و سپس دانلود نرم افزار بر روی دستگاه شروع خواهد شد. بعد از اتمام دانلود، نرم افزار بر روی دستگاه شما نصب می شود.</p>
<p style="text-align: justify;" dir="rtl">
<h3 style="text-align: justify;" dir="rtl">دانلود با استفاده از کارت اعتباری معتبر غیر آمریکایی</h3>
<p style="text-align: justify;" dir="rtl">اگر یک کارت اعتباری معتبر، ولی غیر آمریکایی دارید، و قصد خرید محصولات تجاری از مارکت آمازون برای اندروید را دارید، در این مرحله می توانید اطلاعات کارت اعتباری واقعی خودتان را در تنظیمات حساب کاربری خودتان وارد کنید، و از طریق آن به خرید بپردازید؛ چون ظاهرا بررسی آمریکایی بودن آدرس شما فقط یک بار انجام میشه، و تغییر آدرس و شماره کارت اعتباری در مراحل بعدی، تاثیری بر امکان دانلود یا خرید شما نخواهد داشت.</p>
<p style="text-align: justify;" dir="rtl">
<p style="text-align: justify;" dir="rtl">خوش بگذره <img class="wlEmoticon wlEmoticon-smile" style="border-style: none;" src="http://vcldeveloper.com/wp-content/uploads/2011/04/wlEmoticon-smile.png" alt="Smile" /></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/tips-tricks/download-from-amazon-appstore-for-android/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to use TProcessInfo #2</title>
		<link>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo-2/</link>
		<comments>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo-2/#comments</comments>
		<pubDate>Sun, 25 Jul 2010 23:51:07 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=371</guid>
		<description><![CDATA[I had a few e-mails and comments about using TProcessInfo, so I decided to answer those questions in new blog posts. Q1: How can we find a module which is running a specific thread, giving a thread ID: A: First of all, Threads are not assigned to modules, they are assigned to processes. You can [...]]]></description>
			<content:encoded><![CDATA[<p>I had a few e-mails and comments about using <a href="http://vcldeveloper.com/products/products-components/process-info/" target="_blank">TProcessInfo</a>, so I decided to answer those questions in new blog posts.</p>
<p><strong><span style="color: #ff0000;">Q1</span></strong>: How can we find a module which is running a specific thread, giving a thread ID:</p>
<p><strong>A</strong>: First of all, <span style="text-decoration: underline;">Threads are not assigned to modules</span>, they are assigned to processes. You can find a process which is running the thread, by searching in the list of threads owned by each running process. Here is a sample code:</p>
<pre class="brush: delphi; title: ; notranslate">
function FindProcessByThreadID(ID: Cardinal): TProcessItem;
var
  ProcessInfo : TProcessInfo;
  AProcess : TProcessItem;
begin
  Result := nil;
  ProcessInfo := TProcessInfo.Create(nil);
  try
    for AProcess in ProcessInfo.RunningProcesses do
    begin
      if Assigned(AProcess.Threads.FindByID(ID)) then
      begin
        Result := AProcess;
        Exit;
      end;
    end;
  finally
    ProcessInfo.Free;
  end;
end;
</pre>
<p>FindProcessByThreadID iterates over all running processes, and checks which of them has a thread with the given ID. If a process owns a thread with that ID, it will return that process as a TProcessItem object.</p>
<p>Once you have the process object, you can get more information about the process or the specific thread, or you can kill the process, or suspend the thread. For example:</p>
<pre class="brush: delphi; title: ; notranslate">
var
  Process : TProcessItem;
begin
  Process := FindProcessByThreadID(StrToInt(3444));
  if Assigned(Process) then
    ShowMessage(Process.FullPath);
end;
</pre>
<p>The above code looks for a thread with its ID = 3444, and if it is found, it provides full path of the EXE file for that process.</p>
<p><strong><span style="color: #ff0000;">Q2</span></strong>: How can we get memory consumption for a given process?</p>
<p><strong>A</strong>: You can read memory info for a given process using TProcessItem.MemoryInfo. It provides different info about the memory the process is consuming. Here is an example for reading memory info of Google Chrome process while it is running :</p>
<pre class="brush: delphi; title: ; notranslate">
var
  ProcessInfo : TProcessInfo;
  AProcess : TProcessItem;
begin
  ProcessInfo := TProcessInfo.Create(nil);
  try
    AProcess := ProcessInfo.RunningProcesses.FindByName('Chrome.exe');
    if Assigned(AProcess) then
      ShowMessage(Format('WorkingSet Size = %d, Peak WorkingSet Size = %d',
                         [AProcess.MemoryInfo.WorkingSetSize,
                          AProcess.MemoryInfo.PeakWorkingSetSize]));
  finally
    ProcessInfo.Free;
  end;
end;
</pre>
<p>First we search for Chrome.exe process among running processes. Once the process is found, we read its current working set size, and pick working set size through MemoryInfo property, and show them in a message box. The values returned are in Bytes.</p>
<p><strong><span style="color: #ff0000;">Q3</span></strong>: How can we get process base priority class or change it?</p>
<p><strong>A</strong>: You can access base priority class for a given process or modify it (added in <a href="http://vcldeveloper.com/uncategorized/processinfo-1-3-is-released/" target="_blank">version 1.3</a>), using TProcessItem.</p>
<p>PriorityClassBase. Be careful, adjusting a base priority class of a given process inappropriately might make other processes unresponsive! Here is a example code:</p>
<pre class="brush: delphi; title: ; notranslate">
var
  ProcessInfo : TProcessInfo;
  AProcess : TProcessItem;
begin
  ProcessInfo := TProcessInfo.Create(nil);
  try
    AProcess := ProcessInfo.RunningProcesses.FindByName('firefox.exe');
    if Assigned(AProcess) then
      AProcess.PriorityClassBase := BELOW_NORMAL_PRIORITY_CLASS;
  finally
    ProcessInfo.Free;
  end;
end;
</pre>
<p>You can also change each priority of  each thread within a process by setting BasePriority property of that TThreadItem instace.</p>
<p><strong><span style="color: #ff0000;">Q4</span></strong>: How can I check if a process is 64-bit?</p>
<p><strong>A</strong>: You can check this by reading TProcessItem.Is64Bits property.</p>
<p><strong><span style="color: #ff0000;">Q5</span></strong>: How can I get CPU usage for a given process?</p>
<p><strong>A</strong>: You can get CPU usage by reading TProcessItem.CPUUsage property.</p>
<p>I hope these few answers and sample source codes can help you use Process Info. For other examples of using Process Info, please refer to this post: <a href="http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo/">How to use TProcessInfo</a></p>
<p>If there is any question regarding using Process Info, or anything about Delphi that you think worth being mentioned in Tips &amp; Tricks section of this website, please <a href="http://vcldeveloper.com/contact-me/" target="_blank">contact me</a>, and let me know about it.</p>
<p>Have Fun!</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Component Toolbar slows down RAD Studio 2010</title>
		<link>http://vcldeveloper.com/tips-tricks/component-toolbar-slows-down-rad-studio-2010/</link>
		<comments>http://vcldeveloper.com/tips-tricks/component-toolbar-slows-down-rad-studio-2010/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 19:04:01 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Component Toolbar]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Delphi 2010]]></category>
		<category><![CDATA[RAD Studio 2010]]></category>
		<category><![CDATA[دلفی]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=237</guid>
		<description><![CDATA[In RAD Studio 2010 there is a new IDE feature called Component Toolbar. This feature provides a component palette similar to the old Delphi component palette. Component Toolbar in RAD Studio 2010 This toolbar provides a nice search box which is able to filter components in the palette based on the search phrase. This toolbar [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">In <a title="RAD Studio 2010" href="http://www.embarcadero.com/products/rad-studio" target="_blank">RAD Studio 2010</a> there is a new IDE feature called Component Toolbar. This feature provides a component palette similar to the old Delphi component palette.</p>
<p style="text-align: justify;">
<div class="mceTemp" style="text-align: justify;">
<dl id="attachment_241" class="wp-caption alignnone" style="width: 540px;">
<dt class="wp-caption-dt"><a href="http://vcldeveloper.com/wp-content/uploads/2010/01/component_toolbar.png"><img class="size-full wp-image-241 " title="Component Toolbar" src="http://vcldeveloper.com/wp-content/uploads/2010/01/component_toolbar.png" alt="Component Toolbar" width="530" height="55" /></a></dt>
<dd class="wp-caption-dd">Component Toolbar in RAD Studio 2010</dd>
</dl>
</div>
<p style="text-align: justify;">
<p style="text-align: justify;">This toolbar provides a nice search box which is able to filter components in the palette based on the search phrase. This toolbar is disabled by default, and is shown when Classic Layout is selected. Here you can see a snapshot of Classic Layout in RAD Studio 2010:</p>
<p style="text-align: justify;">
<div class="mceTemp" style="text-align: justify;">
<dl id="attachment_242" class="wp-caption alignnone" style="width: 630px;">
<dt class="wp-caption-dt"><a href="http://vcldeveloper.com/wp-content/uploads/2010/01/classic_ide_delphi2010.png"><img class="size-full wp-image-242  " title="classic_ide_delphi2010" src="http://vcldeveloper.com/wp-content/uploads/2010/01/classic_ide_delphi2010.png" alt="" width="620" height="323" /></a></dt>
<dd class="wp-caption-dd">Classic Layout in Delphi 2010</dd>
</dl>
</div>
<p style="text-align: justify;">
<p style="text-align: justify;">A few weeks ago while I was working with Delphi 2010, I noticed a delay when switching from code view to form designer. The delay was there not only in the complex forms, but also in simple empty forms! It was not a big delay (about 1 second), but since I had to switch between code and form designer view many times, it was really annoying, so I decided to investigate it and find out what is causing this delay.</p>
<p style="text-align: justify;"><span id="more-237"></span>At first I got suspected to <a title="CnPack" href="http://www.cnpack.org/" target="_blank">CnPack</a> toolbars in form designer and code view, so I disabled them, but it had no effect on the delay!  Then I went for <a href="http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx" target="_blank">SysInternals Process Monitor</a> to monitor RAD Studio while switching from code view to form designer. There were many Registry activities regarding to component toolbar. At that time I was thinking about standard Tool Palette in RAD Studio 2010, not the classic component toolbar, because I was not using classic layout.</p>
<p style="text-align: justify;">I tried to hide Tool Palette to see if it fixes the delay, but it didn&#8217;t! So I decided to disable its IDE package and see if it fixes the issue. While I was looking into the list of IDE packages in Registry, I found Component Toolbar Package, and I thought this is the package corresponding to Tool Palette. So I removed it from the list of known IDE packages, and restarted RAD Studio 2010; the Tool Palette was still there, BUT the switching delay was gone!</p>
<p style="text-align: justify;">I was wondering if Component Toolbar was not related</p>
<p style="text-align: justify;">to Tool Palette, then what was it related to?! Suddenly I remembered the new classic component toolbar, and switched to Classic Layout. Yes, it was the new classic component toolbar which was using Component Toolbar Package!</p>
<p style="text-align: justify;">Since I don&#8217;t use classic view, I simply disabled this IDE package to have a faster switch time from code view to form designer. But still it is weird why this toolbar is being update even when it is not being visible, and why it is making switching from code view to form designer slower. This is definitely a bug in RAD Studio 2010.</p>
<h2 style="text-align: justify;">How to disable an IDE package:</h2>
<p style="text-align: justify;">Here is how you can disable Component Toolbar Package from Registry:</p>
<p style="text-align: justify;">1- Go to<strong> HKEY_CURRENT_USER\Software\CodeGear\BDS\7.0\Known IDE Packages</strong>.</p>
<p style="text-align: justify;">2- Make a backup by right-clicking on &#8220;Known IDE Packages&#8221; key, and selecting  Export.</p>
<p style="text-align: justify;">3- Find &#8220;<span style="text-decoration: underline;">$(BDS)\bin\comptoolbar140.bpl</span>&#8221; value in &#8220;Known IDE Packages&#8221; key, and delete it.</p>
<p style="text-align: justify;">4- Run RAD Studio 2010.</p>
<p style="text-align: justify;">Regards</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/tips-tricks/component-toolbar-slows-down-rad-studio-2010/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>How to use TProcessInfo</title>
		<link>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo/</link>
		<comments>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 14:08:29 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Tips & Tricks]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Process Info]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=173</guid>
		<description><![CDATA[The other day I published Process Info component pack which contains TProcessInfo and TAppInfo. A sample task manager was also published as demo. I thought maybe it is a good idea to talk about these components and some of their usages by providing some sample source codes. So I will start with TProcessInfo. Updating running [...]]]></description>
			<content:encoded><![CDATA[<p>The other day I published <a href="http://vcldeveloper.com/products/products-components/process-info/" target="_blank">Process Info component</a> pack which contains TProcessInfo and TAppInfo. A sample task manager was also published as <a title="Download ProcessInfo + Demo" href="http://vcldeveloper.com/downloads/ProcessInfo.zip" target="_blank">demo</a>.</p>
<p>I thought maybe it is a good idea to talk about these components and some of their usages by providing some sample source codes. So I will start with TProcessInfo.</p>
<p><span id="more-173"></span></p>
<h3>Updating running processes list automatically</h3>
<p>TProcessInfo has an internal timer which can update processes list automatically. This timer is controlled by Active, and UpdateInterval properties. Active activates the internal timer, and UpdateInterval specifies update interval. The default value for UpdateInterval is 1000 (1 second).</p>
<p>To update the list manually, and not using the internal timer, you can call UpdateList method.</p>
<h3>OnBeforeUpdate and OnAfterUpdate</h3>
<p>TProcessInfo has two events. They both are invoked when UpdateList is called, either automatically by internal timer or manually by the programmer.</p>
<p>OnBeforeUpdate is invoked just before updating the list. It has a Cancel parameter which lets you to cancel updating. OnAfterUpdate is invoked when the list is updated. So if you have a control (e.g. a list view) that should show processes list, you can write its updating code in the event-handler of OnAfterUpdate.</p>
<h3>Finding a running process</h3>
<p>You can iterate over all running processes to find a specific process with specific characteristics, or use FindByID, and FindByName methods to find a process by its Process ID or Process Name:</p>
<pre class="brush: delphi; title: ; notranslate">
var
  Process : TProcessItem;
begin
  Process := ProcessInfo1.RunningProcesses.FindByID(1234);
  if not Assigned(Process) then
    ShowMessage('No process found');
end;
</pre>
<p>Finding a process by its Process ID.</p>
<pre class="brush: delphi; title: ; notranslate">
var
  Process : TProcessItem;
begin
  Process := ProcessInfo1.RunningProcesses.FindByName('Project3.exe');
  if not Assigned(Process) then
    ShowMessage('No process found');
end;
</pre>
<p>Finding a process by its Process Name.</p>
<pre class="brush: delphi; title: ; notranslate">
var
  I: Integer;
  MemSize,
  MaxMemSize : Cardinal;
  ProcessName : string;
begin
  MaxMemSize := 0;
  for I := 0 to ProcessInfo1.RunningProcesses.Count - 1 do
  begin
    MemSize := ProcessInfo1.RunningProcesses[i].MemoryInfo.WorkingSetSize;
    if MemSize &gt; MaxMemSize then
    begin
      MaxMemSize := MemSize;
      ProcessName := ProcessInfo1.RunningProcesses[i].ExeFile;
    end;
  end;
  ShowMessage(ProcessName + ‘uses more memory than other processes.’);
end; </pre>
<p>Finding the process which consumes more memory than others.</p>
<h3>Terminating a running process</h3>
<p>To terminate a running process, you should first find it in the list of running processes, and then call its TerminateProcess method:</p>
<pre class="brush: delphi; title: ; notranslate"> var
  Process : TProcessItem;
begin
  Process := ProcessInfo1.RunningProcesses.FindByName('notepad.exe');
  if Assigned(Process) then
    Process.TerminateProcess;
end;
</pre>
<h3>Retrieving full path of a process</h3>
<pre class="brush: delphi; title: ; notranslate"> var
  Process : TProcessItem;
begin
  Process := ProcessInfo1.RunningProcesses.FindByName('notepad.exe');
  if Assigned(Process) then
    ShowMessage(Process.FullPath);
end;
</pre>
<h3>Listing modules which a process loaded</h3>
<pre class="brush: delphi; title: ; notranslate"> var
  Process : TProcessItem;
  I: Integer;
begin
  Process := ProcessInfo1.RunningProcesses.FindByName('Project1.exe');
  if  Assigned(Process) then
  begin
    for I := 0 to Process.Modules.Count - 1 do
      Memo1.Lines.Add(Format('%d  : %s',[Process.Modules[i].BaseAddress,
                                         Process.Modules[i].ModuleName]));
  end;
end;
</pre>
<p>You can access other information about a process (e.g. Threads list, threads count, memory consumption, and so on) in the same way.<br />
TAppInfo works very similar to TProcessInfo. I will try to explain it more with some examples in another article.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/tips-tricks/how-to-use-tprocessinfo/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching 1/30 queries in 0.254 seconds using disk: basic
Object Caching 1035/1103 objects using disk: basic

Served from: vcldeveloper.com @ 2012-02-04 21:09:55 -->
