<?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; دلفی</title>
	<atom:link href="http://vcldeveloper.com/tag/%d8%af%d9%84%d9%81%db%8c/feed/" rel="self" type="application/rss+xml" />
	<link>http://vcldeveloper.com</link>
	<description>Ali Keshavarz&#039;s Website</description>
	<lastBuildDate>Mon, 26 Jul 2010 00:37:57 +0000</lastBuildDate>
	<language>fa</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>ProcessInfo 1.3 is released</title>
		<link>http://vcldeveloper.com/news/processinfo-1-3-is-released/</link>
		<comments>http://vcldeveloper.com/news/processinfo-1-3-is-released/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 00:20:25 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Components]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TAppInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>
		<category><![CDATA[کامپوننت]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=370</guid>
		<description><![CDATA[Hi, ProcessInfo 1.3 is released. The changes in this release are: CPU usage is added to TProcessItem. Is64Bit is added to TProcessItem. IsAccessible is added to TProcessItem. Setting thread priority is added to TThreadItem. Setting process base priority class is added to TProcessItem. To download ProcessInfo 1.3, please go to ProcessInfo page.]]></description>
			<content:encoded><![CDATA[<p>Hi,</p>
<p>ProcessInfo 1.3 is released. The changes in this release are:</p>
<ul>
<li>CPU usage is added to TProcessItem.</li>
<li> Is64Bit is added to TProcessItem.</li>
<li> IsAccessible is added to TProcessItem.</li>
<li> Setting thread priority is added to TThreadItem.</li>
<li> Setting process base priority class is added to TProcessItem.</li>
</ul>
<p>To download ProcessInfo 1.3, please go to <a href="http://vcldeveloper.com/category/products/products-components/process-info/">ProcessInfo</a> page.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/news/processinfo-1-3-is-released/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;">
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;">
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;">
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;">
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>ProcessInfo 1.2 is released</title>
		<link>http://vcldeveloper.com/news/processinfo-1-2-is-released/</link>
		<comments>http://vcldeveloper.com/news/processinfo-1-2-is-released/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 18:45:31 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Components]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TAppInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>
		<category><![CDATA[کامپوننت]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=250</guid>
		<description><![CDATA[Hi, ProcessInfo 1.2 is released. The changes in this release are: SuspendThread, ResumeThread, TerminateThread methods are added to TThreadItem class. Now you can pause/resume/terminate any running thread in a given process. TProcessInfo.Active and TAppInfo.Active are published properties, and can be set in design mode. TProcessInfo.RunningProcesses and TAppInfo.RunningApplications automatically populate the corresponding list if UpdateList method [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Hi,</p>
<p style="text-align: justify;">ProcessInfo 1.2 is released. The changes in this release are:</p>
<ul style="text-align: justify;">
<li>SuspendThread, ResumeThread, TerminateThread methods are added to TThreadItem class. Now you can pause/resume/terminate any running thread in a given process.</li>
<li>TProcessInfo.Active and TAppInfo.Active are published properties, and can be set in design mode.</li>
<li>TProcessInfo.RunningProcesses and TAppInfo.RunningApplications automatically populate the corresponding list if UpdateList method is not called yet. This means even if you don&#8217;t activate any of these two components, or call their UpdateList method, accessing RunningProcesses or RunningApplications does not cause Access Violation.</li>
</ul>
<p style="text-align: justify;">To download ProcessInfo 1.2, please go to <a href="../products/products-components/process-info/">ProcessInfo</a> page.</p>
<p style="text-align: justify;">Regards.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/news/processinfo-1-2-is-released/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>1</slash:comments>
		</item>
		<item>
		<title>ProcessInfo 1.1 is released</title>
		<link>http://vcldeveloper.com/news/processinfo-1-1-is-released/</link>
		<comments>http://vcldeveloper.com/news/processinfo-1-1-is-released/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 05:45:15 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Components]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TAppInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>
		<category><![CDATA[کامپوننت]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=202</guid>
		<description><![CDATA[Hi, I released a new version of ProcessInfo. In this release I added these features: Enumerators are added for Windows, Threads, Modules, and Processes; Now you can use for-in statements in D2007 and above for iterating on running processes list, or modules\threads\windows of a given process. TProcessItem.UserName is added; This property returns domain name\user name [...]]]></description>
			<content:encoded><![CDATA[<p>Hi,</p>
<p>I released a new version of ProcessInfo. In this release I added these features:</p>
<ul>
<li> Enumerators are added for Windows, Threads, Modules, and Processes; Now you can use for-in statements in D2007 and above for iterating on running processes list, or modules\threads\windows of a given process.</li>
<li> TProcessItem.UserName is added; This property returns domain name\user name which is running the process.</li>
<li> TProocessInfo.AdjustDebugPrivilage is added; This method is called automatically.<br />
TThreadItem.ToString &amp; TProcessItem.ToString are added; TThreadItem.ToString returns ThreadID. TProcess.ToString returns process EXE name.</li>
<li> Now supports Delphi 7,2007,2009, 2010; Some conditional compiler directives are added so that it can be used in D7, 2007, 2009, and 2010. I tested it in D7, 2009, and 2010. It should work in D2007 too.</li>
</ul>
<p>To download ProcessInfo 1.1, please go to <a href="../products/products-components/process-info/">ProcessInfo</a> page.</p>
<p>Regards.</p>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/news/processinfo-1-1-is-released/feed/</wfw:commentRss>
		<slash:comments>1</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 15: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[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;">
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;">
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;">
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;"> 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;"> 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;"> 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>
		<item>
		<title>Process Info</title>
		<link>http://vcldeveloper.com/products/products-components/process-info/</link>
		<comments>http://vcldeveloper.com/products/products-components/process-info/#comments</comments>
		<pubDate>Tue, 08 Sep 2009 00:57:50 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Components]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[ProcessInfo]]></category>
		<category><![CDATA[TAppInfo]]></category>
		<category><![CDATA[TProcessInfo]]></category>
		<category><![CDATA[دلفی]]></category>
		<category><![CDATA[کامپوننت]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=163</guid>
		<description><![CDATA[Process Info is a free Delphi component package containing two components: TProcessInfo TAppInfo TProcessInfo provides a list of running processes. TAppInfo provides a list running applications (similar to Application tab in Windows Task Manager). Both components can update their list frequently based on the value of Interval property. TProcessInfo returns a collection of TProcessItem objects. [...]]]></description>
			<content:encoded><![CDATA[<div dir="ltr">
<p style="text-align: left;">Process Info is a free <a href="http://www.embarcadero.com/products/delphi">Delphi</a> component package containing two components:</p>
<ul>
<li>TProcessInfo</li>
<li>TAppInfo</li>
</ul>
<p style="text-align: left;">TProcessInfo provides a list of running processes. TAppInfo provides a list running applications (similar to Application tab in Windows Task Manager). Both components can update their list frequently based on the value of Interval property.</p>
<p style="text-align: left;"><span id="more-163"></span></p>
<p style="text-align: left;"><span style="text-decoration: underline;"><strong>TProcessInfo </strong></span>returns a collection of TProcessItem objects. Each instance of TProcessItem provides these information and actions for the process:</p>
<ul style="text-align: left;">
<li>Creation time</li>
<li>Kernel time</li>
<li>User time</li>
<li>EXE file name</li>
<li>Full image path</li>
<li>Process ID</li>
<li>Parent process ID</li>
<li>Terminate process</li>
<li>Threads count</li>
<li>UserName</li>
<li><strong>Modules list (TModuleItem)</strong>
<ul>
<li>Base address</li>
<li>Base size</li>
<li>Handle</li>
<li>Load count</li>
<li>Module ID</li>
<li>Module path</li>
<li>ProcessID</li>
</ul>
</li>
<li><strong>Threads list (TThreadItem)</strong>
<ul>
<li>Base priority</li>
<li>Parent process ID</li>
<li>Resume thread</li>
<li>Suspend thread</li>
<li>Terminate thread</li>
<li>Thread ID</li>
</ul>
</li>
<li><strong>Memory info (TMemoryInfo)</strong>
<ul>
<li>Page Fault Count</li>
<li>Peak Working Set Size</li>
<li>Working Set Size</li>
<li>Quota Peak Paged Pool Usage</li>
<li>Quota Paged Pool Usage</li>
<li>Quota Peak Non-paged Pool Usage</li>
<li>Quota Non-paged Pool Usage</li>
<li>Page file Usage</li>
<li>Peak Page file Usage</li>
</ul>
</li>
<li>Base priority</li>
</ul>
<p style="text-align: left;">
<p style="text-align: left;"><span style="text-decoration: underline;"><strong>TAppInfo </strong></span>returns a collection of TWindowItem. Each instance of TWindowItem provides these information for the window:</p>
<ul style="text-align: left;">
<li>Window caption</li>
<li>Application path</li>
<li>Process ID</li>
<li>Window handle</li>
<li>Window class</li>
</ul>
<p style="text-align: left;">A simple demo is also included which shows basic functionalities of TProcessInfo, and TAppInfo by creating a simple task manager. Demo is tested on Delphi 7, Delphi 2009, and Delphi 2010.</p>
<p style="text-align: left;">Process Info is published under the <a href="http://creativecommons.org/licenses/by/3.0/" target="_blank">Creative Commons Attribution 3.0 Unported License</a>.</p>
<h3 style="text-align: left;">Update:</h3>
<ul>
<li>2010/07/26: <a href="http://vcldeveloper.com/uncategorized/processinfo-1-3-is-released/"><strong>Version 1.3</strong></a></li>
<li>2010/01/13: <a href="http://vcldeveloper.com/news/processinfo-1-2-is-released/"><strong>Version 1.2</strong></a></li>
<li><span style="text-decoration: underline;">2009/10/17</span>: <a href="http://vcldeveloper.com/news/processinfo-1-1-is-released/"><strong>Version 1.1</strong></a></li>
</ul>
<p style="text-align: left;">
<p style="text-align: left;">
<h2>Download:</h2>
<p class="download"><a href="/downloads/ProcessInfo.zip">Download Process Info (Source + Demo)</a></p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/products/products-components/process-info/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>اینترفیس ها در دلفی</title>
		<link>http://vcldeveloper.com/articles/interfaces_in_delphi/</link>
		<comments>http://vcldeveloper.com/articles/interfaces_in_delphi/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 22:04:45 +0000</pubDate>
		<dc:creator>Ali Keshavarz</dc:creator>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[Article]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Farsi]]></category>
		<category><![CDATA[Interfaces]]></category>
		<category><![CDATA[اینترفیس]]></category>
		<category><![CDATA[دلفی]]></category>
		<category><![CDATA[رابط]]></category>
		<category><![CDATA[فارسی]]></category>
		<category><![CDATA[مقاله]]></category>

		<guid isPermaLink="false">http://vcldeveloper.com/?p=64</guid>
		<description><![CDATA[در این مقاله تعریف مختصری از مفهوم Interface و Abstract Class در طراحی نرم افزار ارائه می کنیم، و سپس به قابلیت های نوع Interface در دلفی و برخی کاربردهای آن، با ذکر مثال، می پردازیم.]]></description>
			<content:encoded><![CDATA[<div dir="rtl">
<p>در این مقاله تعریف مختصری از مفهوم Interface و Abstract Class در طراحی نرم افزار ارائه می کنیم، و سپس به قابلیت های نوع Interface در دلفی و برخی کاربردهای آن، با ذکر مثال، می پردازیم.</p>
<h2>مقدمه</h2>
<p>نوع Interface از نسخه ۳ به دلفی اضافه شد تا پشتیبانی از تکنولوژی COM شرکت مایکروسافت در دلفی فراهم شود. Interface علاوه بر پشتیبانی از COM، قابلیت های جالبی برای برنامه نویسان دلفی به ارمغان آورد که کمتر از آن استفاده می شود. متاسفانه به دلیل آنکه چارچوب اصلی VCL و بخصوص کامپوننت های کار با بانک اطلاعاتی دلفی مدت ها قبل از آن (از نسخه اول دلفی) ایجاد شده بودند، استفاده چندانی از Interfaceها در  VCL صورت نگرفت.</p>
<p>برای درک بهتر interface ها، و قبل از آنکه به تعریف Interface و کاربردهای آن بپردازیم، ابتدا به مفهوم کلاس های Abstract و تعریف آنها اشاره ایی خواهیم داشت؛ زیرا مشابهت هایی در کاربرد این دو مفهوم وجود دارد، و شناخت مفهوم کلاس های Abstract درک مفهوم Interfaceها را ساده تر می کند.
</p></div>
<p><span id="more-64"></span></p>
<div dir="rtl">
<h2>کلاس های Abstract</h2>
<p>در دلفی، کلاسی که حداقل یکی از متدهای آن با استفاده از رهنمود abstract تعریف شده باشد، کلاس Abstract نامیده می شود.[۱]<br />
متدهای abstract متدهایی هستند که توسط یک کلاس والد (parent) تعریف می شوند، اما پیاده سازی نمی شوند. پیاده سازی اینگونه متدها بر عهده کلاس های فرزند (child) می باشد.<br />
در صورتی که یک نمونه (instance) [ یک شی (object) ]  از یک کلاس abstract ایجاد کنید، با هشدار کامپایل مواجه خواهید شد و در صورتی که یکی از متدهای abstract آن شی را فراخوانی کنید، برنامه شما با یک استثنای EAbstractError&#8221;" متوقف خواهد شد.</p>
<p>در اینجا این سوال ممکن است مطرح شود که اصلا کلاس یا متدی که هیچ پیاده سازیی ندارد و نمی توان از آن یک نمونه شی ایجاد کرد، چه استفاده ایی ممکن است داشته باشد؟<br />
کلاس های Abstract در ساختار یک نرم افزار موجب می شوند که برنامه نویسی که پیاده سازی کلاس های فرزند را برعهده دارد، ملزم به پیاده سازی یکسری رفتارهای معین در هر یک از کلاس های خود شود؛ در غیر این صورت، با هشدارهای کامپایلر مواجه می شود. به این ترتیب احتمال اشتباه برنامه نویس (بخصوص در پروژه های بزرگ) کاهش می یابد.<br />
<span style="text-decoration: underline;">مثال :</span><br />
فرض کنید قصد داریم دو نوع پنجره طراحی کنیم (پنجره بیضوی و پنجره مستطیلی). هر دو این پنجره رفتارهای استانداردی مثل Minimize, Restore و غیره دارند. هر دو این پنجره ها باید ترسیم شوند، اما نحوه ترسیم هر یک از آنها فرق می کند. برای طراحی آنها می توانیم رفتارهای مشترک آنها را در کلاس TBaseWindow قرار دهیم و کلاس های دیگر از همین کلاس پایه، مشتق شوند. برای تعریف کلاس TBaseWindow دو روش می توانیم بکار بریم.</p>
<p>روش اول:</p>
<div dir=ltr>
<pre class="brush: delphi;">
TBaseWindow = class
private
  AField  : TSomeType;
public
  procedure Draw; virtual;
  procedure Minimize;
  procedure Maximize;
  procedure Restore;
end;
</pre>
</div>
<p>متد Draw در کلاس پایه به صورت virtual تعریف شده است، در نتیجه کلاس های TOvalWindow و TRectangularWindow (دو کلاس فرضی برای رسم پنجره بیضوی و مستطیلی، مشتق شده از کلاس پایه TBaseWindow) می توانند این متد را override کرده و پیاده سازی خود را اعمال کنند. اگر برنامه نویسان این کلاس ها فراموش کنند که متد Draw را Override کنند، تا زمان اجرای برنامه مشکلی بوجود نخواهد آمد؛ اما در زمان اجرا با فراخوانی متد Draw پنجره ایی رسم نخواهد شد!</p>
<p>روش دوم:</p>
<div dir=ltr>
<pre class="brush: delphi;">
TBaseWindow = class
private
  AField  : TSomeType;
public
  procedure Draw; virtual; abstract;
  procedure Minimize;
  procedure Maximize;
  procedure Restore;
end;
</pre>
</div>
<p>متد Draw در کلاس پایه بصورت abstract تعریف شده است. اگر برنامه نویسی که کلاس های TOvalWindow و TRectangularWindow را ایجاد می کند، فراموش کند که متد Draw را پیاده سازی کند؛ با فراخوانی متد Draw هشدار زیر را دریافت می کند:</p>
<div dir=ltr>
<p>OvalWindow.Draw;</p>
<p>Constructing instance of TOvalWindow contains abstract method TBaseWindow.Draw</p>
</div>
<h2>Interfaces</h2>
<p>اینترفیس ها نوعی قرارداد بین دو یا چند کلاس محسوب می شوند که در آن یک کلاس پیاده سازی تمامی متدهای مشخص شده در قرار داد را برای استفاده سایر کلاس ها یا کاربر تضمین می کند. پیاده سازی این متدها از دید کلاس های استفاده کننده و کاربر پنهان است. اینترفیس ها شبیه به کلاسی هستند که تمامی متد های آن abstract باشد و هیچ فیلدی برای ذخیره اطلاعات نداشته باشد.</p>
<p>اما اینترفیس ها ویژگی هایی دارند که آنها را از کلاس های Abstract جدا می کند:</p>
<p>۱-	اینترفیس ها  کلاس نیستند، بلکه یک نوع (Type) مستقل در زبان مربوطه (در اینجا Object Pascal) محسوب می شوند.<br />
۲-	اینترفیس ها از TObject مشتق نمی شوند. IUnknown در نسخه های قبلی دلفی (قبل از دلفی ۵) بعنوان والد تمام اینترفیس ها محسوب می شد، اما از نسخه ۵ به بعد، همه اینترفیس ها از IInterface مشتق می شوند.  IUnknown و IInterface یکسان هستند. از IUnknown در برنامه های مبتنی بر تکنولوژی COM مایکروسافت استفاده می شود.<br />
۳-	اگر پیدا سازی نکردن یک متد از کلاس abstract ،در کلاس های فرزند، موجب ایجاد هشدار کامپایلر می شد؛ پیاده سازی نکردن هر یک از متدهای یک اینترفیس، توسط کلاسی که آن اینترفیس را پشتیبانی می کند، موجب کامپایل نشدن برنامه می شود.<br />
۴-	یک کلاس می تواند از چندین اینترفیس بطور همزمان پشتیبانی کند.<br />
۵-	اینترفیس ها در دلفی قابلیت Reference-counting (شمارش مرجع) دارند.</p>
<p><span style="text-decoration: underline;">نکته</span>: از اینترفیس ها هم مثل کلاس های abstract نمی توان یک نمونه (شی) ایجاد کرد.</p>
<p>اینترفیس ها این امکان را به شما می دهند که خارج از ساختار سلسله مراتبی کلاس ها، قابلیت هایی را به برخی از کلاس های خود اضافه کنید. برای مثال فرض کنید شما کلاسی بنام TCar (برای تعریف یک اتومبیل) دارید که کلاس هایی مثل  TSUV, TTruck, TSedan, TVan و غیره (برای تعریف انواع اتومبیل) از آن مشتق شده اند. اگر شما قصد اضافه کردن قابلیت ۴WD (تقسیم نیروی محرکه بر روی هر چهار چرخ) به ماشین های SUV و Van داشته باشید، نمی توانید این قابلیت را در کلاس TCar پیاده سازی کنید، چون در این صورت تمامی ماشین ها از آن بهره خواهند برد. البته می توان این قابلیت را در هر یک ار این کلاس ها بصورت مستقل تعریف و پیاده سازی کرد، اما در صورت استفاده از اینترفیس (در اینجا I4wd)، هم می توانید از یک واسط مشترک استفاده کنید و هم از قابلیت های Polymorphic (چند ریختی) اینترفیس ها بهره ببرید:</p>
<div dir=ltr>
<pre class="brush: delphi;">
I4wd = interface
   ['{C2816773-A5DF-4136-AC86-27E6231DB4A9}']
   procedure Initialize4WD;
end;

TCar = class(TInterfacedObject)
public
   procedure SomeCommonBehavior;
   procedure StartEngine; virtual;
end;

TSedan = class(TCar)
public
  procedure SomeSpecificBehavior;
  procedure StartEngine; override;
end;

TSUV = class(TCar, I4wd)
public
   procedure SomeSpecificBehavior;
   procedure StartEngine; override;
   procedure Initialize4WD;
end;

TVan = class(TCar, I4wd)
public
  procedure SomeSpecificBehavior;
  procedure Initialize4WD;
end;

{نحوه استفاده}

procedure Drive4WD(A4WDCar : I4WD);
begin
  if Assigned(A4WDCar) then
  begin
     A4WDCar.Initialize4WD;
    {Add Code for driving the car here}
  end;
end;
</pre>
</div>
<p>با استفاده از رویه Drive4WD شما می توانید هر ماشینی را که از اینترفیس I4WD پشتیبانی می کند، برانید. البته هر ماشین متد Initialize4WD مربوط به خود را فراخوانی می کند. برای مثال:</p>
<div dir=ltr>Drive4WD(TVan.Create);</div>
<p>نگران آزاد کردن حافظه اشغال شده توسط TVan.Create نباشید، شی ایجاد شده بصورت خودکار آزاد خواهد شد.</p>
<div dir=rtl text-align=left>
<h3>Globally Unique Identifier (GUID)</h3>
</div>
<p>عبارت  {C2816773-A5DF-4136-AC86-27E6231DB4A9}در تعریف اینترفیس بالا، یک GUID نامیده می شود. GUID عددی ۱۲۸ بیتی است (در مبنای ۱۶) که با تقریب بالایی منحصر به فرد می باشد [ تعداد کل GUID هایی که می توان ساخت ۲ به توان ۱۲۸ است و عملا احتمال اینکه دو GUID یکسان تولید شود بسیار کم است.]</p>
<p>استفاده از GUID در تعریف یک اینترفیس موجب منحصر به فرد شدن آن اینترفیس می شود، به عبارت دیگر، حتی اگر چند اینترفیس در یک سیستم با نام مشابه وجود داشته باشند، مشکلی در استفاده از آنها بوجود نمی آید. استفاده از GUID در یک اینترفیس  اجباری  نیست، اما وجود آن برای استفاده از عملگر as، متد GetInterface، تابع Supports و متد QueryInterface  (بطور کلی (Interface Querying الزامی است. اشیاء COM، اینترفیس ها و Type Library  آنها نیز باید هر کدام دارای GUID باشند.</p>
<p>برای ساخت GUID در Editor دلفی می توانید از ترکیب سه کلید Ctrl+Shift+G استفاده کنید تا دلفی برای شما یک GUID ایجاد کند.</p>
<p>نکته: هیچگاه GUID یک اینترفیس را در یک اینترفیس دیگر استفاده نکنید.</p>
<h3>استخراج یک Interface از داخل یک Class</h3>
<p>فرد متاهلی را در نظر بگرید که ریس یک شرکت می باشد. این فرد در رابطه با کارمندان خود نقش ریس، در رابطه با همسر خود نقش شوهر و در رابطه با فرزندان خود نقش پدر را ایفا می کند. در واقع این فرد در رابطه با هر گروه از افراد مذکور طبق یک رسم یا توافق مشترک، عمل می کند. هر یک از این گروه ها نیز بر اساس همان توافق یا رسم با این فرد ارتباط برقرار می کند و فقط به نقش مربوط به خود نیاز دارد (مثلا یک کارمند نیازی به دانستن رابطه ریس خود با همسر و فرزندانش ندارد). در دنیای نرم افزار هم یک کلاس می تواند با پیاده سازی اینترفیس های مختلف، نقش های مختلفی را در ارتباط با دنیای خارج بر عهده بگیرد.</p>
<p>حال، فرد فوق را بعنوان یک کلاس و توافق او با هر یک از گروه های فوق را به عنوان یک اینترفیس در نظر می گیریم:<br />
هر گروه (درخواست کننده؛ هر شی در دنیای خارج از آن کلاس) باید ابتدا بررسی کند که آیا فرد  (کلاس پیاده سازی کننده )  مذکور به رسومات و توافق مشخص شده (اینترفیس)  پایبند هست یا نه، اگر آن کلاس از اینترفیس مشخص شده پشتیبانی کند، درخواست کننده می تواند، بر اساس همان اینترفیس، درخواست خود را به آن کلاس ارائه دهد و جواب دریافت کند (استخراج یک اینترفیس از کلاسی که آن را پیاده سازی می کند).</p>
<p>در دلفی برای بررسی پشتیبانی کردن یک کلاس از یک اینترفیس خاص و استخراج آن اینترفیس می توان از تابع Supports در یونیت SysUtils، متد QueryInterface از هر کلاسی که IInterface را پشتیبانی می کند (مثل TInterfaceObject)  ، عملگر as، یا متد GetInterface در کلاس TObject استفاده کرد.[۲]</p>
<p>به روش های مختلف استخراج اینترفیس I4WD از کلاس TSUV در مثال زیر توجه کنید:</p>
<div dir=ltr>
<pre class="brush: delphi;">
var
SUV : TSUV;
A4wdInterface : I4WD;
begin
  {If TSuv implements I4WD (supports it), extract the interface.}
  if Supports(TSUV.Create,I4WD,A4wdInterface) then
  {Invoke Initialize4WD from returned interface.}
  A4wdInterface.Initialize4WD;

  //----------------------------------
  {Just check if TSuv supports I4WD, no interface is returned.}
  if Supports(TSuv,I4WD) then
  ShowMessage('TSuv supports I4WD interface');

  //----------------------------------
  SUV := TSUV.Create;
  {If you are sure than SUV supports I4WD, use as operator to extract
  the interface and invoke Initialize4WD.
  If SUV does not support I4WD, an exception will be thrown.}
  (SUV as I4wd).Initialize4WD;

  //----------------------------------
  SUV := TSUV.Create;
  {If Suv implements I4WD (supports it), extract the interface.}
  if SUV.GetInterface(I4WD,A4wdInterface) then
  A4wdInterface.Initialize4WD;

  //----------------------------------
  {TSUV supports I4WD, so you can assign an instance of it to a variable of type I4WD.}
  A4wdInterface := TSuv.Create;
  A4wdInterface.Initialize4WD;
end;
</pre>
</div>
<p>* تمامی توابع و عملگرهای فوق در راهنمای دلفی توضیح داده شده اند.</p>
<h3>Multiple Inheritance (وراثت چندگانه)</h3>
<p>در زبانهایی مثل دلفی، C#، و جاوا وراثت چندگانه امکان پذیر نیست &#8211; یعنی یک کلاس نمی تواند مثل C++ از چند کلاس والد مشتق شود. اما در این زبان ها امکان پیاده سازی چند اینترفیس توسط یک کلاس وجود دارد و می تواند به نوعی این خلاء را پر کند. مثلا کلاس TMyMobile (یک کلاس فرضی مربوط به گوشی موبایل) می تواند بطور همزمان اینترفیس های IInfraRed و IBlueTooth را پیاده سازی کند:</p>
<div dir=ltr>
<pre class="brush: delphi;">
TMyMobile = class(TInterfaceObject, IInfraRed, IBlueTooth)
  {TMobile's fields and methods + IInfraRed's methods + IBlueThoot's methods}
end;
</pre>
</div>
<h3>Reference counting (شمارش مرجع)</h3>
<p>یکی از ویژگی های مهم اینترفیس ها در دلفی (همچنین در COM) خصوصیت Reference Counting آنها ست. با استفاده از این قابلیت اشیاء ایجاد شده بصورت خودکار مدیریت می شوند و در صورتی که نیازی به آنها نباشد، بطور خودکار آزاد می شوند. متدهای مربوط به این قابلیت در اینترفیس IInterface تعریف شده اند.<br />
هر بار که اینترفیسی از یک کلاس استخراج می شود یا نمونه ایی از یک کلاس به متغیری از یک اینترفیس اختصاص داده می شود، دلفی متد _AddRef از اینترفیس IInterface را فراخوانی می کند. هر زمان که آن متغیر نا معتبر شود (با اختصاص مقدار nil به آن یا خارج شدن از محدوده تعریف آن متغیر)، دلفی متد _Release را فراخوانی می کند. شما به عنوان برنامه نویس وظیفه دارید که متغیری در کلاس خود تعریف کرده (برای ذخیره شماره مرجع) و این متد ها را پیاده سازی کنید. با اجرای _AddRef باید یک واحد به شماره مرجع اضافه شود. با اجرای _Release باید یک واحد از شماره مرجع کم شود، اگر شماره مرجع به صفر رسید، _Release وظیفه آزاد کردن شی ایجاد شده را بر عهده دارد.</p>
<p>در صورتی که تمایلی به پیاده سازی متدهای فوق ندارید، می توانید کلاس خود را از کلاس TInterfacedObject مشتق بگیرید. در این صورت کلاس TInterfacedObject قابلیت شمارش مرجع را برای کلاس شما پیاده سازی خواهد کرد. TInterfacedObject در یونیت System تعریف شده است. بهتر است کد آن را مطالعه نمایید.</p>
<p>به مثال های زیر در رابطه با کاربرد Reference Counting توجه کنید:</p>
<div dir=ltr>
<pre class="brush: delphi;">
procedure TForm1.Button3Click(Sender: TObject);
var
  SUV : TSUV;
  Van : TVan;
  AnInterface,
  AnotherInterface : I4WD;
begin
  Memo1.Clear;
  SUV := TSuv.Create;
  //SUV.RefCount = 0
  AnInterface := SUV;
  //SUV.RefCount = 1
  AnotherInterface := SUV;
  //SUV.RefCount = 2

  Van := TVan.Create;
  //Van.RefCount = 0;
  AnInterface := Van;
  //SUV.RefCount = 1
  //Van.RefCount = 1
end;
//&quot; AnInterface&quot; is out of scope: SUV.RefCount = 0
//SUV is destroyed
//AnotherInterface is out of scope: Van.RefCount = 0
//Van is destroyed
</pre>
</div>
<p>در مثال بالا به تغییرات RefCount توجه کنید:<br />
زمانی که SUV به یک اینترفیس اختصاص داده می شود، یک واحد به شمارشگر مرجع آن افزوده می شود.<br />
با اختصاص SUV به اینترفیس بعدی (AnotherInterface)، شمارشگر مرجع آن به ۲ می رسد.<br />
با اختصاص  Vanبه اینترفیس AnInterface ، شمارشگر مرجع این شی یک واحد افزایش پیدا می کند، ولی شمارشگر مرجع شی SUV که قبلا به AnInterface اختصاص داده شده بود، یک واحد کاهش پیدا می کند.<br />
در پایان این متد، هیچ کدی برای آزاد سازی متغیرهای SUV و Van وجود ندارد؛ اما با پایان یافتن کد Form1.Button3Click، متغیرهای AnInterface و AnotherInterface که بصورت محلی تعریف شده اند، نامعتبر می شوند و با نامعتبر شدن هر یک از آنها، یک واحد از شمارشگر مرجع هر یک از اشیاء اختصاص یافته به آنها کاهش میابد. با صفر شدن شمارشگر مرجع هر شی، آن شی آزاد می شود.</p>
<p>Malcome Groves در مقاله Interfaces: Off the Beaten Track مثالی از پیاده سازی قابلیت Garbage Collection با استفاده از اینترفیس ارائه کرده است[۳] :</p>
<div dir=ltr>
<pre class="brush: delphi;">
unit mtReaper;

interface

type
ImtReaper = interface
  ['{1B321324-975F-4026-B742-E7B3AD486BB5}']
end;

TmtReaper = class(TInterfacedObject, ImtReaper)
private
  FObject : TObject;
public
  constructor Create(AObject : TObject);
  destructor Destroy; override;
end;

implementation

uses SysUtils;

constructor TmtReaper.Create(AObject: TObject);
begin
  FObject := AObject;
end;

destructor TmtReaper.Destroy;
begin
  FreeAndNil(FObject);
  inherited;
end;

end.
</pre>
</div>
<p>در این کد کلاس ساده ایی ((TmtReaper تعریف شده که Garbage Collection را برای شما انجام می دهد. با ارسال یک شی به متد Create این کلاس، شی مورد نظر در زمان مقتضی آزاد خواهد شد و نیازی نیست که شما شخصا آن شی را آزاد کنید:</p>
<div dir=ltr>
<pre class="brush: delphi;">
var
  List : TStringList;
  mtReaper : ImtReaper;
begin
  List := TStringList.Create;
  mtReaper := TmtReaper.Create(List);

  //Use List in your code
  List.LoadFromFile('A File Name');
  List.Sort;
end;
//List will be destroyed automatically by mtReaper
</pre>
</div>
<p>در دلفی ۲۰۰۹ می توان این قابلیت را با استفاده از مفهوم Smart Pointers به شکل مناسب تری پیاده سازی کرد.</p>
<p>۲۷ مهر ۱۳۸۴  (بازنگری: ۱۳ اسفند ۱۳۸۷)</p>
<hr /></hr>
<h2>پاورقی</h2>
<p>[۱] &#8211; در دلفی ۲۰۰۶ و نسخه های بعد از آن می توان با اضافه کردن رهنمود abstract به تعریف کلاس، کل متدهای آن را بصورت abstract تعریف کرد، و لزومی ندارد عبارت abstract را به تعریف تک تک متدها اضافه کنیم:<br />
TPureAbstract = class abstract</p>
<p>[2] &#8211; در واقع تمامی روش های ذکر شده در داخل خود به نوعی از متد GetInterface استفاده می کنند.</p>
<p>[۳] &#8211; Delphi Magazine شماره ۸۰٫</p></div>
]]></content:encoded>
			<wfw:commentRss>http://vcldeveloper.com/articles/interfaces_in_delphi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
