Monthly Archiv: May, 2013

Membuat form dengan bentuk mengikuti gambar

Umumnya sebuah form yang kita buat menggunakan delphi bentuknya adalah kotak, namun sebenarnya kita bisa membuat form dengan bentuk yang tidak biasa seperti lingkaran, segitiga, poligon atau bahkan bentuk sesuai yang kita inginkan, misalnya mengikuti bentuk gambar.

Untuk membuat (baca:memotong) form menjadi tidak kotak kita menggunakan fungsi dari Windows API yaitu SetWindowRgn.

Pada SetWindowRgn telah disediakan bentuk-bentuk umum seperti kotak, lingkaran atau segi banyak.

Lantas .. bagaimana cara membuat form dengan bentuk yang tidak umum seperti gambar diatas?

Untuk membuat region dengan bentuk tidak biasa perlu dibuat (baca: copas dari internet) unit (fungsi) sehingga lebih mudah dan tidak perlu pusing.

Langsung saja ..

Pertama-tama siapkan dua buah gambar seperti berikut yang nantinya akan diload ke TImage (imgNormal & imgMask).

Gambar pertama diload ke imgNormal

Gambar kedua diload ke imgMask

Ukuran dari kedua gambar harus sama persis.

… yang perlu diperhatikan dalam membuatnya adalah ..

  • Set property BorderStyle pada form menjadi bsNone.
  • Siapkan 2 buat TImage (imgNormal & imgMask), imgNormal untuk menyimpan gambar yg tampil dan imgMask untuk menyimpan gambar pemotong.
  • Set Property Left & Top imgNormal menjadi 0 sehingga akan berada di kiri atas form.
  • Set Propeety AutoSize imgNormal menjadi True.
  • Set property visible pada imgMask menjadi False.

Berikut ini contoh potongan kode yang akan kita tulis di event OnCreate

procedure TFMain.FormCreate(Sender: TObject);
var
   hr,br: HRGN;
   bmp: TBitmap;
begin
     bmp:=TBitmap.Create;
     bmp.Assign(ImgMask.Picture.Graphic);
     hr:=BitmapToRegion(bmp.Handle);
     bmp.Free;
     br:=CreateRectRgnIndirect(mInfo.BoundsRect);
     CombineRgn(hr,hr,br,RGN_OR);
     br:=CreateRectRgnIndirect(btClose.BoundsRect);
     CombineRgn(hr,hr,br,RGN_OR);
     SetWindowRgn(Handle,hr,True);
end;

Karena form ini tidak mempunyai Caption, lantas bagaimana caranya jika kita ingin menggesernya?
Agar form bisa kita geser dengan Click-Drag pada selain Caption, maka kita harus melakukan intercept pada Message WM_NCHITTEST seperti kode berikut ini

  private
    { Private declarations }
    procedure GeserForm(var msg: TWMNCHitTest);
              message WM_NCHITTEST;

Bagi yang tertarik untuk membuat aplikasi dengan form seperti gambar diatas silahkan download contoh project beserta source codenya di ..
https://www.box.com/s/n29a3n5x10srvrr1jvqg

Semoga bermanfaat
Wassalam

Imam Chalimi Muslim

Cara sederhana membuat tampilan UNICODE pada Delphi 2006 kebawah

Apakah UNICODE itu?

UNICODE adalah suatu standar industri yang dirancang untuk mengijinkan teks dan simbol dari semua tulisan di dunia untuk ditampilkan dan dimanipulasi secara konsisten oleh komputer.

Dengan UNICODE kita dapat menampilkan teks atau simbol khusus (kode ASCII diatas 255) seperti tulisan Arab, China, Latin dan lain-lain.

Pada UNICODE setiap karakter disimpan dalam 2 byte (2x karakter biasa), sehingga memungkinkan ada $FFFF (65535 karakter).

