एक खिड़की को स्थानांतरित करने का सबसे आम तरीका है कि इसे अपने शीर्षक बार द्वारा खींचें। यह जानने के लिए पढ़ें कि आप किस प्रकार ड्रैगिंग क्षमता प्रदान कर सकते हैं delphमैं एक टाइटल बार के बिना बनता हूं, इसलिए उपयोगकर्ता क्लाइंट क्षेत्र पर कहीं भी क्लिक करके एक फॉर्म को स्थानांतरित कर सकता है।
उदाहरण के लिए, ए के मामले पर विचार करें विंडोज एप्लिकेशन इसका शीर्षक बार नहीं है, हम इस तरह की खिड़की को कैसे स्थानांतरित कर सकते हैं? वास्तव में, गैर-मानक शीर्षक पट्टी और यहां तक कि गैर-आयताकार रूपों के साथ खिड़कियां बनाना संभव है। इस मामले में, विंडोज को कैसे पता चल सकता है कि सीमाएं और खिड़की के कोने कहां हैं?
WM_NCHitTest Windows संदेश
विंडोज ऑपरेटिंग सिस्टम पर आधारित है संदेश संभालना. उदाहरण के लिए, जब आप किसी विंडो या नियंत्रण पर क्लिक करते हैं, तो Windows उसे wm_LButtonDown संदेश भेजता है, वर्तमान में माउस कर्सर कहां है और कौन सी नियंत्रण कुंजी है, इसके बारे में अतिरिक्त जानकारी के साथ दब गया। परिचित लगता है? हां, डेल्फी में यह ऑनमॉउजडाउन इवेंट से ज्यादा कुछ नहीं है।
इसी तरह, विंडोज जब भी कोई wm_NCHitTest संदेश भेजता है
माउस घटना तब होता है, जब कर्सर चलता है, या जब माउस बटन दबाया या छोड़ा जाता है।इनपुट के लिए कोड
यदि हम विंडोज को यह सोच सकते हैं कि उपयोगकर्ता क्लाइंट क्षेत्र के बजाय शीर्षक पट्टी को खींच रहा है (क्लिक किया है), तो उपयोगकर्ता ग्राहक क्षेत्र में क्लिक करके विंडो को खींच सकता है। ऐसा करने का सबसे आसान तरीका यह है कि आप वास्तव में एक फॉर्म के टाइटल बार पर क्लिक कर रहे हैं यह सोचकर विंडोज को "मूर्ख" करें। यहाँ आपको क्या करना है:
1. निम्नलिखित फ़ॉर्म को अपने "निजी घोषणाओं" अनुभाग (संदेश हैंडलिंग प्रक्रिया घोषणा) में डालें:
प्रक्रिया WMNCHitTest (वर Msg: TWMNCHitTest); संदेश WM_NCHitTest;
2. अपने फॉर्म की इकाई के "कार्यान्वयन" अनुभाग में निम्नलिखित कोड जोड़ें (जहां फॉर्म 1 मान लिया गया नाम है):
प्रक्रिया TForm1.WMNCHitTest (वर Msg: TWMNCHitTest);
शुरू
विरासत में मिला;
अगर संदेश। परिणाम = htClient फिर संदेश। परिणाम: = htCaption;
समाप्त;
संदेश हैंडलर में कोड की पहली पंक्ति wm_NCHitTest संदेश के लिए डिफ़ॉल्ट हैंडलिंग प्राप्त करने के लिए विरासत में मिली विधि को कॉल करती है। यदि प्रक्रिया का हिस्सा आपकी विंडो के व्यवहार को स्वीकार और बदल देता है। यह वास्तव में ऐसा होता है: जब ऑपरेटिंग सिस्टम विंडो पर wm_NCHitTest संदेश भेजता है, माउस निर्देशांक के साथ मिलकर, विंडो एक कोड देता है जो बताता है कि खुद का कौन सा हिस्सा है मारा गया। हमारे कार्य के लिए जानकारी का महत्वपूर्ण टुकड़ा, Msg के मूल्य में है। परिणाम क्षेत्र। इस बिंदु पर, हमारे पास संदेश परिणाम को संशोधित करने का अवसर है।
यह वही है जो हम करते हैं: यदि उपयोगकर्ता ने फॉर्म के क्लाइंट क्षेत्र में क्लिक किया है, तो हम यह सोचने के लिए विंडोज बनाते हैं कि उपयोगकर्ता ने टाइटल बार पर क्लिक किया है। में ऑब्जेक्ट पास्कल "शब्द": यदि संदेश वापसी मूल्य HTCLIENT है, तो हम बस इसे HTCAPTION में बदल देते हैं।
नो मोर माउस इवेंट्स
अपने प्रपत्रों के डिफ़ॉल्ट व्यवहार को बदलकर हम माउस को क्लाइंट क्षेत्र में होने पर आपको सूचित करने के लिए विंडोज की क्षमता को हटा देते हैं। इस ट्रिक का एक साइड इफेक्ट यह है कि अब आपका फॉर्म जनरेट नहीं होगा माउस के लिए घटनाओं संदेश।
कैप्शनलेस-बॉर्डरलेस विंडो
यदि आप एक फ्लोटिंग टूलबार के समान एक कैप्शन रहित बॉर्डरलेस विंडो चाहते हैं, तो फॉर्म का कैप्शन एक खाली स्ट्रिंग पर सेट करें, सभी BorderIcons को अक्षम करें, और बॉस्सनेल को bsNone पर सेट करें।
CreateParams पद्धति में कस्टम कोड लागू करके एक फॉर्म को विभिन्न तरीकों से बदला जा सकता है।
अधिक WM_NCHitTest ट्रिक्स
यदि आप wm_NCHitTest संदेश को अधिक ध्यान से देखते हैं, तो आप देखेंगे कि फ़ंक्शन का रिटर्न मान कर्सर हॉट स्पॉट की स्थिति को इंगित करता है। यह हमें अजीब परिणाम बनाने के लिए संदेश के साथ कुछ और खेलने में सक्षम बनाता है।
निम्न कोड टुकड़ा उपयोगकर्ताओं को क्लोज बटन पर क्लिक करके आपके फॉर्म को बंद करने से रोकेगा।
अगर संदेश। परिणाम = htClose फिर संदेश। परिणाम: = htNowhere;
यदि उपयोगकर्ता कैप्शन पट्टी पर क्लिक करके और ड्रैग करके फ़ॉर्म को स्थानांतरित करने का प्रयास कर रहा है, तो कोड संदेश के परिणाम को एक परिणाम के साथ बदलता है जो ग्राहक क्षेत्र पर क्लिक किए गए उपयोगकर्ता को इंगित करता है। यह उपयोगकर्ता को माउस के साथ खिड़की को आगे बढ़ने से रोकता है (हम लेख की भीख में जो कर रहे थे उसके विपरीत)।
अगर संदेश। परिणाम = htCaption फिर संदेश। परिणाम: = htClient;
एक फार्म पर घटक होने
ज्यादातर मामलों में, हमारे पास एक फॉर्म में कुछ घटक होंगे। उदाहरण के लिए, मान लें कि एक पैनल ऑब्जेक्ट एक फॉर्म पर है। यदि किसी पैनल की संरेखित संपत्ति को alClient के लिए सेट किया गया है, तो पैनल पूरे क्लाइंट क्षेत्र को भर देता है ताकि उस पर क्लिक करके मूल रूप का चयन करना असंभव हो। उपरोक्त कोड काम नहीं करेगा - क्यों? ऐसा इसलिए है क्योंकि माउस हमेशा पैनल के घटक पर घूम रहा है, न कि फॉर्म पर।
पैनल फॉर्म के लिए OnMouseDown ईवेंट प्रक्रिया में कोड की कुछ पंक्तियों को जोड़ने के लिए हमें एक पैनल को खींचकर अपने फॉर्म को स्थानांतरित करना है:
प्रक्रिया TForm1.Panel1MouseDown
(प्रेषक: Tobject; बटन: TMouseButton;
शिफ्ट: TShiftState; एक्स, वाई: इंटेगर);
शुरू
ReleaseCapture;
SendMessage (Form1.Handle, WM_SYSCOMMAND, 61458, 0);
समाप्त;
ध्यान दें: यह कोड नॉन-विंडो कंट्रोल जैसे काम नहीं करेगा टीलाबेल घटक.