הדרך הנפוצה ביותר להזיז חלון היא לגרור אותו ליד שורת הכותרת שלה. המשך לקרוא כדי לגלות כיצד אתה יכול לספק יכולות גרירה עבור דלףi טפסים ללא שורת כותרות, כך שהמשתמש יכול להזיז טופס על ידי לחיצה בכל מקום באזור הלקוח.
לדוגמא, שקלו את המקרה של א יישום חלונות שאין בו שורת כותרות, איך נוכל להזיז חלון כזה? למעשה, ניתן ליצור חלונות עם סרגל כותרות לא סטנדרטי ואפילו טפסים לא מלבניים. במקרה זה, כיצד יכולה Windows לדעת היכן נמצאים הגבולות ופינות החלון?
הודעת Windows_N WMitCHTest
ה מערכת הפעלה של חלונות מבוסס בכבדות טיפול בהודעות. לדוגמה, כשאתה לוחץ על חלון או פקד, Windows שולח לו הודעת wm_LButtonDown, עם מידע נוסף על היכן נמצא סמן העכבר ואילו מקשי בקרה נמצאים כעת לחוץ. נשמע מוכר? כן, זה לא יותר מאירוע OnMouseDown בדלפי.
באופן דומה, Windows שולחת הודעת wm_NCHitTest בכל פעם ש אירוע עכבר מתרחשת, כלומר כאשר הסמן זז, או כאשר לחיצת עכבר נלחצת או משתחררת.
קוד להזנה
אם אנו יכולים לגרום לחלונות לחשוב שהמשתמש גורר (לחץ עליו) על שורת הכותרת ולא על אזור הלקוח, המשתמש יכול היה לגרור את החלון על ידי לחיצה באזור הלקוח. הדרך הקלה ביותר לעשות זאת היא "לשטות" בחלונות לחשוב שאתה בעצם לוחץ על סרגל הכותרת של טופס. הנה מה שעליך לעשות:
1. הכנס את השורה הבאה לסעיף 'הצהרות פרטיות' בטופס שלך (הצהרת נוהל טיפול בהודעות):
תהליך WMNCHitTest (var מס ': TWMNCHitTest); הודעה WM_NCHitTest;
2. הוסף את הקוד הבא לקטע "יישום" ביחידת הטופס שלך (כאשר טופס 1 הוא שם הטופס ההנחה):
תהליך TForm1.WMNCHitTest (var מס ': TWMNCHitTest);
התחל
ירש;
אם מסג. תוצאה = htClient לאחר מכן מסג. תוצאה: = htCaption;
סוף;
שורת הקוד הראשונה במטפל ההודעות קוראת לשיטה שעברה בירושה כדי להשיג את הטיפול המוגדר כברירת מחדל עבור הודעת wm_NCHitTest. החלק אם ההליך מיירט ומשנה את התנהגות החלון שלך. זה מה שקורה בפועל: כאשר מערכת ההפעלה שולחת הודעת wm_NCHitTest לחלון, יחד עם קואורדינטות העכבר, החלון מחזיר קוד שמציין איזה חלק מעצמו נפגע. המידע החשוב, למשימתנו, הוא בערך ה- Msg. שדה תוצאה. בשלב זה יש לנו הזדמנות לשנות את תוצאת ההודעה.
זה מה שאנחנו עושים: אם המשתמש לחץ על הלקוח של הטופס, אנו גורמים ל- Windows לחשוב שהמשתמש לחץ על שורת הכותרת. בתוך אובייקט פסקל "מילים": אם ערך החזרת ההודעה הוא HTCLIENT, אנו פשוט משנים אותו ל- HTCAPTION.
אין עוד אירועי עכבר
על ידי שינוי התנהגות ברירת המחדל של הטפסים שלנו, אנו מסירים את היכולת של Windows להודיע לך כאשר העכבר נמצא מעל אזור הלקוח. אחת מתופעות הלוואי של הטריק הזה היא שהטופס שלך כבר לא יפיק אירועים לעכבר הודעות.
חלון ללא כיתוב
אם ברצונך חלון ללא גבולות כותרות הדומה לסרגל כלים צף, קבע את הכיתוב של הטופס למחרוזת ריקה, השבת את כל מספרי הגבול והגדר את BorderStyle ל- bsNone.
ניתן לשנות טופס בדרכים שונות על ידי החלת קוד מותאם אישית בשיטת CreateParams.
טריקים נוספים של WM_NCHit
אם אתה מסתכל בזהירות על הודעת wm_NCHitTest תראה שערך ההחזרה של הפונקציה מציין את מיקום הנקודה החמה של הסמן. זה מאפשר לנו לשחק קצת יותר עם ההודעה כדי ליצור תוצאות משונות.
שבר הקוד הבא ימנע ממשתמשים לסגור את הטפסים שלך על ידי לחיצה על כפתור הסגירה.
אם מסג. תוצאה = htClose לאחר מכן מסג. תוצאה: = htNowhere;
אם המשתמש מנסה להזיז את הטופס על ידי לחיצה על סרגל הכותרות וגרירתו, הקוד מחליף את תוצאת ההודעה בתוצאה שמציינת שהמשתמש לחץ על אזור הלקוח. זה מונע מהמשתמש להזיז את החלון עם העכבר (בניגוד למה שאנחנו עשינו בתחנונים של המאמר).
אם מסג. תוצאה = כיתוב לאחר מכן מסג. תוצאה: = htClient;
בעל רכיבים בטופס
ברוב המקרים, יהיו לנו כמה רכיבים בטופס. נניח, למשל, שאובייקט פאנל אחד נמצא על גבי טופס. אם מאפיין יישור של לוח מוגדר ל- alClient, הלוח ממלא את כל אזור הלקוח כך שאי אפשר לבחור את טופס האב על ידי לחיצה עליו. הקוד שלמעלה לא יעבוד - מדוע? הסיבה לכך היא שהעכבר תמיד נע על רכיב הפאנל ולא על הטופס.
כדי להזיז את הטופס שלנו על ידי גרירת פאנל בטופס עלינו להוסיף כמה שורות קוד בהליך האירוע OnMouseDown עבור רכיב הפאנל:
תהליך TForm1.Panel1MouseDown
(שולח: נושא; כפתור: TMouseButton;
Shift: TShiftState; X, Y: מספר שלם);
התחל
ReleaseCapture;
SendMessage (Form1.Handle, WM_SYSCOMMAND, 61458, 0);
סוף;
הערה: קוד זה לא יעבוד עם בקרות שאינן חלונות כגון רכיבי Tabel.