Dukungan Delphi terhadap UNICODE dimulai sejak Delphi 2009, lalu bagaimana nasib pengguna Delphi dibawah 2009, apakah harus gigit jari ..?

Tenang  ….. , dengan trik sederhana kita pengguna Delphi yang belum mendukung UNICODE (Delphi 2006 atau bahkan Delphi 7) dapat menikmati tampilan UNICODE tanpa hapus menginstall komponen tambahan.

Sudah gak sabar ya ..

Langsung aja deh ini penampakannya ..
unicode.jpg

Ini source kodenya

unit main;

interface

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

type
  TFMain = class(TForm)
    procedure FormPaint(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  FMain: TFMain;

const
     arbBasmalah: array[0..30] of WideChar =
                  (#$0628,#$0640,#$0633,#$0640,#$0640,
                  #$0640,#$0640,#$0640,#$0640,#$0640,
                  #$0640,#$0645,#$0020,#$0627,#$0644,
                  #$0644,#$0647,#$0020,#$0627,#$0644,
                  #$0631,#$062D,#$0645,#$0646,#$0020,
                  #$0627,#$0644,#$0631,#$062D,#$064A,
                  #$0645);
     arbImam: array[0..8] of WideChar = (#$0627,#$0645,#$0627,#$0645,
	          #$0020,#$062D,#$0627,#$0644,#$0645);

implementation

{$R *.dfm}

procedure TextSizeW(Canvas:TCanvas;ws:WideString;var sz:TSize);
begin
     GetTextExtentPoint32W(Canvas.Handle,PWideChar(ws),Length(ws),sz);
end;

procedure TulisUnicode(Canvas:TCanvas;Left,Top:Integer;sText:WideString);
var
   r: TRect;
   sz: TSize;
begin
     with Canvas do
     begin
          TextSizeW(Canvas,sText,sz);
          r:=Rect(Left,Top,Left+sz.cx,Top+sz.cy);
          DrawTextW(Handle,PWideChar(sText),Length(sText),r,DT_CENTER);
     end;
end;

procedure TFMain.FormPaint(Sender: TObject);
begin
     with Canvas do
     begin
          Brush.Style:=bsClear;
          with Font do
          begin
               Name:='Times New Roman';
               Size:=40;
               Color:=clGreen;
          end;
     end;
     TulisUnicode(Canvas,10,10,arbBasmalah);
     Canvas.Font.Color:=clMaroon;
     TulisUnicode(Canvas,10,100,arbImam);
end;

end.

Kalo males ngoding sendiri, boleh langsung download aja disini

https://www.box.com/s/kbax7j9xur8ienj8v3vw

Catatan:
Telah diuji menggunakan Turbo Delphi 2006 dan Delphi 7
Tools untuk mempermudah generate array akan di posting menyusul

== Semoga Bermanfaat ==

Sumber mengenai UNICODE dapat dibaca di

http://edn.embarcadero.com/article/38437
http://en.wikipedia.org/wiki/Unicode
http://id.wikipedia.org/wiki/Unicode

RTLVersion Constant, solusi conditional defines yang lebih baik

Pada setiap perkembangan versi delphi tentunya terdapat fitur-fitur baru yang ada kalanya tidak kompatibel dengan versi sebelumnya.
Pada saat tertentu kita perlu membuat aplikasi menggunakan Turbo Delphi 2006 namun disaat yang lain kita ingin aplikasi tersebut dapat juga di compile menggunakan Delphi 7.

Sebagai contoh, pada project Delphi 2007 keatas ada property Application.MainFormOnTaskbar, yang mana akan terjadi error bila dicompile menggunakan Delphi 2006 kebawah.

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(...., ....);
  Application.Run;
end.

Perbedaan lain adalah type variable PChar, yang pada pada delphi yang unicode (Delphi 2009 keatas) adalah sama dengan WideChar sementara pada Delphi versi sebelumnya PChar sama dengan AnsiChar.

Untuk dapat membuat aplikasi yang dapat dikompilasi dengan berbagai macam versi delphi solusinya kita dapat menggunakan Conditional Define.

Condition Define yang banyak dipakai menggunakan {$IFDEF VERxxx} seperti contoh berikut ini

{$IFDEF VER210}
{$DEFINE D2010}
{$DEFINE D2009}
{$DEFINE D2007}
{$DEFINE D2006}
{$DEFINE D2005}
{$DEFINE DELPHI6UP}
{$DEFINE DELPHI7UP}
{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$DEFINE SPLASH}
{$ENDIF}

{$IFDEF VER200}
{$DEFINE D2009}
{$DEFINE D2007}
{$DEFINE D2006}
{$DEFINE D2005}
{$DEFINE DELPHI6UP}
{$DEFINE DELPHI7UP}
{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$DEFINE SPLASH}
{$ENDIF}

{$IFDEF VER185}
{$DEFINE D2007}
{$DEFINE D2006}
{$DEFINE D2005}
{$DEFINE DELPHI6UP}
{$DEFINE DELPHI7UP}
{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$DEFINE SPLASH}
{$ENDIF}

{$IFDEF VER180}
{$DEFINE D2006}
{$DEFINE D2005}
{$DEFINE DELPHI6UP}
{$DEFINE DELPHI7UP}
{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$DEFINE SPLASH}
{$ENDIF}

{$IFDEF VER170}
{$DEFINE D2005}
{$DEFINE DELPHI6UP}
{$DEFINE DELPHI7UP}
{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$DEFINE SPLASH}
{$ENDIF}

{$IFDEF VER150}
{$DEFINE COMPILER7}
{$IFDEF BCB}
{$DEFINE BCB7}
{$DEFINE BCB}
{$DEFINE DELPHI6UP}
{$ELSE}
{$DEFINE DELPHI7}
{$DEFINE DELPHI}
{$DEFINE DELPHI6UP}
{$DEFINE DELPHI7UP}
{$ENDIF}
{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}
{$ENDIF}

Kelemahan dari cara diatas adalah bila kita menggunakan Delphi diatas Delphi 2010, compiler akan menganggap kita menggunakan Delphi 7 kebawah, tentunya hal ini akan berakibat yg tidak kita harapkan.
Solusi terbaik kita dapat menggunakan Konstanta RTLVersion.
Pada contoh berikut akan menghasilkan kode yang berbeda jika dicompile menggunakan Delphi dibawah Delphi 2006.

procedure TForm1.Button1Click(Sender: TObject);
begin
{$IF RTLVersion>=18}
ShowMessage('Anda menggunakan Delphi 2006 keatas');
{$ELSE}
ShowMessage('Upgrade Delphi anda untuk mendukung versi baru');
{$IFEND}
end;

Contoh lain

{$R *.res}

begin
  Application.Initialize;
{$IF RTLVersion>=18.5}
  Application.MainFormOnTaskbar := True;
{$IFEND}
  Application.CreateForm(...., ....);
  Application.Run;
end.

Berikut ini daftar kontanta masing-masing versi Delphi.

VERxxx RTLVersion Delphi Version
VER140 14 Delphi 6
VER150 15 Delphi 7
VER160 16 Delphi 8, BDS 2.0
VER170 17 Delphi 2005, Delphi 9, BDS 3.0
VER180 18 Turbo Delphi, Delphi 2006, Delphi 10, BDS 4.0
VER185 18.5 Delphi 2007, Delphi 11, BDS 5.0
VER200 20 Delphi 2009, Delphi 12, BDS 6.0
VER210 21 Delphi 2010, delphi 13, RAD 7.0
VER220 22 Delphi XE, Delphi 14, RAD 8.0
VER230 23 Delphi XE2, Delphi 15, RAD 9.0
VER240 24 Delphi XE3, Delphi 16, RAD 10.0

Semoga bermanfaat.