TDateTimePicker mendapatkan properti Format di suatu tempat antara Delphi 5 dan Delphi 6. Batas versi yang tepat jarang didokumentasikan dengan cara yang dapat dipercaya, dan ketika Anda menemukannya, kompiler hanya memberi tahu Anda bahwa pengenal tidak ada. Baris yang dikompilasi dan berfungsi di setiap Delphi baru yang Anda miliki gagal secara diam-diam atau langsung pada versi lama, tergantung bagaimana proyek terstruktur
Kontrol yang mendasarinya adalah common control Windows DATETIMEPICK_CLASS dari comctl32.dll, dan selalu menerima format string melalui pesan DTM_SETFORMAT. VCL Delphi membungkus pesan itu dalam properti Format pada versi yang lebih baru. Di Delphi 5, Anda mengirim pesannya sendiri melalui wrapper makro DateTime_SetFormat yang dideklarasikan di CommCtrl
Pola kompilasi kondisional
Pendekatan standar adalah blok kondisional kompiler yang dikunci pada simbol versi. Delphi 5 mendefinisikan VER130; Anda dapat mengujinya secara langsung atau mendefinisikan simbol D5 Anda sendiri di opsi proyek untuk membuat label cabang lebih mudah dibaca di seluruh codebase. Bagaimanapun, cabang Delphi 5 memanggil DateTime_SetFormat dengan handle kontrol; setiap cabang lain menetapkan properti:
{$IFDEF D5}
DateTime_SetFormat(DateTimePicker1.Handle, PChar('MM/dd/yyyy'));
{$ELSE}
DateTimePicker1.Format := 'MM/dd/yyyy';
{$ENDIF}
Tambahkan CommCtrl ke klausa uses untuk unit yang berisi cabang Delphi 5. Tidak perlu menambahkannya secara tanpa syarat; jika Anda lebih suka menjaga cakupan dependensi, bungkus entri uses dalam kondisional yang sama:
uses
...,
{$IFDEF D5}
CommCtrl,
{$ENDIF}
...;
Sintaks format string
Format string yang dilewatkan ke DateTime_SetFormat mengikuti format date-time picker Windows, bukan token FormatDateTime Delphi. Keduanya terlihat mirip tetapi tidak dapat dipertukarkan. Windows menggunakan d untuk hari-dalam-bulan (tanpa nol di depan), dd untuk hari dengan padding nol, M untuk nomor bulan, MM untuk bulan dengan padding nol, yy untuk tahun dua digit, dan yyyy untuk tahun empat digit. Kolom waktu menggunakan h/hh untuk jam 12 jam, H/HH untuk jam 24 jam, m/mm untuk menit, s/ss untuk detik. Teks literal ditempatkan di dalam tanda kutip tunggal di dalam format string, jadi 'dd/MM/yyyy' sudah benar, tetapi 'dd '<literal>' MM' akan memerlukan pasangan tanda kutip tunggal yang disematkan
FormatDateTime Delphi, sebaliknya, menggunakan d/dd/ddd/dddd untuk bentuk hari dengan semantik berbeda, dan m untuk bulan (bukan M). Jika Anda menyalin format string dari panggilan FormatDateTime dan langsung menyerahkannya ke DateTime_SetFormat, kolom bulan dan menit kemungkinan akan tertukar dalam output. Tulis format string kontrol dari awal berdasarkan dokumentasi Windows alih-alih mengonversi dari format Delphi
Pengaturan regional dan ShortDateFormat global
Mengubah variabel ShortDateFormat global Delphi tidak memengaruhi TDateTimePicker yang sudah dibuat. Picker membaca pengaturan regional dari Windows saat pembuatan dan setelahnya merender sesuai pesan yang diterimanya, bukan global RTL Delphi. Itu berarti mengatur ShortDateFormat di FormCreate tidak akan mengubah tampilan kontrol. Anda memerlukan DateTime_SetFormat (atau properti Format di Delphi yang lebih baru) untuk mengganti format string kontrol sendiri setelah handle ada
Untuk aplikasi yang di-deploy secara internasional, uji format string di mesin dengan pengaturan regional non-AS. Windows dapat mengganti format string kosong atau nil dengan default locale, tetapi string non-nil yang eksplisit menggantikan pengaturan regional sepenuhnya. Itu biasanya yang Anda inginkan, tetapi berarti pola yang berpusat pada AS seperti 'MM/dd/yyyy' akan muncul apa adanya bagi pengguna yang mengharapkan konvensi dd/MM/yyyy. Jika date picker menghadap pengguna alih-alih field entri data murni, pertimbangkan untuk membiarkan kontrol menggunakan default (lewatkan nil ke DateTime_SetFormat) agar mengikuti locale pengguna secara otomatis
Recreasi handle
Pengaturan format dimiliki oleh window handle, bukan oleh field objek VCL mana pun. Jika handle kontrol dihancurkan dan dibuat ulang, yang dapat dilakukan VCL saat Anda menyematkan ulang kontrol atau mengubah properti style tertentu pada saat runtime, format kembali ke default Windows. Tempat yang aman untuk menerapkan DateTime_SetFormat adalah di handler yang berjalan setelah pembuatan handle: timpa CreateWnd di kelas turunan dan panggil di sana, atau terapkan di event OnEnter atau OnShow hanya setelah mengonfirmasi handle aktif. Mengaturnya sekali di FormCreate sering kali cukup untuk form sederhana, tetapi tidak andal jika form melakukan peralihan style dinamis atau re-parenting kontrol
Kendala yang sama berlaku untuk properti VCL Format di versi Delphi yang lebih baru; secara internal memanggil pesan Windows yang sama dan menghadapi siklus handle yang sama. Perbedaannya adalah setter properti VCL memeriksa apakah handle dialokasikan sebelum memanggil, dan menerapkan ulang format secara otomatis pada CreateWnd. Panggilan DateTime_SetFormat mentah tidak memiliki perlindungan seperti itu, sehingga cabang Delphi 5 perlu lebih berhati-hati tentang kapan ia berjalan
Menghapus solusi sementara
Ketika sebuah proyek meninggalkan dukungan Delphi 5, blok kondisional menjadi bobot mati. Hapus cabang {$IFDEF D5} dan impor CommCtrl yang lingkupnya, tinggalkan hanya penugasan properti Format langsung. Simpan penghapusan dalam satu commit agar mudah diidentifikasi jika sesuatu yang tidak terduga rusak di kompiler yang belum Anda uji. Format string itu sendiri tetap sama; hanya mekanisme pengirimannya yang berubah