<?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/"
	xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Bayu Prasetio's Weblog &#187; Delphi</title>
	<atom:link href="http://bprasetio.wordpress.com/category/delphi/feed/" rel="self" type="application/rss+xml" />
	<link>http://bprasetio.wordpress.com</link>
	<description>Exploring the Possibilities</description>
	<lastBuildDate>Fri, 21 Aug 2009 22:21:01 +0000</lastBuildDate>
	<generator>http://wordpress.com/</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<cloud domain='bprasetio.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://www.gravatar.com/blavatar/5f5419da963ff1ac5e3643ae766e3879?s=96&#038;d=http://s.wordpress.com/i/buttonw-com.png</url>
		<title>Bayu Prasetio's Weblog &#187; Delphi</title>
		<link>http://bprasetio.wordpress.com</link>
	</image>
			<item>
		<title>Kode untuk Mematikan Layar Laptop</title>
		<link>http://bprasetio.wordpress.com/2009/02/10/kode-untuk-mematikan-layar-laptop/</link>
		<comments>http://bprasetio.wordpress.com/2009/02/10/kode-untuk-mematikan-layar-laptop/#comments</comments>
		<pubDate>Tue, 10 Feb 2009 11:00:10 +0000</pubDate>
		<dc:creator>bprasetio</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Did You Know]]></category>
		<category><![CDATA[Ngoprek]]></category>
		<category><![CDATA[SC_MONITORPOWER]]></category>
		<category><![CDATA[turn off monitor]]></category>
		<category><![CDATA[WM_SYSCOMMAND]]></category>

		<guid isPermaLink="false">http://bprasetio.wordpress.com/?p=577</guid>
		<description><![CDATA[Cerita bermula ketika saya berada di luar kota untuk tugas kantor. Saat itu tim lupa membawa sebuah perlengkapan penting, yaitu kabel roll. Namun untunglah tim yang lain membawanya, tapi masalahnya sampai di tempat penginapan belakangan, berjam-jam kemudian. Jadilah tim berhemat ria dalam menggunakan laptop.

Berbagai macam cara ditempuh, mulai dari mematikan perangkat yang tidak diperlukan seperti [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=577&subd=bprasetio&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Cerita bermula ketika saya berada di luar kota untuk tugas kantor. Saat itu tim lupa membawa sebuah perlengkapan penting, yaitu kabel roll. Namun untunglah tim yang lain membawanya, tapi masalahnya sampai di tempat penginapan belakangan, berjam-jam kemudian. Jadilah tim berhemat ria dalam menggunakan laptop.</p>
<p><span id="more-577"></span></p>
<p>Berbagai macam cara ditempuh, mulai dari mematikan perangkat yang tidak diperlukan seperti <em>Wireless Network</em>, <em>Infrared</em>, <em>Bluetooth</em>, mematikan volume suara, meredupkan layar, mematikan <em>service</em> yang tidak perlu, bahkan mengurangi periode <em>compile</em>.</p>
<p>Saat itu timbul pemikiran bagaimana mematikan layar laptop untuk sementara waktu, seperti layaknya mematikan layar monitor dengan tombol <em>power-off</em> nya. Di monitor LCD atau CRT, hal ini tidak masalah, namun bagaimana dengan laptop yang tidak punya tombol <em>power-off</em> ? Satu &#8211; satu nya cara untuk mematikan adalah memanfaatkan power management yang tentunya harus menentukan <em>idle time</em> nya terlebih dahulu. Padahal yang diinginkan adalah mematikan saat itu juga.</p>
<p>So, solusinya adalah dengan menggunakan <em>software</em>. Untuk <em>software</em> semestinya tersedia, namun karena waktu itu tidak terlintas untuk <em>hunting</em> <em>software</em> seperti itu,  jadinya saya buat program kecil untuk mematikan layar laptop, dan itu tidaklah sulit.</p>
<p>Intinya adalah dengan menggunakan Windows API <em>WM_SYSCOMMAND</em> dengan <em>wParam</em> <em>SC_MONITORPOWER</em> dengan <em>lParam</em> berikut:<br />
-1 =&gt; turn monitor on<br />
 1 =&gt; turn monitor to low power<br />
 2 =&gt; turn monitor off</p>
<p>Untuk memudahkan akses, ditambahkan <em>hotkey</em>, <em>hotkey</em> ini fleksibel bisa diubah sekehendak hati.</p>
<p>Berikut cuplikan gambar dari program kecil ini:<br />
<div id="attachment_580" class="wp-caption alignnone" style="width: 350px"><img src="http://bprasetio.files.wordpress.com/2009/02/monitorpowerswitcher.jpg?w=340&#038;h=250" alt="Tampilan Program" title="monitorpowerswitcher" width="340" height="250" class="size-full wp-image-580" /><p class="wp-caption-text">Tampilan Program</p></div></p>
<p>Tentu saja tool ini masih banyak kekurangannya, seperti pada laptop saya, setiap penekanan <em>key</em> men-<em>trigger</em> <em>power-on</em>, tidak cuman <em>hotkey</em> yang sudah ditentukan, mungkin ini pengaruh dari konfigurasi dan <em>driver</em> bawaan dari produsen laptop. </p>
<p>Warning:</p>
<blockquote><p>saya tidak menjamin berjalan 100% di laptop lain, satu hal yang pasti, <em>power-off</em> berjalan di laptop saya, belum tentu berjalan di laptop Anda!
</p></blockquote>
<p>Mungkin rekan &#8211; rekan dapat mengembangkannya lebih lanjut.</p>
<p>Program ini dapat diunduh di <a href="http://home.bprasetio.or.id/files/MonitorPowerSwitcher.7z">sini</a>.</p>
<p>Semoga bermanfaat.</p>
Posted in Delphi, Did You Know, Ngoprek  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bprasetio.wordpress.com/577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bprasetio.wordpress.com/577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bprasetio.wordpress.com/577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bprasetio.wordpress.com/577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bprasetio.wordpress.com/577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bprasetio.wordpress.com/577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bprasetio.wordpress.com/577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bprasetio.wordpress.com/577/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bprasetio.wordpress.com/577/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bprasetio.wordpress.com/577/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=577&subd=bprasetio&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bprasetio.wordpress.com/2009/02/10/kode-untuk-mematikan-layar-laptop/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">bprasetio</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2009/02/monitorpowerswitcher.jpg" medium="image">
			<media:title type="html">monitorpowerswitcher</media:title>
		</media:content>
	</item>
		<item>
		<title>Hindari FieldByName pada Penggunaan Intensif</title>
		<link>http://bprasetio.wordpress.com/2008/12/18/hindari-fieldbyname-pada-penggunaan-intensif/</link>
		<comments>http://bprasetio.wordpress.com/2008/12/18/hindari-fieldbyname-pada-penggunaan-intensif/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 05:46:05 +0000</pubDate>
		<dc:creator>bprasetio</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Did You Know]]></category>
		<category><![CDATA[FieldByName]]></category>
		<category><![CDATA[QueryPerformanceCounter]]></category>
		<category><![CDATA[QueryPerformanceFrequency]]></category>

		<guid isPermaLink="false">http://bprasetio.wordpress.com/?p=564</guid>
		<description><![CDATA[Bagi Delphiers yang sering berinteraksi dengan database, tentu tidak asing dengan penggunaan FieldByName. Pada operasi akses field yang bersifat intensif, misalnya konversi data, penyalinan data dari satu database atau tabel ke database atau tabel lainnya, penggunaan FieldByName harus dihindari.

Untuk mencapai suatu field dengan menggunakan FieldByName, terlebih dahulu harus dilakukan pencarian alamat referensi field yang dimaksud [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=564&subd=bprasetio&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Bagi <em>Delphiers</em> yang sering berinteraksi dengan database, tentu tidak asing dengan penggunaan <em>FieldByName</em>. Pada operasi akses <em>field</em> yang bersifat intensif, misalnya konversi data, penyalinan data dari satu database atau tabel ke database atau tabel lainnya, penggunaan <em>FieldByName</em> harus dihindari.</p>
<p><span id="more-564"></span></p>
<p>Untuk mencapai suatu <em>field</em> dengan menggunakan <em>FieldByName</em>, terlebih dahulu harus dilakukan pencarian alamat referensi field yang dimaksud dengan melakukan iterasi setiap <em>field</em> pada daftar <em>field</em> (<em>FieldList</em>) dari awal hingga akhir untuk mencocokkan namanya (<em>FieldName</em>). Proses iterasi akan berhenti ketika ditemukan nama <em>field</em> pada daftar <em>field</em>. Proses kemudian mengembalikan alamat referensi <em>field</em> yang dimaksud.</p>
<p>Sekilas, proses yang terjadi pada <em>FieldByName</em> ditunjukkan pada potongan kode berikut:</p>
<pre class="brush: delphi;">
function TFields.FieldByName(const FieldName: WideString): TField;
begin
  Result := FindField(FieldName);
  if Result = nil then DatabaseErrorFmt(SFieldNotFound, [FieldName], DataSet);
end;
</pre>
<p>Jika ditelusuri, fungsi <em>FindField</em> adalah sebagai berikut:</p>
<pre class="brush: delphi;">
function TFields.FindField(const FieldName: WideString): TField;
var
  I: Integer;
begin
  for I := 0 to FList.Count - 1 do
  begin
    Result := FList.Items[I];
    if WideCompareText(Result.FFieldName, FieldName) = 0 then Exit;
  end;
  Result := nil;
end;
</pre>
<p>Oke, untuk lebih mantapnya, perlu kita buat sebuah rutin untuk mengukur bagaimana penggunaan <em>FieldByName</em> pada operasi yang intensif mengakses <em>field</em>. Perlu diingat bahwa kode yang dijadikan sebagai contoh dibuat sesederhana mungkin, hanya mengakses 2 <em>field</em> saja dan tidak ada operasi lain yang menyertainya seperti perhitungan, seleksi kondisi dan sebagainya. Pada keadaan sesungguhnya, bentuk operasi bisa jauh lebih kompleks dan bervariasi.</p>
<p>Berikut gambaran singkat mengenai data yang akan dijadikan bahan pengukuran<br />
- Sistem Core2Duo 1.66GHz, 667MHz FSB, 2MB L2 Cache, 1GB RAM, dengan free ram &gt; 256MB (ada program yg berjalan: Delphi2007, FF, EMS SQL Manager, Notepad++)<br />
- Windows XP Professional SP3<br />
- MySQL 5.1.21, akses lokal, konfigurasi standar<br />
- Tabel dengan jenis InnoDB, jumlah <em>record</em> sekitar 29000-an<br />
- Pengukuran menggunakan <em>QueryPerformaceCounter</em> &amp; <em>QueryPerformanceFrequency</em><br />
- Sangat dimungkinkan terjadi proses <em>caching</em> pembacaan hasil proses sebelumnya. Untuk itu lakukan proses perhitungan dengan jeda waktu yang lama dan berkali &#8211; kali untuk meyakinkan nilainya.</p>
<p><strong>Metode 1</strong></p>
<p>Metode 1 menggunakan <em>FieldByName</em> seperti pada potongan kode berikut:</p>
<pre class="brush: delphi;">
procedure TForm2.btnMethod1Click(Sender: TObject);
var
  A, B          : Double;
  FFreq         : Int64;
  FStartCounter : Int64;
  FStopCounter  : Int64;
  I             : Integer;
begin
  MyConnection1.Connected := True;
  MyQuery1.Active := True;

  A := 0;
  B := 0;
  QueryPerformanceFrequency(FFreq);
  QueryPerformanceCounter(FStartCounter);
  for I := 0 to 1000 do
  begin
    MyQuery1.First;
    while not MyQuery1.Eof do
    begin
      A := MyQuery1.FieldByName('jumlah').AsFloat;
      B := MyQuery1.FieldByName('jumlahnetto').AsFloat;
      MyQuery1.Next;
    end;
  end;
  QueryPerformanceCounter(FStopCounter);

  Label1.Caption := FloatToStr((FStopCounter - FStartCounter) / FFreq);

  MyQuery1.Active := False;
  MyConnection1.Connected := False;
end;
</pre>
<p>Hasil dari eksekusi rutin tersebut adalah 117,7975 detik.<br />
<div id="attachment_565" class="wp-caption alignnone" style="width: 212px"><img src="http://bprasetio.files.wordpress.com/2008/12/method1.jpg?w=202&#038;h=35" alt="Hasil Pengukuran Metode 1" title="method1" width="202" height="35" class="size-full wp-image-565" /><p class="wp-caption-text">Hasil Pengukuran Metode 1</p></div></p>
<p>Cukup lama bukan ? Lalu adakah teknik untuk mempersingkat operasi tersebut ? Tentu saja ada !</p>
<p><strong>Metode 2</strong></p>
<p>Teknik ini mungkin sudah banyak diketahui, namun mungkin jarang digunakan. Alih &#8211; alih menggunakan nama <em>field</em> untuk mencari <em>field</em> yang dikehendaki, teknik ini langsung mengakses alamat referensi dari <em>field</em> yang dikehendaki dengan memanfaatkan nomor indeks <em>field</em> tersebut dalam daftar <em>field</em>. Tentu saja untuk melakukannya harus diketahui terlebih dahulu nomor indeks yang tepat. <em>Field</em> pertama diakses melalui nomor indeks 0, <em>field</em> kedua diakses melalui nomor indeks 1, demikian seterusnya.</p>
<p>Salah satu sebab teknik ini jarang dilakukan adalah karena konsistensi nomor urut <em>field</em>. Jika misalnya terdapat perubahan susunan tabel atau perintah <em>query</em>, maka nomor urut <em>field</em> dimungkinkan tidak sesuai lagi. Dengan demikian harus dilakukan perubahan nomor urut pada kode sumber.</p>
<p>Disisi lain, teknik ini sangat sesuai apabila diterapkan pada aplikasi konversi / migrasi database / tabel dimana jumlah dan nama <em>field</em> sangat variatif. Disini, nama <em>field</em> tidak dapat dijadikan sebagai acuan. Yang perlu dilakukan hanyalah memberikan nomor indeks dari awal hingga akhir dan lakukan proses iterasi per <em>record</em>, dari <em>field</em> awal sampai akhir.</p>
<p>Berdasarkan kode metode 1, maka dilakukan perubahan seperti pada kode berikut:</p>
<pre class="brush: delphi;">
procedure TForm2.btnMethod2Click(Sender: TObject);
var
  A, B          : Double;
  FFreq         : Int64;
  FStartCounter : Int64;
  FStopCounter  : Int64;
  I             : Integer;
begin
  MyConnection1.Connected := True;
  MyQuery1.Active := True;

  A := 0;
  B := 0;
  QueryPerformanceFrequency(FFreq);
  QueryPerformanceCounter(FStartCounter);
  for I := 0 to 1000 do
  begin
    MyQuery1.First;
    while not MyQuery1.Eof do
    begin
      A := MyQuery1.Fields[12].AsFloat;
      B := MyQuery1.Fields[13].AsFloat;
      MyQuery1.Next;
    end;
  end;
  QueryPerformanceCounter(FStopCounter);

  Label2.Caption := FloatToStr((FStopCounter - FStartCounter) / FFreq);

  MyQuery1.Active := False;
  MyConnection1.Connected := False;
end;
</pre>
<p>Hasil dari eksekusi rutin tersebut adalah 27,1231 detik. Sangat manjur bukan ?<br />
<div id="attachment_567" class="wp-caption alignnone" style="width: 210px"><img src="http://bprasetio.files.wordpress.com/2008/12/method2.jpg?w=200&#038;h=30" alt="Hasil Pengukuran Metode 2" title="method2" width="200" height="30" class="size-full wp-image-567" /><p class="wp-caption-text">Hasil Pengukuran Metode 2</p></div></p>
<p>Masih belum puas dengan hasil tersebut ? Simak teknik berikutnya.</p>
<p><strong>Metode 3</strong></p>
<p>Teknik ini lebih jarang lagi digunakan. Alih &#8211; alih melakukan penunjukan <em>field</em> yang dimaksud dengan memberikan nomor indeks yang sesuai pada setiap iterasi <em>record</em> dimana proses penunjukan <em>field</em> membutuhkan proses untuk mengakses kelas <em>TField</em>, teknik ini langsung mengakses kelas <em>TField</em> tersebut berada. Caranya adalah dengan terlebih dahulu mendapatkan alamat dimana kelas <em>TField</em> tersebut berada. Alamat tersebut kemudian di simpan pada variabel lokal yang akan digunakan untuk mengakses <em>field</em> tersebut secara langsung.</p>
<p>Berikut kode untuk metode 3:</p>
<pre class="brush: delphi;">
procedure TForm2.btnMethod3Click(Sender: TObject);
var
  A, B          : Double;
  FFreq         : Int64;
  FStartCounter : Int64;
  FStopCounter  : Int64;
  I             : Integer;
  AField        : TField;
  AField2       : TField;
begin
  MyConnection1.Connected := True;
  MyQuery1.Active := True;

  A := 0;
  B := 0;
  QueryPerformanceFrequency(FFreq);
  QueryPerformanceCounter(FStartCounter);
  AField := MyQuery1.FieldByName('jumlah');
  AField2 := MyQuery1.FieldByName('jumlahnetto');
  for I := 0 to 1000 do
  begin
    MyQuery1.First;
    while not MyQuery1.Eof do
    begin
      A := AField.AsFloat;
      B := AField2.AsFloat;
      MyQuery1.Next;
    end;
  end;
  QueryPerformanceCounter(FStopCounter);

  Label3.Caption := FloatToStr((FStopCounter - FStartCounter) / FFreq);

  MyQuery1.Active := False;
  MyConnection1.Connected := False;
end;
</pre>
<p>Hasil dari eksekusi rutin tersebut adalah 26,9201 detik.<br />
<div id="attachment_568" class="wp-caption alignnone" style="width: 209px"><img src="http://bprasetio.files.wordpress.com/2008/12/method3.jpg?w=199&#038;h=34" alt="Hasil Pengukuran Metode 3" title="method3" width="199" height="34" class="size-full wp-image-568" /><p class="wp-caption-text">Hasil Pengukuran Metode 3</p></div></p>
<p>Tentu saja masih ada celah perbaikan walaupun pengaruhnya mungkin tidak signifikan, tergantung dari kode Anda, yaitu dengan mengganti kode <em>FieldByName</em> menjadi <em>Fields[x]</em> dimana x adalah nomor indeks field yang dikehendaki.</p>
<p>Contoh kode diatas sangat intensif menggunakan variabel bertipe <em>TField</em> untuk menampung alamat referensi dari <em>field</em> yang dikehendaki. Lalu bagaimana apabila jumlah <em>field</em> yang diakses sangat banyak atau bahkan sangat bervariasi ? Bukankah sangat tidak efisien apabila mendeklarasikan semua variabel yang diperlukan ? Lalu adakah teknik untuk mensiasatinya ? Simak metode selanjutnya.</p>
<p><strong>Metode 4</strong></p>
<p>Salah satu teknik yang dapat digunakan adalah dengan menggunakan <em>array</em> dinamis. Namun untuk menyederhanakan pembahasan, pada contoh ini hanya akan mengunakan <em>array</em> statis.</p>
<pre class="brush: delphi;">
procedure TForm2.btnMehtod4Click(Sender: TObject);
var
  A, B          : Double;
  FFreq         : Int64;
  FStartCounter : Int64;
  FStopCounter  : Int64;
  I             : Integer;
  AField        : array [1..2] of TField;
begin
  MyConnection1.Connected := True;
  MyQuery1.Active := True;

  A := 0;
  B := 0;
  QueryPerformanceFrequency(FFreq);
  QueryPerformanceCounter(FStartCounter);
  AField[1] := MyQuery1.FieldByName('jumlah');
  AField[2] := MyQuery1.FieldByName('jumlahnetto');
  for I := 0 to 1000 do
  begin
    MyQuery1.First;
    while not MyQuery1.Eof do
    begin
      A := AField[1].AsFloat;
      B := AField[2].AsFloat;
      MyQuery1.Next;
    end;
  end;
  QueryPerformanceCounter(FStopCounter);

  Label4.Caption := FloatToStr((FStopCounter - FStartCounter) / FFreq);

  MyQuery1.Active := False;
  MyConnection1.Connected := False;
end;
</pre>
<p>Sama seperti sebelumnya, tentu saja masih ada celah perbaikan walaupun pengaruhnya mungkin tidak signifikan, tergantung dari kode Anda, yaitu dengan mengganti kode <em>FieldByName</em> menjadi <em>Fields[x]</em> dimana x adalah nomor indeks field yang dikehendaki.</p>
<p>Hasil dari eksekusi rutin tersebut adalah 26,8862 detik.<br />
<div id="attachment_566" class="wp-caption alignnone" style="width: 204px"><img src="http://bprasetio.files.wordpress.com/2008/12/method4.jpg?w=194&#038;h=32" alt="Hasil Pengkuran Metode 4" title="method4" width="194" height="32" class="size-full wp-image-566" /><p class="wp-caption-text">Hasil Pengkuran Metode 4</p></div></p>
<p>Sebagai latihan, silahkan mencoba dengan jumlah <em>field</em> yang lebih banyak dan bandingkan hasilnya. Adakah terjadi peningkatan kecepatan ? Silahkan cari tahu sendiri sebabnya.</p>
<p>Semoga bermanfaat.</p>
Posted in Delphi, Did You Know  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bprasetio.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bprasetio.wordpress.com/564/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bprasetio.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bprasetio.wordpress.com/564/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bprasetio.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bprasetio.wordpress.com/564/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bprasetio.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bprasetio.wordpress.com/564/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bprasetio.wordpress.com/564/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bprasetio.wordpress.com/564/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=564&subd=bprasetio&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bprasetio.wordpress.com/2008/12/18/hindari-fieldbyname-pada-penggunaan-intensif/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">bprasetio</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/12/method1.jpg" medium="image">
			<media:title type="html">method1</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/12/method2.jpg" medium="image">
			<media:title type="html">method2</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/12/method3.jpg" medium="image">
			<media:title type="html">method3</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/12/method4.jpg" medium="image">
			<media:title type="html">method4</media:title>
		</media:content>
	</item>
		<item>
		<title>Built-in Memory Leak Detection</title>
		<link>http://bprasetio.wordpress.com/2008/10/07/built-in-memory-leak-detection/</link>
		<comments>http://bprasetio.wordpress.com/2008/10/07/built-in-memory-leak-detection/#comments</comments>
		<pubDate>Tue, 07 Oct 2008 03:46:57 +0000</pubDate>
		<dc:creator>bprasetio</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Did You Know]]></category>
		<category><![CDATA[fastmm]]></category>
		<category><![CDATA[memory leak]]></category>
		<category><![CDATA[ReportMemoryLeaksOnShutdown]]></category>

		<guid isPermaLink="false">http://bprasetio.wordpress.com/?p=520</guid>
		<description><![CDATA[Mulai versi Delphi 2006, manajemen memori yang digunakan oleh Delphi, baik untuk IDE maupun aplikasi hasil kompilasi telah menggunakan proyek open-source FastMM. Salah satu kelebihannya adalah tersedianya fasilitas deteksi memory leak.

Sabar, sebelum saya menerangkan penggunaannya, terlebih dahulu akan saya terangkan apa dan bagaimana memory-leak.
Definisi Memory Leak
Memory leak adalah suatu keadan dimana alokasi suatu blok memori [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=520&subd=bprasetio&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Mulai versi Delphi 2006, manajemen memori yang digunakan oleh Delphi, baik untuk IDE maupun aplikasi hasil kompilasi telah menggunakan proyek <em>open-source</em> <strong>FastMM</strong>. Salah satu kelebihannya adalah tersedianya fasilitas <strong>deteksi <em>memory leak</em></strong>.</p>
<p><span id="more-520"></span></p>
<p>Sabar, sebelum saya menerangkan penggunaannya, terlebih dahulu akan saya terangkan apa dan bagaimana <em>memory-leak</em>.</p>
<p><strong>Definisi Memory Leak</strong></p>
<p><em>Memory leak</em> adalah suatu keadan dimana alokasi suatu blok memori tidak dibebaskan oleh pihak yang bertanggung jawab membebaskannya. Normalnya, ketika suatu aplikasi meminta sejumlah alokasi memori, pada suatu kondisi, aplikasi harus membebaskan memori yang telah dialokasikan tersebut sehingga blok memori yang tersedia dapat digunakan oleh aplikasi lainnya. </p>
<p>Nah kondisi apa yang membuat memori harus dibebaskan? Umumnya adalah ketika aplikasi sudah tidak menggunakan blok memori tersebut. Toleransi maksimal pembebasan alokasi memori adalah pada saat aplikasi ditutup. Pembuat aplikasi harus bertanggungjawab membebaskan blok memori yang telah dialokasikan.</p>
<p>Lalu mengapa memori yang digunakan harus dibebaskan? Jika memori yang dialokasikan tidak dibebaskan, maka akan mengurangi ketersedian memori yang dapat digunakan oleh sistem operasi dan aplikasi lainnya, sehingga apabila terdapat dalam jumlah yang besar, dapat mempengaruhi kinerja sistem operasi dan aplikasi lainnya. Blok memori yang tidak dibebaskan hanya bisa di peroleh kembali (di-klaim) dengan menggunakan aplikasi semacam <em>memory cleaner</em> atau melalui <em>restart</em> sistem operasi.</p>
<p><em>Memory leak</em> murni merupakan kesalahan pembuat program yang kurang hati &#8211; hati dalam merancang / mengembangkan programnya.</p>
<p><strong>Bagaimana menghasilkan memori leak?</strong></p>
<p>Sebagai contoh akan saya tunjukkan konsep bagaimana menghasilkan <em>memory leak</em>.</p>
<p>Pertama, buat suatu kontrol tombol, dan berikan <em>event</em> pada saat tombol di klik. Pada <em>event</em> tersebut, deklarasikan sebuah obyek lokal. Selanjutnya pada bagian implementasi <em>event</em>, buat obyek lokal yang telah dideklarasikan. Pembuatan obyek ini secara tidak langsung akan meminta sejumlah alokasi blok memori.</p>
<p>Dengan kondisi di atas, maka akan terjadi <em>memory leak</em> karena obyek yang telah dibuat tersebut tidak pernah dibebaskan. Untuk lebih jelasnya simak lanjutannya mengenai implementasi konsep tersebut dengan Delphi.</p>
<p><strong>Bagaimana Prakteknya ?</strong></p>
<p>Bagaimana prakteknya? coba simak cuplikan kode berikut:</p>
<pre class="brush: delphi;">
procedure TMainForm.btnGenerateObjectClick(Sender: TObject);
var
  AObject : TObject;
begin
  AObject := TObject.Create;
  ShowMessage('An object has been created.');
end;
</pre>
<p>Kode diatas sudah benar? Ya dan Tidak. Ya, karena kode diatas berhasil dikompilasi. Tidak, karena ketika kode tersebut dijalankan, akan menghasilkan <em>memory leak</em>.</p>
<p>Pada baris kelima, sebuah obyek lokal dari kelas TObject dialokasikan. Namun sampai dengan akhir prosedur, alokasi memori terhadap obyek tersebut tidak pernah dibebaskan, yang tentunya menghasilkan <em>memory leak</em>.</p>
<p><strong>Deteksi Memory Leak Terintegrasi</strong></p>
<p><strong>FastMM</strong>, sebagai <strong>default memory manager</strong> dapat <strong>melaporkan</strong> adanya penggunaan memori yang tidak dibebaskan. Secara default fasilitas ini <strong>tidak diaktifkan</strong>. Dengan hanya menambahkan satu baris kode sumber saja, kita dapat mengaktifkan fasilitas ini, yaitu dengan memberikan nilai <strong>True</strong> pada variabel global <strong>ReportMemoryLeaksOnShutdown</strong>. </p>
<p>Laporan<em> memory leak</em> akan disajikan ketika aplikasi ditutup. Laporan yang dihasilkan adalah berupa rincian besaran blok memori yang dialokasikan beserta jumlah frekuensi alokasinya, misalnya  TObject dialokasikan sebanyak 5 kali. Jika tidak terdeteksi <em>memory leak</em>, maka laporan tidak disajikan. Memang jika dibandingkan dengan produk komersial seperti <em>EurekaLog</em>, fasilitas ini masih kalah, tapi setidaknya kita sudah mempunyai fasilitas ini tanpa harus memasang komponen / kelas tambahan.</p>
<p><strong>Bagaimana dan Dimana mengaktifkannya ?</strong></p>
<p>Karena sifatnya sebagai <strong>variabel global</strong>, maka dapat dapat dipanggil dimana saja, namun untuk keseragaman dan pencegahan duplikasi, pengaturan dapat diletakkan pada file proyek seperti yang dicontohkan pada potongan kode berikut:</p>
<pre class="brush: delphi;">
program BuiltInMemoryLeakDetection;

uses
  Forms,
  MainUnit in 'MainUnit.pas' {MainForm};

{$R *.res}

begin
  ReportMemoryLeaksOnShutdown := True;
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;
end.
</pre>
<p>Dan jika aplikasi dijalankan, dengan menekan tombol sebanyak 5 kali, maka ketika aplikasi ditutup, akan tampak laporan <em>memory leak</em> seperti gambar berikut:</p>
<div id="attachment_521" class="wp-caption alignnone" style="width: 474px"><a href="http://bprasetio.files.wordpress.com/2008/10/memoryleakreport.jpg"><img src="http://bprasetio.files.wordpress.com/2008/10/memoryleakreport.jpg?w=464&#038;h=133" alt="Deteksi Memory Leak" title="memoryleakreport" width="464" height="133" class="size-full wp-image-521" /></a><p class="wp-caption-text">Deteksi Memory Leak</p></div>
<p>Semoga bermanfaat.</p>
Posted in Delphi, Did You Know  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bprasetio.wordpress.com/520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bprasetio.wordpress.com/520/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bprasetio.wordpress.com/520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bprasetio.wordpress.com/520/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bprasetio.wordpress.com/520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bprasetio.wordpress.com/520/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bprasetio.wordpress.com/520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bprasetio.wordpress.com/520/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bprasetio.wordpress.com/520/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bprasetio.wordpress.com/520/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=520&subd=bprasetio&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bprasetio.wordpress.com/2008/10/07/built-in-memory-leak-detection/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">bprasetio</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/10/memoryleakreport.jpg" medium="image">
			<media:title type="html">memoryleakreport</media:title>
		</media:content>
	</item>
		<item>
		<title>Form Load Profiler: High Precision Timer</title>
		<link>http://bprasetio.wordpress.com/2008/10/06/form-load-profiler-high-precision-timer/</link>
		<comments>http://bprasetio.wordpress.com/2008/10/06/form-load-profiler-high-precision-timer/#comments</comments>
		<pubDate>Sun, 05 Oct 2008 22:59:09 +0000</pubDate>
		<dc:creator>bprasetio</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Did You Know]]></category>
		<category><![CDATA[form load time]]></category>
		<category><![CDATA[high precision timer]]></category>
		<category><![CDATA[high resolution timer]]></category>
		<category><![CDATA[interposer class]]></category>
		<category><![CDATA[profiler]]></category>
		<category><![CDATA[QueryPerformanceCounter]]></category>
		<category><![CDATA[QueryPerformanceFrequency]]></category>

		<guid isPermaLink="false">http://bprasetio.wordpress.com/?p=516</guid>
		<description><![CDATA[Pada beberapa kali kesempatan, saya menyajikan bagaimana mengukur waktu tayang (load-time) suatu form dari form tersebut di buat hingga benar &#8211; benar tampil dan siap digunakan. Beberapa variasi sudah saya sajikan, mulai dari pengukuran form tunggal hingga banyak form dengan menggunakan teknik interposer class maupun class helper. Ketiga variasi artikel tersebut menggunakan metode pengukuran waktu [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=516&subd=bprasetio&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Pada beberapa kali kesempatan, saya menyajikan bagaimana mengukur waktu tayang (<em>load-time</em>) suatu form dari form tersebut di buat hingga benar &#8211; benar tampil dan siap digunakan. Beberapa variasi sudah saya sajikan, mulai dari pengukuran form tunggal hingga banyak form dengan menggunakan teknik <a href="http://bprasetio.wordpress.com/2008/09/15/form-load-profiler-multiple-form/">interposer class</a> maupun<a href="http://bprasetio.wordpress.com/2008/09/26/form-load-profiler-multi-form-class-helper/"> class helper</a>. Ketiga variasi artikel tersebut menggunakan metode pengukuran waktu yang sama, yaitu menggunakan fungsi <em>GetTickCount</em>. Fungsi <em>GetTickCount</em> memiliki ketelitian hingga hitungan <strong>mili-detik</strong> (ms). Untuk kebutuhan secara umum, <em>GetTickCount</em> sudah mencukupi, namun adakalanya pengukuran yang dilakukan membutuhkan ketelitian yang lebih, misalnya dalam nano-detik. Disinilah <em>GetTickCount</em> <strong>tidak bisa</strong> memenuhinya.</p>
<p><span id="more-516"></span></p>
<p>Windows menyediakan 2 (dua) API yang berkaitan dengan pengukuran dengan ketelitian tinggi, yaitu <strong>QueryPerformanceCounter</strong> dan <strong>QueryPerformanceFrequency</strong>. Kedua fungsi ini digunakan saling melengkapi. </p>
<blockquote><p>
BOOL QueryPerformanceCounter(<br />
  LARGE_INTEGER *lpPerformanceCount 	// address of current counter value<br />
);	</p>
<p>Parameters</p>
<p>lpPerformanceCount</p>
<p>Points to a variable that the function sets, in counts, to the current performance-counter value. If the installed hardware does not support a high-resolution performance counter, this parameter can be to zero. </p>
<p>Return Values</p>
<p>If the installed hardware supports a high-resolution performance counter, the return value is nonzero.<br />
If the installed hardware does not support a high-resolution performance counter, the return value is zero.
</p></blockquote>
<blockquote><p>
BOOL QueryPerformanceFrequency(<br />
  LARGE_INTEGER *lpFrequency 	// address of current frequency<br />
);	</p>
<p>Parameters</p>
<p>lpFrequency</p>
<p>Points to a variable that the function sets, in counts per second, to the current performance-counter frequency. If the installed hardware does not support a high-resolution performance counter, this parameter can be to zero. </p>
<p>Return Values</p>
<p>If the installed hardware supports a high-resolution performance counter, the return value is nonzero.<br />
If the installed hardware does not support a high-resolution performance counter, the return value is zero.
</p></blockquote>
<p>Dari kutipan diatas, sudah jelas bahwa <em>QueryPerformanceCounter</em> digunakan untuk menampung nilai <strong>pencacah</strong> / penghitung pada saat API tersebut dipanggil, sedangkan <em>QueryPerformanceFrequency</em> digunakan untuk mendapatkan besaran <strong>frekuensi</strong> dari pencacah tersebut, berapa nilai cacah yang dihasilkan dalam 1 (satu) detik.</p>
<p>Sehingga untuk mendapatkan nilai pengukuran adalah dengan menghitung nilai cacah setelah pengukuran dikurangi dengan nilai cacah sebelum pengukuran. Nilai tersebut kemudian dibagi dengan frekuensi. Nilai ukur yang didapat adalah dalam satuan detik, untuk mengkonversi dalam satuan lain tinggal disesuaikan. Misalnya untuk dihitung dalam satuan mili-detik maka nilai tersebut dikalikan dengan 1000.</p>
<pre class="brush: delphi;">
  FElapsedTime := (FEnd - FStart) / FFrequency * 1000;
</pre>
<p><strong>Integrasi ke Kode</strong></p>
<p>Sekarang saatnya melakukan konversi dari penggunaan API <em>GetTickCount</em> ke <em>QueryPerformanceCounter</em> dan <em>QueryPerformanceFrequency</em>. Disini saya menggunakan kode sumber yang menggunakan teknik <a href="http://bprasetio.wordpress.com/2008/09/15/form-load-profiler-multiple-form/">interposer class</a>. Untuk penggunakan teknik <a href="http://bprasetio.wordpress.com/2008/09/26/form-load-profiler-multi-form-class-helper/">class helper</a> silahkan disesuaikan sendiri sebagai latihan.</p>
<p>Pertama, deklarasi variabel <em>FStart</em> dan <em>FEnd</em> harus diubah tipe datanya dari <em>Cardinal</em> menjadi <strong>Int64</strong>. Mengapa Int64? Karena nilai yang ditampung adalah sangat besar mengingat ketelitian presisi yang dihasilkan sangat tinggi, sehingga dibutuhkan tipe data yang lebih besar dari Cardinal (0..4294967295), yaitu Int64 atau LargeInt (-2^63..2^63-1). Kemudian tambahkan variabel untuk menyimpan nilai frekuensi dari pencacah tersebut, yaitu <em>FFrequency</em>, dengan tipe data <em>Int64</em>. Selanjutnya tambahkan variabel untuk menampung nilai hasil pengukuran, yaitu <em>FElapsedTime</em>, dengan tipe data <em>Double</em>.</p>
<pre class="brush: delphi;">
  protected
    FStart, FEnd : Int64;
    FFrequency   : Int64;
    FElapsedTime : Double;
</pre>
<p>Perubahan kedua adalah pada <em>constructor Create</em>. Disini perlu dilakukan pemanggilan fungsi <em>QueryPerformanceFrequency</em> untuk mengetahui frekuensi nilai pencacah.</p>
<pre class="brush: delphi;">
constructor TForm.Create(AOwner: TComponent);
begin
  QueryPerformanceFrequency(FFrequency);
  QueryPerformanceCounter(FStart);
  inherited;
end;
</pre>
<p>Ketiga, modifikasi <em>method Activate</em>, dan menambahkan perhitungan waktu ukur dalam 1 (satu) mili-detik.</p>
<pre class="brush: delphi;">
procedure TForm.Activate;
begin
  inherited;
  QueryPerformanceCounter(FEnd);
  FElapsedTime := (FEnd - FStart) / FFrequency * 1000;
end;
</pre>
<p>Modifikasi keempat adalah modifikasi pada unit &#8211; unit lain yang menggunakan unit <em>MultipleInterposerClassHP.pas</em>. Bagian yang diubah adalah cara penyampaian pesan informasi besarnya waktu tayang. Jika sebelumnya menggunakan fungsi <em>IntToStr</em> karena waktu ukur berbasis pada tipe data Cardinal, maka sekarang menjadi <strong>FloatToStr</strong> karena waktu ukur, yaitu variabel <em>FElapsedTime</em> bertipe data <em>Double</em>. Sebagai contoh unit yang dimodifikasi adalah unit <em>MultipleMainFormUnit.pas</em>.</p>
<pre class="brush: delphi;">
procedure TMainForm.btnShowResultClick(Sender: TObject);
begin
  lblLoadTime.Caption := ' Form Load Time: ' + FloatToStr(FElapsedTime) + ' ms';
  btnShowResult.Enabled := False;
end;
</pre>
<p>Sehingga rangkaian kode <em>MultipleInterposerClassHP</em> menjadi sebagai berikut:</p>
<pre class="brush: delphi;">
{-----------------------------------------------------------------------------
 The contents of this file are subject to the Mozilla Public License
 Version 1.1 (the &quot;License&quot;); you may not use this file except in compliance
 with the License. You may obtain a copy of the License at
 http://www.mozilla.org/MPL/MPL-1.1.html

 Software distributed under the License is distributed on an &quot;AS IS&quot; basis,
 WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
 the specific language governing rights and limitations under the License.

 The Original Code is: MultipleInterposerClassHP.pas, released on 2008-09-30

 The Initial Developer of the Original Code is Bayu Prasetio
 Portions created by Bayu Prasetio are Copyright (C) 2008 Bayu Prasetio.
 All Rights Reserved.
 -----------------------------------------------------------------------------}
unit MultipleInterposerClassHP;

interface

uses
  Classes, Forms;

type
  TForm = class(Forms.TForm)
  protected
    FStart, FEnd : Int64;
    FFrequency   : Int64;
    FElapsedTime : Double;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    procedure Activate; override;
  end;

implementation

{ TForm }

uses
  Windows;

procedure TForm.Activate;
begin
  inherited;
  QueryPerformanceCounter(FEnd);
  FElapsedTime := (FEnd - FStart) / FFrequency * 1000;
end;

constructor TForm.Create(AOwner: TComponent);
begin
  QueryPerformanceFrequency(FFrequency);
  QueryPerformanceCounter(FStart);
  inherited;
end;

end.
</pre>
<p>Dan sebagai contoh <em>MultipleMainFormUnit.pas</em> menjadi:</p>
<pre class="brush: delphi;">
{-----------------------------------------------------------------------------
 The contents of this file are subject to the Mozilla Public License
 Version 1.1 (the &quot;License&quot;); you may not use this file except in compliance
 with the License. You may obtain a copy of the License at
 http://www.mozilla.org/MPL/MPL-1.1.html

 Software distributed under the License is distributed on an &quot;AS IS&quot; basis,
 WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
 the specific language governing rights and limitations under the License.

 The Original Code is: MultipleMainFormUnit.pas, released on 2008-09-30

 The Initial Developer of the Original Code is Bayu Prasetio
 Portions created by Bayu Prasetio are Copyright (C) 2008 Bayu Prasetio.
 All Rights Reserved.
 -----------------------------------------------------------------------------}
unit MultipleMainFormUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, MultipleInterposerClassHP;

type
  TMainForm = class(TForm)
    btnShowResult: TButton;
    mmoLegend: TMemo;
    stbMain: TStatusBar;
    btnLoadSecondary: TButton;
    lblLoadTime: TLabel;
    btnLoadAnotherForm: TButton;
    procedure btnShowResultClick(Sender: TObject);
    procedure btnLoadSecondaryClick(Sender: TObject);
    procedure btnLoadAnotherFormClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

{ TSingleForm }

uses
  MultipleSecondaryFormUnit, MultipleAnotherFormUnit;

procedure TMainForm.btnLoadAnotherFormClick(Sender: TObject);
begin
  AnotherForm := TAnotherForm.Create(nil);
  AnotherForm.ShowModal;
  AnotherForm.Free;
end;

procedure TMainForm.btnLoadSecondaryClick(Sender: TObject);
begin
  SecondaryForm := TSecondaryForm.Create(nil);
  SecondaryForm.ShowModal;
  SecondaryForm.Free;
end;

procedure TMainForm.btnShowResultClick(Sender: TObject);
begin
  lblLoadTime.Caption := ' Form Load Time: ' + FloatToStr(FElapsedTime) + ' ms';
  btnShowResult.Enabled := False;
end;

end.
</pre>
<p>Selengkapnya mengenai demo ini dapat di-unduh di sini: <a href="http://home.bprasetio.or.id/files/FormLoadProfiler-HighPrecision-InterposerClass.7z">Source Code</a>.</p>
Posted in Delphi, Did You Know  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bprasetio.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bprasetio.wordpress.com/516/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bprasetio.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bprasetio.wordpress.com/516/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bprasetio.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bprasetio.wordpress.com/516/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bprasetio.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bprasetio.wordpress.com/516/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bprasetio.wordpress.com/516/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bprasetio.wordpress.com/516/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=516&subd=bprasetio&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bprasetio.wordpress.com/2008/10/06/form-load-profiler-high-precision-timer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">bprasetio</media:title>
		</media:content>
	</item>
		<item>
		<title>Form Load Profiler: Multi Form: Class Helper</title>
		<link>http://bprasetio.wordpress.com/2008/09/26/form-load-profiler-multi-form-class-helper/</link>
		<comments>http://bprasetio.wordpress.com/2008/09/26/form-load-profiler-multi-form-class-helper/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 17:56:27 +0000</pubDate>
		<dc:creator>bprasetio</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Did You Know]]></category>
		<category><![CDATA[class helper]]></category>
		<category><![CDATA[form load time]]></category>
		<category><![CDATA[GetTickCount]]></category>
		<category><![CDATA[profiler]]></category>

		<guid isPermaLink="false">http://bprasetio.wordpress.com/?p=511</guid>
		<description><![CDATA[Pada kesempatan yang lalu, saya sajikan artikel mengenai bagaimana mengukur waktu tayang (load-time) suatu form dari form tersebut di buat hingga benar &#8211; benar tampil dan siap digunakan. Sudah saya sajikan metode untuk form tunggal maupun multi form. Pada teknik multi form, saya menggunakan teknik interposser class. Selain teknik tersebut, ada alternatif lain yaitu dengan [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=511&subd=bprasetio&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Pada kesempatan yang lalu, saya sajikan artikel mengenai bagaimana mengukur waktu tayang (<em>load-time</em>) suatu form dari form tersebut di buat hingga benar &#8211; benar tampil dan siap digunakan. Sudah saya sajikan metode untuk form tunggal maupun multi form. Pada teknik multi form, saya menggunakan teknik <em>interposser class</em>. Selain teknik tersebut, ada alternatif lain yaitu dengan menggunakan <em>class helper</em> yang akan dibahas pada kesempatan ini.</p>
<p><span id="more-511"></span></p>
<p>Bagi pembaca yang mengikuti blog saya dari awal, tentunya ingat bahwa saya sudah beberapa kali menyajikan artikel <a href="http://bprasetio.wordpress.com/category/did-you-know/">Did You Know</a> yang membahas mengenai penggunaan <em>Class Helper</em>. Dan pada kesempatan ini saya tidak akan membahas apa dan bagaimana <em>class helper</em> itu sendiri. Anda dapat mencarinya pada dokumentasi yang disediakan oleh <em><a href="http://www.codegear.com">CodeGear</a></em> atau <em>googling</em>.</p>
<p>Nah, sekarang bagaimana menerapkan <em>class helper</em> dalam kasus ini.</p>
<p>Pertama, buat <em>helper</em> untuk kelas TForm.</p>
<pre class="brush: delphi;">
  TGlobalFormHelper = class helper for TForm
  end;
</pre>
<p>Kemudian untuk mendeklarasikan variabel <em>FStart</em> dan FEnd, tidak bisa dilakukan secara sembarangan mengingat <em>class helper</em> memberikan batasan tidak dapat menambah <em>instance data</em>, namun dapat menambah <em>class fields</em>. Nah untuk itu kita memanfaatkan <strong>class var</strong>, sehingga deklarasi variabelnya menjadi:</p>
<pre class="brush: delphi;">
  TGlobalFormHelper = class helper for TForm
    class var
      FStart, FEnd : Cardinal;
  end;
</pre>
<p>langkah selanjutnya adalah mendeklarasikan <em>constructor Create</em>, namun kali ini deklarasinya sedikit berbeda. Jika pada <em>interposer class</em>, kita harus meng-<em>override constructor Create</em>, maka pada <em>class helper</em> tidak perlu. Secara umum, isi dari <em>constructor</em> sebagai berikut:</p>
<pre class="brush: delphi;">
  TGlobalFormHelper = class helper for TForm
    class var
      FStart, FEnd : Cardinal;
  public
    constructor Create(AOwner: TComponent);
  end;
//
// ....
//
constructor TGlobalFormHelper.Create(AOwner: TComponent);
begin
  FStart := GetTickCount;
  inherited;
end;
</pre>
<p>Sampai di sini kita sudah mulai menghitung pengukuran, langkah berikutnya tentu saja adalah meletakkan rutin akhir pengukuran pada <em>method Activate</em>. Namun sayang sekali, dalam <em>class helper</em> ini, kita tidak dapat mendeklarasikan dan atau meng-<em>override method Activate</em> karena <strong>sudah dideklarasikan</strong>. Sebagai alternatif solusinya, kita akan <strong>membelokkan <em>event onActivate</em></strong> untuk menjalankan rutin pengukuran. Untuk itu kita harus menyimpan <em>event onActivate</em> yang sebenarnya. Nah di dalam rutin pengukuran tersebut kita jalankan <em>event onActivate</em> yang sebenarnya sebelum mengakhiri perhitungan. Selengkapnya menjadi:</p>
<pre class="brush: delphi;">
  TGlobalFormHelper = class helper for TForm
    class var
      FStart, FEnd : Cardinal;
      FOnActivateTemporary : TNotifyEvent;
  public
    constructor Create(AOwner: TComponent);
    procedure CalculateLoadTime(Sender: TObject);
  end;
//
// ....
//
procedure TGlobalFormHelper.CalculateLoadTime(Sender: TObject);
begin
  if Assigned(FOnActivateTemporary) then FOnActivateTemporary(Sender);
  FEnd := GetTickCount;
end;

constructor TGlobalFormHelper.Create(AOwner: TComponent);
begin
  FStart := GetTickCount;
  inherited;

  Sleep(50);
  FOnActivateTemporary := Self.OnActivate;
  Self.OnActivate := CalculateLoadTime;
end;
</pre>
<p>Ok, sampai disini <em>class helper</em> sudah beres, sekarang bagaimana dengan kelas utama nya? Cukup dengan menambahkan <em>constructor Create</em> dan tambahkan <em>directive override</em>. Di dalam <em>constructor</em> tersebut, tambahkan kode <strong>inherited</strong> untuk memanggil <em>constructor Create</em> yang sebenarnya, yaitu yang dideklarasikan pada <em>class helper</em>.</p>
<pre class="brush: delphi;">
  TMainForm = class(TForm)
//
// ...
//
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
  end;
//
// ...
//
constructor TMainForm.Create(AOwner: TComponent);
begin
  inherited;
end;
</pre>
<p>Langkah selanjutnya adalah bagaimana memanfaatkan <em>class helper</em> tersebut pada form. Untuk form utama, tidak ada masalah, tidak ada tambahan apapun karena <em>class helper</em> dideklarasikan dalam unit yang sama.</p>
<pre class="brush: delphi;">
{-----------------------------------------------------------------------------
 The contents of this file are subject to the Mozilla Public License
 Version 1.1 (the &quot;License&quot;); you may not use this file except in compliance
 with the License. You may obtain a copy of the License at
 http://www.mozilla.org/MPL/MPL-1.1.html

 Software distributed under the License is distributed on an &quot;AS IS&quot; basis,
 WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
 the specific language governing rights and limitations under the License.

 The Original Code is: MultipleMainFormUnit.pas, released on 2008-09-25

 The Initial Developer of the Original Code is Bayu Prasetio
 Portions created by Bayu Prasetio are Copyright (C) 2008 Bayu Prasetio.
 All Rights Reserved.
 -----------------------------------------------------------------------------}
unit MultipleMainFormUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TMainForm = class(TForm)
    btnShowResult: TButton;
    mmoLegend: TMemo;
    stbMain: TStatusBar;
    btnLoadSecondary: TButton;
    lblLoadTime: TLabel;
    btnLoadAnotherForm: TButton;
    procedure btnShowResultClick(Sender: TObject);
    procedure btnLoadSecondaryClick(Sender: TObject);
    procedure btnLoadAnotherFormClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
  end;

  TGlobalFormHelper = class helper for TForm
    class var
      FStart, FEnd : Cardinal;
      FOnActivateTemporary : TNotifyEvent;
  public
    constructor Create(AOwner: TComponent);
    procedure CalculateLoadTime(Sender: TObject);
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

uses
  MultipleSecondaryFormUnit, MultipleAnotherFormUnit;

procedure TMainForm.btnLoadAnotherFormClick(Sender: TObject);
begin
  AnotherForm := TAnotherForm.Create(nil);
  AnotherForm.ShowModal;
  AnotherForm.Free;
end;

procedure TMainForm.btnLoadSecondaryClick(Sender: TObject);
begin
  SecondaryForm := TSecondaryForm.Create(nil);
  SecondaryForm.ShowModal;
  SecondaryForm.Free;
end;

procedure TMainForm.btnShowResultClick(Sender: TObject);
begin
  lblLoadTime.Caption := ' Form Load Time: ' + IntToStr(FEnd - FStart) + ' ms';
  btnShowResult.Enabled := False;
end;

constructor TMainForm.Create(AOwner: TComponent);
begin
  inherited;
end;

procedure TGlobalFormHelper.CalculateLoadTime(Sender: TObject);
begin
  if Assigned(FOnActivateTemporary) then FOnActivateTemporary(Sender);
  FEnd := GetTickCount;
end;

constructor TGlobalFormHelper.Create(AOwner: TComponent);
begin
  FStart := GetTickCount;
  inherited;

  Sleep(50);
  FOnActivateTemporary := Self.OnActivate;
  Self.OnActivate := CalculateLoadTime;
end;

end.
</pre>
<p>Nah untuk form yang lainya, deklarasi mirip dengan menggunakan <em>interposer class</em>, yaitu cukup dengan menambahkan pada klausul <em>uses</em> dengan nama unit dimana <em>class helper</em> dideklarasikan, seperti contoh kode berikut:</p>
<pre class="brush: delphi;">
{-----------------------------------------------------------------------------
 The contents of this file are subject to the Mozilla Public License
 Version 1.1 (the &quot;License&quot;); you may not use this file except in compliance
 with the License. You may obtain a copy of the License at
 http://www.mozilla.org/MPL/MPL-1.1.html

 Software distributed under the License is distributed on an &quot;AS IS&quot; basis,
 WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
 the specific language governing rights and limitations under the License.

 The Original Code is: MultipleAnotherFormUnit.pas, released on 2008-09-25

 The Initial Developer of the Original Code is Bayu Prasetio
 Portions created by Bayu Prasetio are Copyright (C) 2008 Bayu Prasetio.
 All Rights Reserved.
 -----------------------------------------------------------------------------}
unit MultipleAnotherFormUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TAnotherForm = class(TForm)
    btnShowResult: TButton;
    procedure btnShowResultClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  AnotherForm: TAnotherForm;

implementation

{$R *.dfm}

uses
  MultipleMainFormUnit;

procedure TAnotherForm.btnShowResultClick(Sender: TObject);
begin
  ShowMessage('Load Time : ' + IntToStr(FEnd - FStart));
end;

procedure TAnotherForm.FormCreate(Sender: TObject);
begin
  Sleep(200);
end;

end.
</pre>
<p>Nah selesai&#8230; </p>
<p>Selengkapnya mengenai demo <em>class helper</em> dapat di-unduh di sini: <a href="http://home.bprasetio.or.id/files/FormLoadProfiler-ClassHelper.7z">Source Code</a>.</p>
<p>Jika Anda sudah lupa dengan <em>form load profiler</em> untuk form tunggal, silahkan disimak di sini: <a href="http://bprasetio.wordpress.com/2008/09/01/form-load-profiler-single-form/">Form Load Profiler: Single Form</a></p>
<p>Jika Anda sudah lupa dengan <em>form load profiler</em> dengan menggunakan teknik <em>interposer class</em>, silahkan disimak di sini: <a href="http://bprasetio.wordpress.com/2008/09/15/form-load-profiler-multiple-form/">Form Load Profiler: Multiple Form: Interposer Class</a></p>
<p>Lalu mana yang terbaik antara <em>interposer class</em> dan <em>class helper</em> ? </p>
<p>Dilihat dari faktor kompatibilitas <em>compiler</em> <a href="http://www.codegear.com/products/delphi/win32">Delphi</a>, jelas <em>interposer class</em> karena <em>class helper</em> baru diperkenalkan mulai Delphi 2005 (CMIIW).</p>
<p>Di sisi lain, <a href="http://www.codegear.com">CodeGear</a> dalam dokumentasinya menyebut secara khusus <em>class helper</em>: </p>
<blockquote><p>
Class helpers provide a way to extend a class, but they should not be viewed as a design tool to be used when developing new code. They should be used solely for their intended purpose, which is language and platform RTL binding.
</p></blockquote>
<p> Namun menurut saya tergantung kebutuhan dan pemahaman Anda mengenai kedua teknik tersebut.</p>
<p>Semoga bermanfaat.</p>
Posted in Delphi, Did You Know  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bprasetio.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bprasetio.wordpress.com/511/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bprasetio.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bprasetio.wordpress.com/511/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bprasetio.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bprasetio.wordpress.com/511/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bprasetio.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bprasetio.wordpress.com/511/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bprasetio.wordpress.com/511/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bprasetio.wordpress.com/511/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=511&subd=bprasetio&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bprasetio.wordpress.com/2008/09/26/form-load-profiler-multi-form-class-helper/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">bprasetio</media:title>
		</media:content>
	</item>
		<item>
		<title>Form Load Profiler: Multiple Form</title>
		<link>http://bprasetio.wordpress.com/2008/09/15/form-load-profiler-multiple-form/</link>
		<comments>http://bprasetio.wordpress.com/2008/09/15/form-load-profiler-multiple-form/#comments</comments>
		<pubDate>Mon, 15 Sep 2008 07:32:31 +0000</pubDate>
		<dc:creator>bprasetio</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Did You Know]]></category>
		<category><![CDATA[form load time]]></category>
		<category><![CDATA[GetTickCount]]></category>
		<category><![CDATA[interposer class]]></category>
		<category><![CDATA[profiler]]></category>

		<guid isPermaLink="false">http://bprasetio.wordpress.com/?p=504</guid>
		<description><![CDATA[Pada kesempatan yang lalu, saya sajikan artikel mengenai bagaimana mengukur waktu tayang (load-time) suatu form dari form tersebut di buat hingga benar &#8211; benar tampil dan siap digunakan. Pada artikel tersebut, kode yang saya sajikan hanya berlaku untuk satu form, untuk form yang bersangkutan saja. Nah pada kesempatan ini akan saya sajikan teknik bagaimana mengimplementasikan [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=504&subd=bprasetio&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Pada kesempatan yang <a href="http://bprasetio.wordpress.com/2008/09/01/form-load-profiler-single-form/">lalu</a>, saya sajikan artikel mengenai bagaimana mengukur waktu tayang (<em>load-time</em>) suatu form dari form tersebut di buat hingga benar &#8211; benar tampil dan siap digunakan. Pada artikel tersebut, kode yang saya sajikan hanya berlaku untuk satu form, untuk form yang bersangkutan saja. Nah pada kesempatan ini akan saya sajikan teknik bagaimana mengimplementasikan kode pengukur (meng-<em>override</em> <em>constructor Create</em> dan <em>method Activate</em>) tanpa harus menuliskan kode tersebut secara berulang pada setiap form yang diinginkan.</p>
<p><span id="more-504"></span></p>
<p>Disini saya akan menggunakan teknik <em>interposer class</em>. Tapi sebelum melangkah lebih jauh, ada baiknya kita simak lebih dahulu mengenai definisi interposer class yang saya cuplik dari<br />
<a href="http://blog.marcocantu.com/blog/handbook_note_67.html">Handbook Note 67/113: Interposer Classes</a></p>
<blockquote><p>
An interposer class is a class with the same name of the class it wants to change (using inheritance). By adding its unit after the unit of its base class in a uses statement, a unit will use the modified version of the class rather than the original. Interposer classes are not a terribly neat technique, rather a hack. But they can be very handy, indeed!
</p></blockquote>
<p><strong>Nah, sekarang bagaimana membuat interposer class tersebut ?</strong></p>
<p>Pertama, buat kelas <em>TForm</em> baru yang merupakan turunan dari kelas TForm yang asli, yaitu kelas yang dideklarasikan pada <em>unit Forms</em>. Pendeklarasian dari kelas induk harus menyertakan unit asal dimana kelas TForm yang sebenarnya berasal, yaitu <em>Forms.TForm</em>.</p>
<pre>
  TForm = class(Forms.TForm)
</pre>
<p>Kedua, kita tambahkan variable <em>FStart</em> dan <em>FEnd</em>. Untuk lingkup aksesnya, bisa dipilih apakah <em>Private</em>, <em>Protected</em> atau <em>Public</em>. Karena kita ingin mengakses variabel FStart dan FEnd, maka lingkup aksesnya minimal adalah <em>protected</em>. Anda bisa saja membuatnya sebagai private, namun nantinya harus menambahkan <em>property</em> untuk mengakses kedua variabel tersebut. </p>
<pre>
  protected
    FStart, FEnd : Cardinal;
</pre>
<p>Ketiga, tidak lupa deklarasikan <em>constructor Create</em> dan method Activate yang akan di-override. </p>
<pre>
  public
    constructor Create(AOwner: TComponent); override;
    procedure Activate; override;
</pre>
<p>Sehingga definisi kelas interposer menjadi:</p>
<pre class="brush: delphi;">
type
  TForm = class(Forms.TForm)
  protected
    FStart, FEnd : Cardinal;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    procedure Activate; override;
  end;
</pre>
<p>Rangkaian kode selanjutnya sama dengan pada kode untuk form tunggal pada artikel sebelumnya, sehingga kode lengkapnya menjadi sebagai berikut:</p>
<pre class="brush: delphi;">
{-----------------------------------------------------------------------------
 The contents of this file are subject to the Mozilla Public License
 Version 1.1 (the &quot;License&quot;); you may not use this file except in compliance
 with the License. You may obtain a copy of the License at
 http://www.mozilla.org/MPL/MPL-1.1.html

 Software distributed under the License is distributed on an &quot;AS IS&quot; basis,
 WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
 the specific language governing rights and limitations under the License.

 The Original Code is: MultipleInterposerClass.pas, released on 2008-09-15

 The Initial Developer of the Original Code is Bayu Prasetio
 Portions created by Bayu Prasetio are Copyright (C) 2008 Bayu Prasetio.
 All Rights Reserved.
 -----------------------------------------------------------------------------}
unit MultipleInterposerClass;

interface

uses
  Classes, Forms;

type
  TForm = class(Forms.TForm)
  protected
    FStart, FEnd : Cardinal;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    procedure Activate; override;
  end;

implementation

{ TForm }

uses
  Windows;

procedure TForm.Activate;
begin
  inherited;
  FEnd := GetTickCount;
end;

constructor TForm.Create(AOwner: TComponent);
begin
  FStart := GetTickCount;
  inherited;
end;

end.
</pre>
<p><strong>Lalu bagaimana menggunakan interposer class tersebut ?</strong></p>
<p>Cukup mudah, yaitu tambahkan unit dimana interposer class tersebut dideklarasikan pada bagian klausul <em>uses</em>. Yang perlu diperhatikan adalah, urutan deklarasi unit tersebut harus terletak <strong>setelah</strong> unit Forms karena jika dideklarasikan sebelum unit Forms, maka yang akan dijadikan sebagai rujukan adalah kelas TForm yang dideklarasikan pada unit Forms, bukan kelas TForm dari unit MultipleInterposerClass. Dan setelah deklarasi ditambahkan, selesai sudah. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Berikut contoh bagaimana menggunakan interposer class:</p>
<pre class="brush: delphi;">
{-----------------------------------------------------------------------------
 The contents of this file are subject to the Mozilla Public License
 Version 1.1 (the &quot;License&quot;); you may not use this file except in compliance
 with the License. You may obtain a copy of the License at
 http://www.mozilla.org/MPL/MPL-1.1.html

 Software distributed under the License is distributed on an &quot;AS IS&quot; basis,
 WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
 the specific language governing rights and limitations under the License.

 The Original Code is: MultipleMainFormUnit.pas, released on 2008-09-15

 The Initial Developer of the Original Code is Bayu Prasetio
 Portions created by Bayu Prasetio are Copyright (C) 2008 Bayu Prasetio.
 All Rights Reserved.
 -----------------------------------------------------------------------------}
unit MultipleMainFormUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, MultipleInterposerClass;

type
  TMainForm = class(TForm)
    btnShowResult: TButton;
    mmoLegend: TMemo;
    stbMain: TStatusBar;
    btnLoadSecondary: TButton;
    lblLoadTime: TLabel;
    btnLoadAnotherForm: TButton;
    procedure btnShowResultClick(Sender: TObject);
    procedure btnLoadSecondaryClick(Sender: TObject);
    procedure btnLoadAnotherFormClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

{ TSingleForm }

uses
  MultipleSecondaryFormUnit, MultipleAnotherFormUnit;

procedure TMainForm.btnLoadAnotherFormClick(Sender: TObject);
begin
  AnotherForm := TAnotherForm.Create(nil);
  AnotherForm.ShowModal;
  AnotherForm.Free;
end;

procedure TMainForm.btnLoadSecondaryClick(Sender: TObject);
begin
  SecondaryForm := TSecondaryForm.Create(nil);
  SecondaryForm.ShowModal;
  SecondaryForm.Free;
end;

procedure TMainForm.btnShowResultClick(Sender: TObject);
begin
  lblLoadTime.Caption := ' Form Load Time: ' + IntToStr(FEnd - FStart) + ' ms';
  btnShowResult.Enabled := False;
end;

end.
</pre>
<p>Sedangkan cuplikan ketika aplikasi dioperasikan adalah sebagai berikut:<br />
<div id="attachment_505" class="wp-caption alignnone" style="width: 433px"><a href="http://bprasetio.files.wordpress.com/2008/09/formloadprofiler-multiform-interposer.jpg"><img src="http://bprasetio.files.wordpress.com/2008/09/formloadprofiler-multiform-interposer.jpg?w=423&#038;h=243" alt="Multiple Form" title="formloadprofiler-multiform-interposer" width="423" height="243" class="size-full wp-image-505" /></a><p class="wp-caption-text">Form Load Time Profiler: Multiple Form</p></div></p>
<p>Selengkapnya mengenai demo interposer class dapat di-download di sini: <a href="http://home.bprasetio.or.id/files/FormLoadProfiler-InterposerClass.7z">Source Code</a></p>
<p>Pada kesempatan selanjutnya, akan saya bahas alternatif selain menggunakan interposer class.<br />
Jika Anda sudah lupa dengan form load profiler untuk form tunggal, silahkan disimak di sini: <a href="http://bprasetio.wordpress.com/2008/09/01/form-load-profiler-single-form/">Form Load Profiler: Single Form</a></p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/bprasetio.wordpress.com/504/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/bprasetio.wordpress.com/504/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bprasetio.wordpress.com/504/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bprasetio.wordpress.com/504/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bprasetio.wordpress.com/504/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bprasetio.wordpress.com/504/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bprasetio.wordpress.com/504/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bprasetio.wordpress.com/504/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bprasetio.wordpress.com/504/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bprasetio.wordpress.com/504/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bprasetio.wordpress.com/504/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bprasetio.wordpress.com/504/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=504&subd=bprasetio&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bprasetio.wordpress.com/2008/09/15/form-load-profiler-multiple-form/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">bprasetio</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/09/formloadprofiler-multiform-interposer.jpg" medium="image">
			<media:title type="html">formloadprofiler-multiform-interposer</media:title>
		</media:content>
	</item>
		<item>
		<title>Form Load Profiler: Single Form</title>
		<link>http://bprasetio.wordpress.com/2008/09/01/form-load-profiler-single-form/</link>
		<comments>http://bprasetio.wordpress.com/2008/09/01/form-load-profiler-single-form/#comments</comments>
		<pubDate>Mon, 01 Sep 2008 03:38:41 +0000</pubDate>
		<dc:creator>bprasetio</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Did You Know]]></category>
		<category><![CDATA[form load time]]></category>
		<category><![CDATA[GetTickCount]]></category>
		<category><![CDATA[profiler]]></category>

		<guid isPermaLink="false">http://bprasetio.wordpress.com/?p=482</guid>
		<description><![CDATA[Pada kesempatan ini saya ingin memaparkan bagaimana membuat pengukur lama proses (profiler) sederhana untuk mengukur waktu tayang (load-time) suatu form dari form tersebut di buat hingga benar &#8211; benar tampil dan siap digunakan. 

Tunggu dulu, sabar, sebelum saya memaparkan triknya, perlu saya informasikan siklus bagaimana suatu form dibuat sampai dengan ditayangkan dan siap digunakan dan [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=482&subd=bprasetio&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Pada kesempatan ini saya ingin memaparkan bagaimana membuat pengukur lama proses (<em>profiler</em>) sederhana untuk mengukur waktu tayang (<em>load-time</em>) suatu form dari form tersebut di buat hingga benar &#8211; benar tampil dan siap digunakan. </p>
<p><span id="more-482"></span></p>
<p>Tunggu dulu, sabar, sebelum saya memaparkan triknya, perlu saya informasikan siklus bagaimana suatu form dibuat sampai dengan ditayangkan dan siap digunakan dan pada akhirnya sampai form itu ditutup dan dibebaskan dari memori.</p>
<p>1. Pembuatan Form (Form Creation: DFM Loading, Objects Construction, OnCreate Event)<br />
2. Penayangan Form (Form Show: Form Painting, OnShow Event)<br />
3. Aktivasi Form (Form Activate: Form Resizing, Form Painting, OnActivate Event)<br />
4. Penggunaan Form (Form Usage)<br />
5. Konfirmasi Penutupan Form (Form CloseQuery: OnCloseQuery)<br />
6. Penutupan Form (Form Close: OnClose)<br />
7. Penyembunyian Form (Form Hiding: OnHide)<br />
8. Penghancuran Form (Form Destruction: OnDestroy)</p>
<p>Nah setelah kita mengetahui siklus pembuatan dan penayangan form, kita sudah bisa meraba akan diletakkan dimana pengkuran yang dilakukan. Ya, pengukuran dimulai dari pemanggilan constructor create yang diakhiri dengan setelah aktivasi form (activate).</p>
<p><strong>Lalu bagaimana meletakkan awal pengukuran?</strong></p>
<p>Mudahnya adalah dengan menyisipkan kode pada saat pemanggilan constructor create suatu form. Yaitu di dalam method contructor create, pada awal baris, sisipkan kode untuk menghitung waktu mulai proses, yaitu dengan menggunakan fungsi GetTickCount() yang hasilnya disimpan pada variabel FStart yang bertipe Cardinal.</p>
<p><strong>Lalu bagaimana meletakkan akhir pengukuran?</strong></p>
<p>Pengukuran diletakkan pada bagian paling akhir Form Activation, yaitu dengan menggunakan fungsi GetTickCount() yang hasilnya disimpan pada variabel FEnd yang bertipe Cardinal.</p>
<p><strong>Teknik Penyisipan Kode</strong></p>
<p>Pasti ada yang berpendapat bahwa kode disisipkan pada event OnCreate (awal pengukuran) dan onActivate (akhir pengukuran). Tidak. Peletakan pada event onCreate tidak mengukur rutin untuk membaca form DFM dan pembuatan komponen yang ada didalamnya. Dan penyisipan pada event onActivate juga demikian, tidak menjamin bahwa semua rutin sudah dilakukan. Lalu dimana?</p>
<p>Tentu saja di <em>constructor Create</em>. Kita perlu melakukan overriding constructor Create, menyisipkan kode pengukuran diatas segalanya, kemudian memanggil constructor yang sebenarnya (<em>inherited</em>).</p>
<p>Demikian pula untuk menyisipkan pengukuran akhir. <em>Procedure Activate</em> harus di-<em>override</em> dengan meletakkan kode pengukuran di bawah segalanya, dengan sebelumnya memanggil procedure Activate yang sebenarnya (<em>inherited</em>).</p>
<p>sehingga kode nya sebagai berikut:</p>
<pre class="brush: delphi;">
unit SingleFormUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TSingleForm = class(TForm)
    btnShowResult: TButton;
    mmoLegend: TMemo;
    stbMain: TStatusBar;
    procedure btnShowResultClick(Sender: TObject);
  private
    { Private declarations }
    FStart, FEnd : Cardinal;
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    procedure Activate; override;
  end;

var
  SingleForm: TSingleForm;

implementation

{$R *.dfm}

{ TSingleForm }

procedure TSingleForm.Activate;
begin
  inherited;
  FEnd := GetTickCount;
end;

procedure TSingleForm.btnShowResultClick(Sender: TObject);
begin
  ShowMessage('Load Time : ' + IntToStr(FEnd - FStart));
end;

constructor TSingleForm.Create(AOwner: TComponent);
begin
  FStart := GetTickCount;
  inherited;
end;

end.
</pre>
<p>Sementara disain form-nya sebagai berikut:<br />
<div id="attachment_483" class="wp-caption alignnone" style="width: 461px"><a href="http://bprasetio.files.wordpress.com/2008/09/formloadprofiler-single-design.jpg"><img src="http://bprasetio.files.wordpress.com/2008/09/formloadprofiler-single-design.jpg?w=451&#038;h=237" alt="Design Form" width="451" height="237" class="size-full wp-image-483" /></a><p class="wp-caption-text">Design Form</p></div></p>
<p>Pengukuran secara otomatis akan dilakukan ketika aplikasi dijalankan. Klik tombol &#8220;Show Measurement Result&#8221; untuk melihat hasilnya.<br />
<div id="attachment_484" class="wp-caption alignnone" style="width: 436px"><a href="http://bprasetio.files.wordpress.com/2008/09/formloadprofiler-single-result.jpg"><img src="http://bprasetio.files.wordpress.com/2008/09/formloadprofiler-single-result.jpg?w=426&#038;h=185" alt="Form Load Time Result" width="426" height="185" class="size-full wp-image-484" /></a><p class="wp-caption-text">Form Load Time Result</p></div></p>
<p>Nah selesai, cukup mudah dan sederhana bukan?</p>
<p>Langkah pengembangan selanjutnya adalah bagaimana menerapkan pengukuran tersebut untuk semua form di aplikasi. </p>
<p>Simak lanjutannya di Bagian 2.</p>
<p>Semoga bermanfaat.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/bprasetio.wordpress.com/482/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/bprasetio.wordpress.com/482/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bprasetio.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bprasetio.wordpress.com/482/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bprasetio.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bprasetio.wordpress.com/482/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bprasetio.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bprasetio.wordpress.com/482/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bprasetio.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bprasetio.wordpress.com/482/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bprasetio.wordpress.com/482/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bprasetio.wordpress.com/482/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=482&subd=bprasetio&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bprasetio.wordpress.com/2008/09/01/form-load-profiler-single-form/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">bprasetio</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/09/formloadprofiler-single-design.jpg" medium="image">
			<media:title type="html">Design Form</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/09/formloadprofiler-single-result.jpg" medium="image">
			<media:title type="html">Form Load Time Result</media:title>
		</media:content>
	</item>
		<item>
		<title>Custom MessageDlg: Centered Message</title>
		<link>http://bprasetio.wordpress.com/2008/08/12/custom-messagedlg-centered-message/</link>
		<comments>http://bprasetio.wordpress.com/2008/08/12/custom-messagedlg-centered-message/#comments</comments>
		<pubDate>Tue, 12 Aug 2008 10:31:43 +0000</pubDate>
		<dc:creator>bprasetio</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Did You Know]]></category>
		<category><![CDATA[Custom MessageDlg]]></category>
		<category><![CDATA[MessageDlg]]></category>

		<guid isPermaLink="false">http://bprasetio.wordpress.com/?p=476</guid>
		<description><![CDATA[Salah seorang pejuang Delphi menanggapi artikel saya mengenai Custom MessageDlg. Ybs menanyakan apakah mungkin teks pesan pada MessageDlg diubah perataannya, yaitu rata tengah (Ridwan&#8217;s Comment). 

Dan tanpa babibu lagi, berikut cuplikan gambar aksinya:
Lalu bagaimana triknya? Seperti yang telah saya utarakan pada tanggapan artikel tersebut, ada beberapa cara, salah satunya adalah dengan CodeRedirect. CodeRedirect merupakan teknik [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=476&subd=bprasetio&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Salah seorang pejuang Delphi menanggapi artikel saya mengenai <a href="http://bprasetio.wordpress.com/2008/08/07/custom-messagedlg/">Custom MessageDlg</a>. Ybs menanyakan apakah mungkin teks pesan pada MessageDlg diubah perataannya, yaitu rata tengah (<a href="http://bprasetio.wordpress.com/2008/08/07/custom-messagedlg/#comment-430">Ridwan&#8217;s Comment</a>). </p>
<p><span id="more-476"></span></p>
<p>Dan tanpa babibu lagi, berikut cuplikan gambar aksinya:<br />
<div id="attachment_477" class="wp-caption alignnone" style="width: 310px"><a href="http://bprasetio.files.wordpress.com/2008/08/custommessagedlgcentered.jpg"><img src="http://bprasetio.files.wordpress.com/2008/08/custommessagedlgcentered.jpg?w=300&#038;h=156" alt="Teks MessageDlg Rata Tengah" width="300" height="156" class="size-medium wp-image-477" /></a><p class="wp-caption-text">Teks MessageDlg Rata Tengah</p></div></p>
<p>Lalu bagaimana triknya? Seperti yang telah saya utarakan pada tanggapan artikel tersebut, ada beberapa cara, salah satunya adalah dengan CodeRedirect. CodeRedirect merupakan teknik membelokkan (mengganti alamat tujuan) pemanggilan suatu blok kode program ke menuju blok kode yang dikehendaki. Dengan demikian blok kode yang dibelokkan tidak pernah dieksekusi.</p>
<p>Berhubung saya lagi malas ber-panjang-lebar cas cis cus, jadi silahkan dipahami dan dinikmati kode sumber yang saya sajikan.</p>
<pre class="brush: delphi;">
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the &quot;License&quot;); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html

Software distributed under the License is distributed on an &quot;AS IS&quot; basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.

The Original Code is: CustomMessageDlgCenteredUnit.pas, released on 2008-08-12

The Initial Developer of the Original Code is Bayu Prasetio
Portions created by Bayu Prasetio are Copyright (C) 2008 Bayu Prasetio.
Portions created by Andreas Hausladen are Copyright (C) Andreas Hausladen
All Rights Reserved.
-----------------------------------------------------------------------------}

{-----------------------------------------------------------------------------
  Perhatian :
    Apa yang tertera pada kode sumber ini sebaiknya dipahami terlebih dahulu,
    jangan asal 'copy-paste' dan melakukan protes jika tidak sesuai dengan
    keinginan.

    Yang perlu saya tekankan adalah, bahwa materi yang terdapat dalam kode
    sumber ini sekedar demo, 'proof-of-concept' untuk mendukung eksplorasi
    mengatur MessageDlg sampai ke batas yang Anda tentukan sendiri berdasarkan
    imajinasi dan kreativitas Anda. Dan tentu saja harapan saya adalah Anda
    dapat mengeksplorasi dan mengembangkan jauh lebih baik dari yang ada di
    demo ini.
-----------------------------------------------------------------------------}

unit CustomMessageDlgCenteredUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    btnCentered: TButton;
    mmoLegend: TMemo;
    procedure btnCenteredClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  function MessageDlgCentered(const Msg: string; DlgType: TMsgDlgType;
    Buttons: TMsgDlgButtons; HelpCtx: Integer): Integer;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//------------------------------------------------------------------------------
//   taken from bpCodeReplacement
//   Portions created by Andreas Hausladen
//------------------------------------------------------------------------------
type
  TInjectRec = packed record
    Jump: Byte;
    Offset: Integer;
  end;

  PAbsoluteIndirectJmp = ^TAbsoluteIndirectJmp;
  TAbsoluteIndirectJmp = packed record
    OpCode: Word;   //$FF25
    Addr: ^Pointer;
  end;

  PWin9xDebugThunk = ^TWin9xDebugThunk;
  TWin9xDebugThunk = packed record
    PUSH: Byte;    // $68
    Addr: Pointer;
    JMP: Byte;     // $E9
    Offset: Integer;
  end;

function IsWin9xDebugThunk(Addr: Pointer): Boolean;
begin
  Result := (Addr &lt;&gt; nil) and (PWin9xDebugThunk(Addr).PUSH = $68) and
                              (PWin9xDebugThunk(Addr).JMP = $E9);
end;

function GetActualAddr(Proc: Pointer): Pointer;
begin
  if Proc &lt;&gt; nil then
  begin
    if (SysUtils.Win32Platform &lt;&gt; VER_PLATFORM_WIN32_NT) and IsWin9xDebugThunk(Proc) then
      Proc := PWin9xDebugThunk(Proc).Addr;
    if (PAbsoluteIndirectJmp(Proc).OpCode = $25FF) then
      Result := PAbsoluteIndirectJmp(Proc).Addr^
    else
      Result := Proc;
  end
  else
    Result := nil;
end;

procedure CodeRedirect(Proc: Pointer; NewProc: Pointer);
var
  OldProtect: Cardinal;
begin
  if Proc = nil then
    Exit;
  Proc := GetActualAddr(Proc);
  if VirtualProtectEx(GetCurrentProcess, Proc, SizeOf(TInjectRec), PAGE_EXECUTE_READWRITE, OldProtect) then
  begin
    TInjectRec(Proc^).Jump := $E9;
    TInjectRec(Proc^).Offset := Integer(NewProc) - (Integer(Proc) + SizeOf(TInjectRec));
    VirtualProtectEx(GetCurrentProcess, Proc, SizeOf(TInjectRec), OldProtect, @OldProtect);
  end;
end;

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

//------------------------------------------------------------------------------
//   Centering Message
//------------------------------------------------------------------------------
function MessageDlgCentered(const Msg: string; DlgType: TMsgDlgType;
  Buttons: TMsgDlgButtons; HelpCtx: Integer): Integer;
var
  ALabel : TComponent;
begin
  with Dialogs.CreateMessageDialog(Msg, DlgType, Buttons) do
  try
    ALabel := FindComponent('Message');
    if ALabel &lt;&gt; nil then
      TLabel(ALabel).Alignment := taCenter;
    Result := ShowModal;
  finally
    Free;
  end
end;

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

procedure TForm1.btnCenteredClick(Sender: TObject);
begin
  MessageDlg('Pesan ini ditulis rata tengah' + #13#10 +
             'Silahkan eksplorasi lebih lanjut. <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> ', mtInformation, [mbOK], 0);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // belokkan setiap pemanggilan MessageDlg ke fungsi MessageDlgCentered
  CodeRedirect(@Dialogs.MessageDlg, @MessageDlgCentered);
end;

end.
</pre>
<p>Semoga bermanfaat.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/bprasetio.wordpress.com/476/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/bprasetio.wordpress.com/476/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bprasetio.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bprasetio.wordpress.com/476/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bprasetio.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bprasetio.wordpress.com/476/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bprasetio.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bprasetio.wordpress.com/476/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bprasetio.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bprasetio.wordpress.com/476/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bprasetio.wordpress.com/476/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bprasetio.wordpress.com/476/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=476&subd=bprasetio&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bprasetio.wordpress.com/2008/08/12/custom-messagedlg-centered-message/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">bprasetio</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/08/custommessagedlgcentered.jpg?w=300" medium="image">
			<media:title type="html">Teks MessageDlg Rata Tengah</media:title>
		</media:content>
	</item>
		<item>
		<title>Custom MessageDlg</title>
		<link>http://bprasetio.wordpress.com/2008/08/07/custom-messagedlg/</link>
		<comments>http://bprasetio.wordpress.com/2008/08/07/custom-messagedlg/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 03:18:57 +0000</pubDate>
		<dc:creator>bprasetio</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Did You Know]]></category>
		<category><![CDATA[Custom MessageDlg]]></category>
		<category><![CDATA[MessageDlg]]></category>

		<guid isPermaLink="false">http://bprasetio.wordpress.com/?p=470</guid>
		<description><![CDATA[Artikel ini merupakan lanjutan dari Meng-Indonesia-kan MessageDlg yang pernah saya publikasikan beberapa bulan yang lalu (lebih tepatnya tahun yang lalu). Sebenarnya saya ingin mengangkat tema lain yang menurut saya lebih menarik, namun berhubung ada diskusi di forum Delphi Indonesia (Delphi-ID) mengenai membuat MessageDlg sesuai dengan keinginan secara dinamis, maka saya putuskan untuk menulisnya terlebih dahulu. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=470&subd=bprasetio&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Artikel ini merupakan lanjutan dari Meng-Indonesia-kan MessageDlg yang pernah saya publikasikan beberapa bulan yang lalu (lebih tepatnya tahun yang lalu). Sebenarnya saya ingin mengangkat tema lain yang menurut saya lebih menarik, namun berhubung ada diskusi di forum Delphi Indonesia (Delphi-ID) mengenai membuat MessageDlg sesuai dengan keinginan secara dinamis, maka saya putuskan untuk menulisnya terlebih dahulu.  </p>
<p><span id="more-470"></span></p>
<p>Ada anggapan bahwa artikel tersebut hanya menitik beratkan pada lokalisasi teks MessageDlg, sebenarnya lebih dari itu. Jika dicermati, saya memaparkan trik bagaimana mengubah judul dan tombol yang digunakan MessageDlg pada saat aplikasi berjalan (run-time). Kemudian trik tersebut saya kuatkan dengan demo agar lebih jelas dipahami. Oiya sekedar untuk diketahui trik tersebut berlaku global, untuk semua MessageDlg yang dipanggil oleh aplikasi yang menggunakan, tidak peduli berasal dari mana form atau unit pemanggilnya sampai aplikasi ditutup.</p>
<p>Ada anggapan bahwa trik tersebut bersifat sekali pakai saja, tidak dinamis. Nah inilah yang perlu saya luruskan. Tentu saja trik tersebut dapat dipanggil dan digunakan berkali – kali untuk menampilkan MessageDlg dengan judul dan teks tombol yang berbeda – beda pula.</p>
<p>Lalu bagaimanakah cara agar dapat menampilkan MessageDlg sesuai dengan konteks teks judul dan tombol yang kita inginkan?</p>
<p>Tentu saja cukup mudah!</p>
<p>Cukup panggil method ReplaceResourceString dengan parameter judul, tombol mana yang ingin diubah teks-nya.</p>
<p>Misalnya:   </p>
<pre class="brush: delphi;">
  ReplaceResourceString(@SMsgDlgConfirm, 'Konfirmasi Penyimpanan');
  ReplaceResourceString(@SMsgDlgYes, 'Simpan Perubahan');
  ReplaceResourceString(@SMsgDlgNo, 'Jangan Simpan');
</pre>
<p>Ok, cukup, saya rasa Anda sudah mendapatkan inti-nya. Jika masih belum, coba simak kode sumber demo berikut, bagi yang belum paham, baca juga penjelasan yang saya tambahkan sebagai komentar:</p>
<pre class="brush: delphi;">
{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the &quot;License&quot;); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html

Software distributed under the License is distributed on an &quot;AS IS&quot; basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.

The Original Code is: CustomMessageDlgDemoUnit.pas, released on 2008-08-05

The Initial Developer of the Original Code is Bayu Prasetio
Portions created by Bayu Prasetio are Copyright (C) 2007, 2008 Bayu Prasetio.
All Rights Reserved.
-----------------------------------------------------------------------------}

{-----------------------------------------------------------------------------
  Perhatian :
    Apa yang tertera pada kode sumber ini sebaiknya dipahami terlebih dahulu,
    jangan asal 'copy-paste' dan melakukan protes jika tidak sesuai dengan
    keinginan.

    Yang perlu saya tekankan adalah, bahwa materi yang terdapat dalam kode
    sumber ini sekedar demo, 'proof-of-concept' untuk mendukung eksplorasi
    lanjutan dari 'Meng-Indonesia-kan MessageDlg' sampai ke batas yang Anda
    tentukan sendiri berdasarkan imajinasi dan kreativitas Anda. Ingat, demo
    ini belum optimal dan terbaik. Dan tentu saja harapan saya adalah Anda
    dapat mengeksplorasi dan mengembangkan jauh lebih baik dari yang ada di
    demo ini.

    Kelemahan mendasar adalah:
    - Ukuran tombol hanya berubah pada saat 'ReplaceResourceString' pertama,
      pemanggilan berikutnya tidak mengubah ukuran tombol
-----------------------------------------------------------------------------}

unit CustomMessageDlgDemoUnit;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TfrmCustomMessageDlg = class(TForm)
    btnStandard: TButton;
    btnIndonesian: TButton;
    btnContextSave: TButton;
    mmoLegend: TMemo;
    stbMain: TStatusBar;
    btnContextPrint: TButton;
    procedure btnStandardClick(Sender: TObject);
    procedure btnIndonesianClick(Sender: TObject);
    procedure btnContextSaveClick(Sender: TObject);
    procedure btnContextPrintClick(Sender: TObject);
  private
    { Private declarations }
    procedure ReplaceResourceString(RStringRec: PResStringRec; AString: PChar);
    procedure SetCustomMessageStandard;
    procedure SetCustomMessageIndonesian;
    procedure SetCustomMessageContextSave;
    procedure SetCustomMessageContextPrint;
  public
    { Public declarations }
  end;

var
  frmCustomMessageDlg: TfrmCustomMessageDlg;

implementation

{$R *.dfm}

uses
  Consts;

const
  // konstanta default untuk MessageDlg
  _SMsgDlgWarning = 'Warning';
  _SMsgDlgError = 'Error';
  _SMsgDlgInformation = 'Information';
  _SMsgDlgConfirm = 'Confirm';
  _SMsgDlgYes = '&amp;amp;Yes';
  _SMsgDlgNo = '&amp;amp;No';
  _SMsgDlgOK = 'OK';
  _SMsgDlgCancel = 'Cancel';
  _SMsgDlgHelp = '&amp;amp;Help';
  _SMsgDlgHelpNone = 'No help available';
  _SMsgDlgHelpHelp = 'Help';
  _SMsgDlgAbort = '&amp;amp;Abort';
  _SMsgDlgRetry = '&amp;amp;Retry';
  _SMsgDlgIgnore = '&amp;amp;Ignore';
  _SMsgDlgAll = '&amp;amp;All';
  _SMsgDlgNoToAll = 'N&amp;amp;o to All';
  _SMsgDlgYesToAll = 'Yes to &amp;amp;All';

  // konstanta MessageDlg untuk Bahasa Indonesia
  _SMsgDlgWarningIndonesian = 'Peringatan';
  _SMsgDlgErrorIndonesian = 'Kesalahan';
  _SMsgDlgInformationIndonesian = 'Informasi';
  _SMsgDlgConfirmIndonesian = 'Konfirmasi';
  _SMsgDlgYesIndonesian = '&amp;amp;Ya';
  _SMsgDlgNoIndonesian = '&amp;amp;Tidak';
  _SMsgDlgOKIndonesian = 'OK';
  _SMsgDlgCancelIndonesian = 'Batal';
  _SMsgDlgHelpIndonesian = '&amp;amp;Panduan';
  _SMsgDlgHelpNoneIndonesian = 'Panduan tidak tersedia';
  _SMsgDlgHelpHelpIndonesian = 'Panduan';
  _SMsgDlgAbortIndonesian = '&amp;amp;Batal';
  _SMsgDlgRetryIndonesian = '&amp;amp;Ulang';
  _SMsgDlgIgnoreIndonesian = 'A&amp;amp;cuh';
  _SMsgDlgAllIndonesian = '&amp;amp;Semua';
  _SMsgDlgNoToAllIndonesian = 'T&amp;amp;idak untuk Semua';
  _SMsgDlgYesToAllIndonesian = 'Ya untuk S&amp;amp;emua';

  // konstanta MessageDlg untuk konteks Pencetakan
  // yang digunakan adalah konfirmasi, mbOK, mbYes dan mbNo
  _SMsgDlgWarningContextPrint = 'Peringatan';
  _SMsgDlgErrorContextPrint = 'Kesalahan';
  _SMsgDlgInformationContextPrint = 'Informasi';
  _SMsgDlgConfirmContextPrint = 'Konfirmasi Tujuan Pencetakan';
  _SMsgDlgYesContextPrint = '&amp;amp;Printer';
  _SMsgDlgNoContextPrint = 'Dokumen PD&amp;amp;F Lebar Yak';
  _SMsgDlgOKContextPrint = '&amp;amp;Layar';
  _SMsgDlgCancelContextPrint = 'Batal';
  _SMsgDlgHelpContextPrint = '&amp;amp;Panduan';
  _SMsgDlgHelpNoneContextPrint = 'Panduan tidak tersedia';
  _SMsgDlgHelpHelpContextPrint = 'Panduan';
  _SMsgDlgAbortContextPrint = '&amp;amp;Batal';
  _SMsgDlgRetryContextPrint = '&amp;amp;Ulang';
  _SMsgDlgIgnoreContextPrint = 'A&amp;amp;cuh';
  _SMsgDlgAllContextPrint = '&amp;amp;Semua';
  _SMsgDlgNoToAllContextPrint = 'T&amp;amp;idak untuk Semua';
  _SMsgDlgYesToAllContextPrint = 'Ya untuk S&amp;amp;emua';

  // konstanta MessageDlg untuk konteks Penyimpanan
  // yang digunakan adalah konfirmasi, mbYes dan mbNo
  _SMsgDlgWarningContextSave = 'Peringatan';
  _SMsgDlgErrorContextSave = 'Kesalahan';
  _SMsgDlgInformationContextSave = 'Informasi';
  _SMsgDlgConfirmContextSave = 'Konfirmasi Penyimpanan';
  _SMsgDlgYesContextSave = '&amp;amp;Simpan';
  _SMsgDlgNoContextSave = '&amp;amp;Lanjut Saja';
  _SMsgDlgOKContextSave = 'OK';
  _SMsgDlgCancelContextSave = 'Batal';
  _SMsgDlgHelpContextSave = '&amp;amp;Panduan';
  _SMsgDlgHelpNoneContextSave = 'Panduan tidak tersedia';
  _SMsgDlgHelpHelpContextSave = 'Panduan';
  _SMsgDlgAbortContextSave = '&amp;amp;Batal';
  _SMsgDlgRetryContextSave = '&amp;amp;Ulang';
  _SMsgDlgIgnoreContextSave = 'A&amp;amp;cuh';
  _SMsgDlgAllContextSave = '&amp;amp;Semua';
  _SMsgDlgNoToAllContextSave = 'T&amp;amp;idak untuk Semua';
  _SMsgDlgYesToAllContextSave = 'Ya untuk S&amp;amp;emua';

procedure TfrmCustomMessageDlg.btnContextPrintClick(Sender: TObject);
begin
  SetCustomMessageContextPrint;
end;

procedure TfrmCustomMessageDlg.btnContextSaveClick(Sender: TObject);
begin
  SetCustomMessageContextSave;
end;

procedure TfrmCustomMessageDlg.btnIndonesianClick(Sender: TObject);
begin
  SetCustomMessageIndonesian;
end;

procedure TfrmCustomMessageDlg.btnStandardClick(Sender: TObject);
begin
  SetCustomMessageStandard;
end;

{-- taken from bpCodeReplacement.pas by Bayu Prasetio}
procedure TfrmCustomMessageDlg.ReplaceResourceString(RStringRec: PResStringRec;
  AString: PChar);
var
  OldProtect: Cardinal;
begin
  if RStringRec = nil then Exit;
  if VirtualProtectEx(GetCurrentProcess, RStringRec, SizeOf(RStringRec^), PAGE_EXECUTE_READWRITE, OldProtect) then
  begin
    RStringRec^.Identifier := Integer(AString);
    VirtualProtectEx(GetCurrentProcess, RStringRec, SizeOf(RStringRec^), OldProtect, @OldProtect);
  end;
end;

procedure TfrmCustomMessageDlg.SetCustomMessageContextPrint;
begin
  // sebagai contoh, ubah resource string untuk MessageDlg berdasarkan konteks kejadian
  // dalam hal ini adalah proses pencetakan
  // mbOK disetarakan tayang ke layar (preview)
  // mbYes disetarakan cetak ke printer
  // mbNo disetarakan cetak ke dokumen PDF
  ReplaceResourceString(@SMsgDlgConfirm, _SMsgDlgConfirmContextPrint);
  ReplaceResourceString(@SMsgDlgYes, _SMsgDlgYesContextPrint);
  ReplaceResourceString(@SMsgDlgNo, _SMsgDlgNoContextPrint);
  ReplaceResourceString(@SMsgDlgOK, _SMsgDlgOKContextPrint);

  // gunakan ModalResult dari MessageDlg untuk menentukan tindakan selanjutnya
  // hati - hati, Anda tidak dapat menggunakan ShowMessage sekehendak hati
  // karena ShowMessage sebenarnya MessageDlg dengan parameter MessageType mtInformation
  // dan Buttons [mbOK]. Pahamkan mengapa tombol 'OK' berubah menjadi 'Layar' ?
  case MessageDlg('Tentukan tujuan pencetakan dokumen ?', mtConfirmation, [mbOK, mbYes, mbNo], 0) of
    mrOK : ShowMessage('Dokumen ditayangkan ke layar');
    mrYes : ShowMessage('Dokumen dicetak ke printer');
    mrNo : ShowMessage('Dokumen disimpan dalam format .PDF');
  end;
end;

procedure TfrmCustomMessageDlg.SetCustomMessageContextSave;
begin
  // sebagai contoh, ubah resource string untuk MessageDlg berdasarkan konteks kejadian
  // dalam hal ini adalah proses simpan
  ReplaceResourceString(@SMsgDlgConfirm, _SMsgDlgConfirmContextSave);
  ReplaceResourceString(@SMsgDlgYes, _SMsgDlgYesContextSave);
  ReplaceResourceString(@SMsgDlgNo, _SMsgDlgNoContextSave);
  ReplaceResourceString(@SMsgDlgCancel, _SMsgDlgCancelContextSave);

  MessageDlg('Anda Yakin akan menyimpan dokumen ini ?', mtConfirmation, mbYesNoCancel, 0);
end;

procedure TfrmCustomMessageDlg.SetCustomMessageIndonesian;
begin
  // ubah semua resource string untuk MessageDlg ke bahasa Indonesia
  ReplaceResourceString(@SMsgDlgWarning, _SMsgDlgWarningIndonesian);
  ReplaceResourceString(@SMsgDlgError, _SMsgDlgErrorIndonesian);
  ReplaceResourceString(@SMsgDlgInformation, _SMsgDlgInformationIndonesian);
  ReplaceResourceString(@SMsgDlgConfirm, _SMsgDlgConfirmIndonesian);
  ReplaceResourceString(@SMsgDlgYes, _SMsgDlgYesIndonesian);
  ReplaceResourceString(@SMsgDlgNo, _SMsgDlgNoIndonesian);
  ReplaceResourceString(@SMsgDlgOK, _SMsgDlgOKIndonesian);
  ReplaceResourceString(@SMsgDlgCancel, _SMsgDlgCancelIndonesian);
  ReplaceResourceString(@SMsgDlgHelp, _SMsgDlgHelpIndonesian);
  ReplaceResourceString(@SMsgDlgHelpNone, _SMsgDlgHelpNoneIndonesian);
  ReplaceResourceString(@SMsgDlgHelpHelp, _SMsgDlgHelpHelpIndonesian);
  ReplaceResourceString(@SMsgDlgAbort, _SMsgDlgAbortIndonesian);
  ReplaceResourceString(@SMsgDlgRetry, _SMsgDlgRetryIndonesian);
  ReplaceResourceString(@SMsgDlgIgnore, _SMsgDlgIgnoreIndonesian);
  ReplaceResourceString(@SMsgDlgAll, _SMsgDlgAllIndonesian);
  ReplaceResourceString(@SMsgDlgNoToAll, _SMsgDlgNoToAllIndonesian);
  ReplaceResourceString(@SMsgDlgYesToAll, _SMsgDlgYesToAllIndonesian);

  MessageDlg('Anda Yakin akan menyimpan dokumen ini ?', mtConfirmation, mbYesNoCancel, 0);
end;

procedure TfrmCustomMessageDlg.SetCustomMessageStandard;
begin
  // ubah semua resource string untuk MessageDlg ke default
  ReplaceResourceString(@SMsgDlgWarning, _SMsgDlgWarning);
  ReplaceResourceString(@SMsgDlgError, _SMsgDlgError);
  ReplaceResourceString(@SMsgDlgInformation, _SMsgDlgInformation);
  ReplaceResourceString(@SMsgDlgConfirm, _SMsgDlgConfirm);
  ReplaceResourceString(@SMsgDlgYes, _SMsgDlgYes);
  ReplaceResourceString(@SMsgDlgNo, _SMsgDlgNo);
  ReplaceResourceString(@SMsgDlgOK, _SMsgDlgOK);
  ReplaceResourceString(@SMsgDlgCancel, _SMsgDlgCancel);
  ReplaceResourceString(@SMsgDlgHelp, _SMsgDlgHelp);
  ReplaceResourceString(@SMsgDlgHelpNone, _SMsgDlgHelpNone);
  ReplaceResourceString(@SMsgDlgHelpHelp, _SMsgDlgHelpHelp);
  ReplaceResourceString(@SMsgDlgAbort, _SMsgDlgAbort);
  ReplaceResourceString(@SMsgDlgRetry, _SMsgDlgRetry);
  ReplaceResourceString(@SMsgDlgIgnore, _SMsgDlgIgnore);
  ReplaceResourceString(@SMsgDlgAll, _SMsgDlgAll);
  ReplaceResourceString(@SMsgDlgNoToAll, _SMsgDlgNoToAll);
  ReplaceResourceString(@SMsgDlgYesToAll, _SMsgDlgYesToAll);

  MessageDlg('Anda Yakin akan menyimpan dokumen ini ?', mtConfirmation, mbYesNoCancel, 0);
end;

end.
</pre>
<p>Dan sebagai catatan, ada kelemahan yang perlu diketahui perihal trik, yaitu ukuran tombol hanya berubah pada saat &#8216;ReplaceResourceString&#8217; pertama, pemanggilan berikutnya tidak mengubah ukuran tombol.</p>
<p>Ok, seperti yang telah saya tulis komentar di kode sumber, “harapan saya adalah Anda dapat mengeksplorasi dan mengembangkan jauh lebih baik dari yang ada di demo ini”. Saya sengaja membuat demo ini belum optimal, jadi silahkan gunakan logika, kreativitas dan imajinasi Anda.</p>
<p>Semoga bermanfaat.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/bprasetio.wordpress.com/470/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/bprasetio.wordpress.com/470/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bprasetio.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bprasetio.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bprasetio.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bprasetio.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bprasetio.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bprasetio.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bprasetio.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bprasetio.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bprasetio.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bprasetio.wordpress.com/470/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=470&subd=bprasetio&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bprasetio.wordpress.com/2008/08/07/custom-messagedlg/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">bprasetio</media:title>
		</media:content>
	</item>
		<item>
		<title>MESSAGE Directive</title>
		<link>http://bprasetio.wordpress.com/2008/07/18/message-directive/</link>
		<comments>http://bprasetio.wordpress.com/2008/07/18/message-directive/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 04:53:52 +0000</pubDate>
		<dc:creator>bprasetio</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[Did You Know]]></category>
		<category><![CDATA[directive]]></category>
		<category><![CDATA[message]]></category>

		<guid isPermaLink="false">http://bprasetio.wordpress.com/?p=458</guid>
		<description><![CDATA[Delphi dilengkapi dengan compiler directive (direktif kompiler) yang memungkinkan kita melakukan perubahan terhadap bagaimana compiler menangani proses kompilasi kode program. Salah satu direktif yang mungkin jarang kita gunakan adalah MESSAGE. Mau tahu apa dan bagaimana direktif MESSAGE ?

Direktif MESSAGE berguna untuk menampilkan informasi petunjuk (hint), peringatan (warning), kesalahan (error) dan kesalahan fatal (fatal) seperti yang [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=458&subd=bprasetio&ref=&feed=1" />]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>Delphi dilengkapi dengan <i>compiler directive</i> (direktif kompiler) yang memungkinkan kita melakukan perubahan terhadap bagaimana <i>compiler</i> menangani proses kompilasi kode program. Salah satu direktif yang mungkin jarang kita gunakan adalah MESSAGE. Mau tahu apa dan bagaimana direktif MESSAGE ?</p>
<p><span id="more-458"></span></p>
<p>Direktif MESSAGE berguna untuk menampilkan informasi petunjuk (<em>hint</em>), peringatan (<em>warning</em>), kesalahan (<em>error</em>) dan kesalahan fatal (<em>fatal</em>) seperti yang dilakukan oleh kompiler ketika proses kompilasi kode sumber. Pesan ini ditampilkan pada jendela <em>Messages</em>.</p>
<p>Berikut cuplikan penjelasan direktif MESSAGE yang saya ambil dari dokumen panduan Delphi.</p>
<blockquote><p>
<strong>MESSAGE directive (Delphi)</strong><br />
<strong>Syntax</strong>   <code>{$MESSAGE HINT|WARN|ERROR|FATAL 'text string' }</code>   </p>
<p><strong>Remarks </strong><br />
The Delphi message directive allows source code to emit hints, warnings, and errors just as the compiler does. This is similar to #emit or pragma warn in C and C++.  </p>
<p>The message type (HINT, WARN, ERROR, or FATAL) is optional. If no message type is indicated, the default is HINT. The text string is required and must be enclosed in single quotes.  </p>
<p>Examples:<br />
<code><br />
{$MESSAGE 'Boo!'}                   emits a hint<br />
    {$Message Hint 'Feed the cats'}     emits a hint<br />
    {$messaGe Warn 'Looks like rain.'}  emits a warning<br />
    {$Message Error 'Not implemented'}  emits an error, continues compiling<br />
    {$Message Fatal 'Bang.  Yer dead.'} emits an error, terminates compiler<br />
</code>
</p></blockquote>
<p>Dalam implementasinya, direktif MESSAGE seringkali ditautkan dengan direktif SUPPORTS_COMPILETIME_MESSAGES untuk memastikan apakah kompiler yang digunakan mendukung direktif MESSAGE. Namun dalam kesempatan ini saya tidak akan menggunakannya.</p>
<p>Sebagai contoh, saya ingin memastikan bahwa kode sumber hanya dapat di-kompilasi oleh Delphi 2007, Jika versi lain, misalnya Delphi 7 digunakan untuk melakukan kompilasi, maka akan ditampilkan pesan kesalahan dan proses kompilasi dihentikan.</p>
<p>Berikut potongan kode nya:</p>
<pre class="brush: delphi;">
{$IFDEF VER185}
  {$MESSAGE 'You used the correct Delphi version.'}
{$ELSE}
  {$MESSAGE FATAL 'You need Delphi 2007 to compile this source code!'}
{$ENDIF}
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

end.
</pre>
<p>Berikut keterangan singkat dari potongan kode dari baris 1 hingga 5. Untuk baris lainnya hanya sebagai &#8216;hiasan&#8217; bagi artikel ini. </p>
<p>Baris 1:<br />
Baris satu menggunakan <em>conditional directive</em> untuk melakukan pemeriksaan versi Delphi yang digunakan. Pemeriksaan kondisi ditandai dengan direktif IF. Sedangkan versi delphi-nya adalah VER185. Untuk mengetahui versi Delphi yang digunakan untuk kompilasi, kita dapat menggunakan direktif VERxxx dimana xxx adalah kode versi Delphi. Untuk Delphi 2007 kodenya adalah 185, namun dapat juga digunakan nilai 180 (sebagai <em>non-breaking</em> terhadap Delphi 2006). Selengkapnya mengenai direktif versi Delphi, dapat disimak di <a href="http://bprasetio.wordpress.com/2005/08/27/delphi-internal-versions/">Delphi Internal Versions</a>.</p>
<p>Baris 2:<br />
Baris 2 berisi statemen yang akan dipilih oleh kompiler bila versi Delphi sesuai dengan yang dikehendaki. Dalam potongan kode, kompiler akan menjalankan direktif MESSAGE berupa informasi bahwa versi Dlephi yang digunakan sesuai dan proses kompilasi dilanjutkan dengan blok kode berikutnya.</p>
<p>Baris 3:<br />
Baris 3 berisi statemen untuk menandai blok yang harus dikompilasi jika versi Delphi tidak sesuai dengan yang dikehendaki.</p>
<p>Baris 4:<br />
Baris 4 berisi statemen yang akan dipilih oleh kompiler bila versi Delphi tidak sesuai dengan yang dikehendaki. Dalam potongan kode, kompiler akan menjalankan direktif MESSAGE berupa kesalahan fatal bahwa versi Dlephi yang digunakan tidak sesuai dan proses kompilasi dihentikan.</p>
<p>Baris 5:<br />
Menandai akhir dari blok direktif kondisional pemeriksaan versi Delphi.</p>
<p>Berikut potongan gambar apabila kode sumber tersebut dikompilasi dengan Delphi 2007.<br />
<div id="attachment_461" class="wp-caption alignnone" style="width: 301px"><a href="http://bprasetio.files.wordpress.com/2008/07/messagedirectivehint.jpg"><img src="http://bprasetio.files.wordpress.com/2008/07/messagedirectivehint.jpg?w=291&#038;h=300" alt="Direktif Message untuk Delphi 2007" width="291" height="300" class="size-medium wp-image-461" /></a><p class="wp-caption-text">Direktif Message untuk Delphi 2007</p></div></p>
<p>Berikut potongan gambar apabila kode sumber tersebut dikompilasi dengan Delphi 7.<br />
<div id="attachment_462" class="wp-caption alignnone" style="width: 310px"><a href="http://bprasetio.files.wordpress.com/2008/07/messagedirectivefatal.jpg"><img src="http://bprasetio.files.wordpress.com/2008/07/messagedirectivefatal.jpg?w=300&#038;h=177" alt="Direktif Message pada Delphi 7" width="300" height="177" class="size-medium wp-image-462" /></a><p class="wp-caption-text">Direktif Message pada Delphi 7</p></div></p>
<p>Jika dicermati, pada kompilasi Delphi 2007, pesan yang ditampilkan tidak sesuai dengan yang diinginkan. Seharusnya berupa HINT namun ternyata WARNING. Padalah apabila kode tersebut diubah agar dapat dikompile pada Delphi 7, dengan mengubah direktif VER180 menjadi VER150, maka pesan yang ditampilkan akan sesuai yaitu berupa HINT.</p>
<p>Berikut cuplikasn kode jika disesuaikan untuk Delphi 7.<br />
<div id="attachment_463" class="wp-caption alignnone" style="width: 310px"><a href="http://bprasetio.files.wordpress.com/2008/07/messagedirectivehintd7.jpg"><img src="http://bprasetio.files.wordpress.com/2008/07/messagedirectivehintd7.jpg?w=300&#038;h=175" alt="Direktif Message yang sudah disesuaikan untuk Delphi 7" width="300" height="175" class="size-medium wp-image-463" /></a><p class="wp-caption-text">Direktif Message yang sudah disesuaikan untuk Delphi 7</p></div></p>
<p>Ada pendapat ?</p>
<p>Semoga bermanfaat.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/bprasetio.wordpress.com/458/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/bprasetio.wordpress.com/458/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/bprasetio.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/bprasetio.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/bprasetio.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/bprasetio.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/bprasetio.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/bprasetio.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/bprasetio.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/bprasetio.wordpress.com/458/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/bprasetio.wordpress.com/458/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/bprasetio.wordpress.com/458/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=bprasetio.wordpress.com&blog=2495349&post=458&subd=bprasetio&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://bprasetio.wordpress.com/2008/07/18/message-directive/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="" medium="image">
			<media:title type="html">bprasetio</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/07/messagedirectivehint.jpg?w=291" medium="image">
			<media:title type="html">Direktif Message untuk Delphi 2007</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/07/messagedirectivefatal.jpg?w=300" medium="image">
			<media:title type="html">Direktif Message pada Delphi 7</media:title>
		</media:content>

		<media:content url="http://bprasetio.files.wordpress.com/2008/07/messagedirectivehintd7.jpg?w=300" medium="image">
			<media:title type="html">Direktif Message yang sudah disesuaikan untuk Delphi 7</media:title>
		</media:content>
	</item>
	</channel>
</rss>