Google
 

Friday, July 31, 2009

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:

1.ReplaceResourceString(@SMsgDlgConfirm, 'Konfirmasi Penyimpanan');
2.ReplaceResourceString(@SMsgDlgYes, 'Simpan Perubahan');
3.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:

001.{-----------------------------------------------------------------------------
002.The contents of this file are subject to the Mozilla Public License
003.Version 1.1 (the "License"); you may not use this file except in compliance
004.with the License. You may obtain a copy of the License at
006.
007.Software distributed under the License is distributed on an "AS IS" basis,
008.WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
009.the specific language governing rights and limitations under the License.
010.
011.The Original Code is: CustomMessageDlgDemoUnit.pas, released on 2008-08-05
012.
013.The Initial Developer of the Original Code is Bayu Prasetio
014.Portions created by Bayu Prasetio are Copyright (C) 2007, 2008 Bayu Prasetio.
015.All Rights Reserved.
016.-----------------------------------------------------------------------------}
017.
018.{-----------------------------------------------------------------------------
019. Perhatian :
020. Apa yang tertera pada kode sumber ini sebaiknya dipahami terlebih dahulu,
021. jangan asal 'copy-paste' dan melakukan protes jika tidak sesuai dengan
022. keinginan.
023.
024. Yang perlu saya tekankan adalah, bahwa materi yang terdapat dalam kode
025. sumber ini sekedar demo, 'proof-of-concept' untuk mendukung eksplorasi
026. lanjutan dari 'Meng-Indonesia-kan MessageDlg' sampai ke batas yang Anda
027. tentukan sendiri berdasarkan imajinasi dan kreativitas Anda. Ingat, demo
028. ini belum optimal dan terbaik. Dan tentu saja harapan saya adalah Anda
029. dapat mengeksplorasi dan mengembangkan jauh lebih baik dari yang ada di
030. demo ini.
031.
032. Kelemahan mendasar adalah:
033. - Ukuran tombol hanya berubah pada saat 'ReplaceResourceString' pertama,
034. pemanggilan berikutnya tidak mengubah ukuran tombol
035.-----------------------------------------------------------------------------}
036.
037.unit CustomMessageDlgDemoUnit;
038.
039.interface
040.
041.uses
042. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
043. Dialogs, StdCtrls, ComCtrls;
044.
045.type
046. TfrmCustomMessageDlg = class(TForm)
047. btnStandard: TButton;
048. btnIndonesian: TButton;
049. btnContextSave: TButton;
050. mmoLegend: TMemo;
051. stbMain: TStatusBar;
052. btnContextPrint: TButton;
053. procedure btnStandardClick(Sender: TObject);
054. procedure btnIndonesianClick(Sender: TObject);
055. procedure btnContextSaveClick(Sender: TObject);
056. procedure btnContextPrintClick(Sender: TObject);
057. private
058. { Private declarations }
059. procedure ReplaceResourceString(RStringRec: PResStringRec; AString: PChar);
060. procedure SetCustomMessageStandard;
061. procedure SetCustomMessageIndonesian;
062. procedure SetCustomMessageContextSave;
063. procedure SetCustomMessageContextPrint;
064. public
065. { Public declarations }
066. end;
067.
068.var
069. frmCustomMessageDlg: TfrmCustomMessageDlg;
070.
071.implementation
072.
073.{$R *.dfm}
074.
075.uses
076. Consts;
077.
078.const
079. // konstanta default untuk MessageDlg
080. _SMsgDlgWarning = 'Warning';
081. _SMsgDlgError = 'Error';
082. _SMsgDlgInformation = 'Information';
083. _SMsgDlgConfirm = 'Confirm';
084. _SMsgDlgYes = '&Yes';
085. _SMsgDlgNo = '&No';
086. _SMsgDlgOK = 'OK';
087. _SMsgDlgCancel = 'Cancel';
088. _SMsgDlgHelp = '&Help';
089. _SMsgDlgHelpNone = 'No help available';
090. _SMsgDlgHelpHelp = 'Help';
091. _SMsgDlgAbort = '&Abort';
092. _SMsgDlgRetry = '&Retry';
093. _SMsgDlgIgnore = '&Ignore';
094. _SMsgDlgAll = '&All';
095. _SMsgDlgNoToAll = 'N&o to All';
096. _SMsgDlgYesToAll = 'Yes to &All';
097.
098. // konstanta MessageDlg untuk Bahasa Indonesia
099. _SMsgDlgWarningIndonesian = 'Peringatan';
100. _SMsgDlgErrorIndonesian = 'Kesalahan';
101. _SMsgDlgInformationIndonesian = 'Informasi';
102. _SMsgDlgConfirmIndonesian = 'Konfirmasi';
103. _SMsgDlgYesIndonesian = '&Ya';
104. _SMsgDlgNoIndonesian = '&Tidak';
105. _SMsgDlgOKIndonesian = 'OK';
106. _SMsgDlgCancelIndonesian = 'Batal';
107. _SMsgDlgHelpIndonesian = '&Panduan';
108. _SMsgDlgHelpNoneIndonesian = 'Panduan tidak tersedia';
109. _SMsgDlgHelpHelpIndonesian = 'Panduan';
110. _SMsgDlgAbortIndonesian = '&Batal';
111. _SMsgDlgRetryIndonesian = '&Ulang';
112. _SMsgDlgIgnoreIndonesian = 'A&cuh';
113. _SMsgDlgAllIndonesian = '&Semua';
114. _SMsgDlgNoToAllIndonesian = 'T&idak untuk Semua';
115. _SMsgDlgYesToAllIndonesian = 'Ya untuk S&emua';
116.
117. // konstanta MessageDlg untuk konteks Pencetakan
118. // yang digunakan adalah konfirmasi, mbOK, mbYes dan mbNo
119. _SMsgDlgWarningContextPrint = 'Peringatan';
120. _SMsgDlgErrorContextPrint = 'Kesalahan';
121. _SMsgDlgInformationContextPrint = 'Informasi';
122. _SMsgDlgConfirmContextPrint = 'Konfirmasi Tujuan Pencetakan';
123. _SMsgDlgYesContextPrint = '&Printer';
124. _SMsgDlgNoContextPrint = 'Dokumen PD&F Lebar Yak';
125. _SMsgDlgOKContextPrint = '&Layar';
126. _SMsgDlgCancelContextPrint = 'Batal';
127. _SMsgDlgHelpContextPrint = '&Panduan';
128. _SMsgDlgHelpNoneContextPrint = 'Panduan tidak tersedia';
129. _SMsgDlgHelpHelpContextPrint = 'Panduan';
130. _SMsgDlgAbortContextPrint = '&Batal';
131. _SMsgDlgRetryContextPrint = '&Ulang';
132. _SMsgDlgIgnoreContextPrint = 'A&cuh';
133. _SMsgDlgAllContextPrint = '&Semua';
134. _SMsgDlgNoToAllContextPrint = 'T&idak untuk Semua';
135. _SMsgDlgYesToAllContextPrint = 'Ya untuk S&emua';
136.
137. // konstanta MessageDlg untuk konteks Penyimpanan
138. // yang digunakan adalah konfirmasi, mbYes dan mbNo
139. _SMsgDlgWarningContextSave = 'Peringatan';
140. _SMsgDlgErrorContextSave = 'Kesalahan';
141. _SMsgDlgInformationContextSave = 'Informasi';
142. _SMsgDlgConfirmContextSave = 'Konfirmasi Penyimpanan';
143. _SMsgDlgYesContextSave = '&Simpan';
144. _SMsgDlgNoContextSave = '&Lanjut Saja';
145. _SMsgDlgOKContextSave = 'OK';
146. _SMsgDlgCancelContextSave = 'Batal';
147. _SMsgDlgHelpContextSave = '&Panduan';
148. _SMsgDlgHelpNoneContextSave = 'Panduan tidak tersedia';
149. _SMsgDlgHelpHelpContextSave = 'Panduan';
150. _SMsgDlgAbortContextSave = '&Batal';
151. _SMsgDlgRetryContextSave = '&Ulang';
152. _SMsgDlgIgnoreContextSave = 'A&cuh';
153. _SMsgDlgAllContextSave = '&Semua';
154. _SMsgDlgNoToAllContextSave = 'T&idak untuk Semua';
155. _SMsgDlgYesToAllContextSave = 'Ya untuk S&emua';
156.
157.procedure TfrmCustomMessageDlg.btnContextPrintClick(Sender: TObject);
158.begin
159. SetCustomMessageContextPrint;
160.end;
161.
162.procedure TfrmCustomMessageDlg.btnContextSaveClick(Sender: TObject);
163.begin
164. SetCustomMessageContextSave;
165.end;
166.
167.procedure TfrmCustomMessageDlg.btnIndonesianClick(Sender: TObject);
168.begin
169. SetCustomMessageIndonesian;
170.end;
171.
172.procedure TfrmCustomMessageDlg.btnStandardClick(Sender: TObject);
173.begin
174. SetCustomMessageStandard;
175.end;
176.
177.{-- taken from bpCodeReplacement.pas by Bayu Prasetio}
178.procedure TfrmCustomMessageDlg.ReplaceResourceString(RStringRec: PResStringRec;
179. AString: PChar);
180.var
181. OldProtect: Cardinal;
182.begin
183. if RStringRec = nil then Exit;
184. if VirtualProtectEx(GetCurrentProcess, RStringRec, SizeOf(RStringRec^), PAGE_EXECUTE_READWRITE, OldProtect) then
185. begin
186. RStringRec^.Identifier := Integer(AString);
187. VirtualProtectEx(GetCurrentProcess, RStringRec, SizeOf(RStringRec^), OldProtect, @OldProtect);
188. end;
189.end;
190.
191.procedure TfrmCustomMessageDlg.SetCustomMessageContextPrint;
192.begin
193. // sebagai contoh, ubah resource string untuk MessageDlg berdasarkan konteks kejadian
194. // dalam hal ini adalah proses pencetakan
195. // mbOK disetarakan tayang ke layar (preview)
196. // mbYes disetarakan cetak ke printer
197. // mbNo disetarakan cetak ke dokumen PDF
198. ReplaceResourceString(@SMsgDlgConfirm, _SMsgDlgConfirmContextPrint);
199. ReplaceResourceString(@SMsgDlgYes, _SMsgDlgYesContextPrint);
200. ReplaceResourceString(@SMsgDlgNo, _SMsgDlgNoContextPrint);
201. ReplaceResourceString(@SMsgDlgOK, _SMsgDlgOKContextPrint);
202.
203. // gunakan ModalResult dari MessageDlg untuk menentukan tindakan selanjutnya
204. // hati - hati, Anda tidak dapat menggunakan ShowMessage sekehendak hati
205. // karena ShowMessage sebenarnya MessageDlg dengan parameter MessageType mtInformation
206. // dan Buttons [mbOK]. Pahamkan mengapa tombol 'OK' berubah menjadi 'Layar' ?
207. case MessageDlg('Tentukan tujuan pencetakan dokumen ?', mtConfirmation, [mbOK, mbYes, mbNo], 0) of
208. mrOK : ShowMessage('Dokumen ditayangkan ke layar');
209. mrYes : ShowMessage('Dokumen dicetak ke printer');
210. mrNo : ShowMessage('Dokumen disimpan dalam format .PDF');
211. end;
212.end;
213.
214.procedure TfrmCustomMessageDlg.SetCustomMessageContextSave;
215.begin
216. // sebagai contoh, ubah resource string untuk MessageDlg berdasarkan konteks kejadian
217. // dalam hal ini adalah proses simpan
218. ReplaceResourceString(@SMsgDlgConfirm, _SMsgDlgConfirmContextSave);
219. ReplaceResourceString(@SMsgDlgYes, _SMsgDlgYesContextSave);
220. ReplaceResourceString(@SMsgDlgNo, _SMsgDlgNoContextSave);
221. ReplaceResourceString(@SMsgDlgCancel, _SMsgDlgCancelContextSave);
222.
223. MessageDlg('Anda Yakin akan menyimpan dokumen ini ?', mtConfirmation, mbYesNoCancel, 0);
224.end;
225.
226.procedure TfrmCustomMessageDlg.SetCustomMessageIndonesian;
227.begin
228. // ubah semua resource string untuk MessageDlg ke bahasa Indonesia
229. ReplaceResourceString(@SMsgDlgWarning, _SMsgDlgWarningIndonesian);
230. ReplaceResourceString(@SMsgDlgError, _SMsgDlgErrorIndonesian);
231. ReplaceResourceString(@SMsgDlgInformation, _SMsgDlgInformationIndonesian);
232. ReplaceResourceString(@SMsgDlgConfirm, _SMsgDlgConfirmIndonesian);
233. ReplaceResourceString(@SMsgDlgYes, _SMsgDlgYesIndonesian);
234. ReplaceResourceString(@SMsgDlgNo, _SMsgDlgNoIndonesian);
235. ReplaceResourceString(@SMsgDlgOK, _SMsgDlgOKIndonesian);
236. ReplaceResourceString(@SMsgDlgCancel, _SMsgDlgCancelIndonesian);
237. ReplaceResourceString(@SMsgDlgHelp, _SMsgDlgHelpIndonesian);
238. ReplaceResourceString(@SMsgDlgHelpNone, _SMsgDlgHelpNoneIndonesian);
239. ReplaceResourceString(@SMsgDlgHelpHelp, _SMsgDlgHelpHelpIndonesian);
240. ReplaceResourceString(@SMsgDlgAbort, _SMsgDlgAbortIndonesian);
241. ReplaceResourceString(@SMsgDlgRetry, _SMsgDlgRetryIndonesian);
242. ReplaceResourceString(@SMsgDlgIgnore, _SMsgDlgIgnoreIndonesian);
243. ReplaceResourceString(@SMsgDlgAll, _SMsgDlgAllIndonesian);
244. ReplaceResourceString(@SMsgDlgNoToAll, _SMsgDlgNoToAllIndonesian);
245. ReplaceResourceString(@SMsgDlgYesToAll, _SMsgDlgYesToAllIndonesian);
246.
247. MessageDlg('Anda Yakin akan menyimpan dokumen ini ?', mtConfirmation, mbYesNoCancel, 0);
248.end;
249.
250.procedure TfrmCustomMessageDlg.SetCustomMessageStandard;
251.begin
252. // ubah semua resource string untuk MessageDlg ke default
253. ReplaceResourceString(@SMsgDlgWarning, _SMsgDlgWarning);
254. ReplaceResourceString(@SMsgDlgError, _SMsgDlgError);
255. ReplaceResourceString(@SMsgDlgInformation, _SMsgDlgInformation);
256. ReplaceResourceString(@SMsgDlgConfirm, _SMsgDlgConfirm);
257. ReplaceResourceString(@SMsgDlgYes, _SMsgDlgYes);
258. ReplaceResourceString(@SMsgDlgNo, _SMsgDlgNo);
259. ReplaceResourceString(@SMsgDlgOK, _SMsgDlgOK);
260. ReplaceResourceString(@SMsgDlgCancel, _SMsgDlgCancel);
261. ReplaceResourceString(@SMsgDlgHelp, _SMsgDlgHelp);
262. ReplaceResourceString(@SMsgDlgHelpNone, _SMsgDlgHelpNone);
263. ReplaceResourceString(@SMsgDlgHelpHelp, _SMsgDlgHelpHelp);
264. ReplaceResourceString(@SMsgDlgAbort, _SMsgDlgAbort);
265. ReplaceResourceString(@SMsgDlgRetry, _SMsgDlgRetry);
266. ReplaceResourceString(@SMsgDlgIgnore, _SMsgDlgIgnore);
267. ReplaceResourceString(@SMsgDlgAll, _SMsgDlgAll);
268. ReplaceResourceString(@SMsgDlgNoToAll, _SMsgDlgNoToAll);
269. ReplaceResourceString(@SMsgDlgYesToAll, _SMsgDlgYesToAll);
270.
271. MessageDlg('Anda Yakin akan menyimpan dokumen ini ?', mtConfirmation, mbYesNoCancel, 0);
272.end;
273.
274.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.

No comments: