Home > Delphi, Did You Know > Custom MessageDlg

Custom MessageDlg


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.

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.

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.

Lalu bagaimanakah cara agar dapat menampilkan MessageDlg sesuai dengan konteks teks judul dan tombol yang kita inginkan?

Tentu saja cukup mudah!

Cukup panggil method ReplaceResourceString dengan parameter judul, tombol mana yang ingin diubah teks-nya.

Misalnya:

  ReplaceResourceString(@SMsgDlgConfirm, 'Konfirmasi Penyimpanan');
  ReplaceResourceString(@SMsgDlgYes, 'Simpan Perubahan');
  ReplaceResourceString(@SMsgDlgNo, 'Jangan Simpan');

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:

{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); 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 "AS IS" 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 = '&Yes';
  _SMsgDlgNo = '&No';
  _SMsgDlgOK = 'OK';
  _SMsgDlgCancel = 'Cancel';
  _SMsgDlgHelp = '&Help';
  _SMsgDlgHelpNone = 'No help available';
  _SMsgDlgHelpHelp = 'Help';
  _SMsgDlgAbort = '&Abort';
  _SMsgDlgRetry = '&Retry';
  _SMsgDlgIgnore = '&Ignore';
  _SMsgDlgAll = '&All';
  _SMsgDlgNoToAll = 'N&o to All';
  _SMsgDlgYesToAll = 'Yes to &All';

  // konstanta MessageDlg untuk Bahasa Indonesia
  _SMsgDlgWarningIndonesian = 'Peringatan';
  _SMsgDlgErrorIndonesian = 'Kesalahan';
  _SMsgDlgInformationIndonesian = 'Informasi';
  _SMsgDlgConfirmIndonesian = 'Konfirmasi';
  _SMsgDlgYesIndonesian = '&Ya';
  _SMsgDlgNoIndonesian = '&Tidak';
  _SMsgDlgOKIndonesian = 'OK';
  _SMsgDlgCancelIndonesian = 'Batal';
  _SMsgDlgHelpIndonesian = '&Panduan';
  _SMsgDlgHelpNoneIndonesian = 'Panduan tidak tersedia';
  _SMsgDlgHelpHelpIndonesian = 'Panduan';
  _SMsgDlgAbortIndonesian = '&Batal';
  _SMsgDlgRetryIndonesian = '&Ulang';
  _SMsgDlgIgnoreIndonesian = 'A&cuh';
  _SMsgDlgAllIndonesian = '&Semua';
  _SMsgDlgNoToAllIndonesian = 'T&idak untuk Semua';
  _SMsgDlgYesToAllIndonesian = 'Ya untuk S&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 = '&Printer';
  _SMsgDlgNoContextPrint = 'Dokumen PD&F Lebar Yak';
  _SMsgDlgOKContextPrint = '&Layar';
  _SMsgDlgCancelContextPrint = 'Batal';
  _SMsgDlgHelpContextPrint = '&Panduan';
  _SMsgDlgHelpNoneContextPrint = 'Panduan tidak tersedia';
  _SMsgDlgHelpHelpContextPrint = 'Panduan';
  _SMsgDlgAbortContextPrint = '&Batal';
  _SMsgDlgRetryContextPrint = '&Ulang';
  _SMsgDlgIgnoreContextPrint = 'A&cuh';
  _SMsgDlgAllContextPrint = '&Semua';
  _SMsgDlgNoToAllContextPrint = 'T&idak untuk Semua';
  _SMsgDlgYesToAllContextPrint = 'Ya untuk S&emua';

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

Dan sebagai catatan, ada kelemahan yang perlu diketahui perihal trik, yaitu ukuran tombol hanya berubah pada saat ‘ReplaceResourceString’ pertama, pemanggilan berikutnya tidak mengubah ukuran tombol.

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.

Semoga bermanfaat.

Advertisements
  1. August 7, 2008 at 3:09 pm

    @deLogic
    ehmm.. ada yg masih mengganjal dibenakku..
    untuk text di messageDlg, mungkinkah Alignmentnya dibuat menjadi center..
    karena defaultnya kan left.. ????

  2. August 8, 2008 at 7:58 am

    Jika berdasarkan cakupan kode di atas, tentu saja tidak bisa. Namun fitur tsb bisa dilakukan, tentu saja dgn menambah trik lain lagi. Tunggu saja tanggal mainnya.

    Atau jika anda tdk sabar, saya berikan kata kuncinya: Code Redirect dan atau Overloading Function. 🙂

  3. August 11, 2008 at 12:21 pm

    Hehehe.. dengan penuh kesabaran daku menunggu tanggal mainnya..
    absolutely i’ll wait your post 😀

  1. August 12, 2008 at 5:31 pm
  2. August 12, 2008 at 5:32 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: