TDateTimePicker קיבל מאפיין Format איפשהו בין Delphi 5 ל-Delphi 6. גבול הגרסה המדויק נדיר שמתועד בדרך שניתן לסמוך עליה, וכאשר אתה נתקל בו, המהדר פשוט אומר לך שהמזהה אינו קיים. השורה שעוברת הידור ועובדת בכל Delphi חדש יותר שיש לך נכשלת בשקט או לחלוטין בגרסה הישנה, תלוי באופן שבו הפרויקט מובנה
הפקד הבסיסי הוא הפקד הנפוץ של Windows DATETIMEPICK_CLASS מ-comctl32.dll, והוא תמיד קיבל מחרוזת עיצוב דרך הודעת DTM_SETFORMAT. ה-VCL של Delphi עוטף את ההודעה הזו במאפיין Format בגרסאות חדשות יותר. ב-Delphi 5, אתה שולח את ההודעה בעצמך דרך מעטפת המאקרו DateTime_SetFormat המוצהרת ב-CommCtrl
תבנית ההידור המותנה
הגישה הסטנדרטית היא בלוק הידור מותנה המבוסס על סמל גרסה. Delphi 5 מגדיר VER130; אתה יכול לבדוק מולו ישירות או להגדיר סמל D5 משלך באפשרויות הפרויקט כדי להפוך את תווית הענף לקריאה יותר ברחבי בסיס הקוד. כך או כך, ענף Delphi 5 קורא ל-DateTime_SetFormat עם ידית הפקד (control handle); כל ענף אחר מקצה את המאפיין:
{$IFDEF D5}
DateTime_SetFormat(DateTimePicker1.Handle, PChar('MM/dd/yyyy'));
{$ELSE}
DateTimePicker1.Format := 'MM/dd/yyyy';
{$ENDIF}
הוסף את CommCtrl לסעיף ה-uses עבור היחידה המכילה את ענף Delphi 5. אין צורך להוסיף אותו ללא תנאי; אם אתה מעדיף לשמור על תלות מצומצמת, עטוף את רישום ה-uses באותו תנאי:
uses
...,
{$IFDEF D5}
CommCtrl,
{$ENDIF}
...;
תחביר מחרוזת העיצוב
מחרוזת העיצוב המועברת ל-DateTime_SetFormat עוקבת אחר תבנית בוחר התאריך והשעה של Windows, לא אחר האסימונים של FormatDateTime ב-Delphi. השניים נראים דומים אך אינם ניתנים להחלפה זה בזה. Windows משתמש ב-d עבור היום בחודש (ללא אפס מוביל), dd עבור יום מרופד באפס, M עבור מספר החודש, MM עבור חודש מרופד באפס, yy עבור שנה בת שתי ספרות, ו-yyyy עבור שנה בת ארבע ספרות. שדות זמן משתמשים ב-h/hh עבור שעות של 12 שעות, H/HH עבור 24 שעות, m/mm עבור דקות, s/ss עבור שניות. טקסט מילולי (literal) נכנס לתוך גרשיים בודדים בתוך מחרוזת העיצוב, כך ש-'dd/MM/yyyy' כבר נכון, אך 'dd '<literal>' MM' ידרוש זוגות גרשיים בודדים מוטמעים
לעומת זאת, FormatDateTime של Delphi משתמש ב-d/dd/ddd/dddd עבור צורות יום עם סמנטיקה שונה, וב-m עבור חודש (לא M). אם תעתיק מחרוזת עיצוב מקריאה ל-FormatDateTime ותמסור אותה ישירות ל-DateTime_SetFormat, שדות חודש ודקה כנראה יוחלפו בפלט. כתוב את מחרוזת העיצוב של הפקד מאפס אל מול תיעוד Windows במקום להמיר מעיצוב של Delphi
הגדרות אזוריות ו-ShortDateFormat הגלובלי
שינוי המשתנה הגלובלי ShortDateFormat של Delphi אינו משפיע על TDateTimePicker שכבר נוצר. הבוחר קורא הגדרות אזוריות מ-Windows בזמן היצירה ולאחר מכן מרנדר בהתאם להודעות שהוא מקבל, לא למשתנים הגלובליים של RTL ב-Delphi. זה אומר שהגדרת ShortDateFormat ב-FormCreate לא תשנה את מה שהפקד מציג. עליך להשתמש ב-DateTime_SetFormat (או במאפיין Format בגרסאות Delphi חדשות יותר) כדי לעקוף את מחרוזת העיצוב של הפקד עצמו לאחר שהידית (handle) קיימת
עבור יישומים הנפרסים בינלאומית, בדוק את מחרוזת העיצוב במחשב עם הגדרה אזורית שאינה של ארה"ב. Windows יכול לעקוף מחרוזת עיצוב ריקה או nil עם ברירת המחדל של האזור (locale), אך מחרוזת שאינה nil גוברת על ההגדרה האזורית לחלוטין. זה בדרך כלל מה שאתה רוצה, אך משמעות הדבר היא שתבנית ממוקדת ארה"ב כגון 'MM/dd/yyyy' תופיע כפי שהיא למשתמשים שמצפים ל-dd/MM/yyyy לפי המוסכמה. אם בוחר התאריך מיועד למשתמש הקצה ולא כשדה הזנת נתונים טהור, שקול לאפשר לפקד לפעול כברירת מחדל (העבר nil ל-DateTime_SetFormat) כך שיעקוב אחר אזור המשתמש באופן אוטומטי
יצירה מחדש של ידית
הגדרת העיצוב שייכת לידית החלון (window handle), לא לאף שדה אובייקט VCL. אם ידית הפקד נהרסת ונוצרת מחדש, דבר ש-VCL יכול לעשות כאשר אתה משנה את אב הפקד (reparent) או משנה מאפייני סגנון מסוימים בזמן ריצה, העיצוב חוזר לברירת המחדל של Windows. המקום הבטוח להחיל את DateTime_SetFormat הוא במנהל אירועים שרץ לאחר יצירת הידית: עקוף את CreateWnd במחלקת יורשת וקרא לו שם, או החל אותו באירוע OnEnter או OnShow רק לאחר וידוא שהידית חיה. הגדרה פעם אחת ב-FormCreate מספיקה לעתים קרובות עבור טפסים פשוטים, אך אינה אמינה אם הטופס מבצע החלפת סגנון דינמית או שינוי אב של פקדים
אותו אילוץ חל על מאפיין Format ב-VCL בגרסאות חדשות יותר של Delphi; באופן פנימי הוא קורא לאותה הודעת Windows ומתמודד עם אותו מחזור חיים של ידית. ההבדל הוא שמגדיר המאפיין של VCL בודק אם הידית מוקצית לפני הקריאה הלאה, ומחיל מחדש את העיצוב אוטומטית ב-CreateWnd. הקריאה הגולמית ל-DateTime_SetFormat חסרה הגנה כזו, ולכן ענף Delphi 5 צריך להיות שקול יותר לגבי מתי הוא פועל
הסרת המעקף
כאשר פרויקט מפסיק את התמיכה ב-Delphi 5, הבלוק המותנה הופך למשקל מת. הסר את הענף {$IFDEF D5} ואת ייבוא ה-CommCtrl המצומצם, והשאר רק את הקצאת המאפיין Format הישירה. שמור על ההסרה ב-commit בודד כך שיהיה קל לזהות אם משהו נשבר באופן בלתי צפוי על מהדר שלא בדקת. מחרוזת העיצוב עצמה נשארת זהה; רק מנגנון המסירה משתנה