2016-08-19 5 views
5

मैंने कुछ बहुत अजीब देखा है। जब मैं बंद हो रहा हूं, तो मैं फॉर्म के शीर्ष, बाएं, चौड़ाई और ऊंचाई गुणों को कायम रख रहा हूं, और इस जानकारी का उपयोग फॉर्म की आखिरी स्थिति को पुनर्स्थापित करने के लिए कर रहा हूं, जब इसे पहले से संग्रहीत जानकारी का उपयोग करके सेटबाउंड को कॉल करके एक बार फिर खोला जाता है। यह अच्छी तरह से काम करता है, लेकिन केवल तभी जब फॉर्म की स्थिति संपत्ति डिज़ाइन समय पर poDefault पर सेट हो। यदि किसी और चीज पर सेट किया गया है, जैसे poDesigned, poScreenCenter, या poMainFormCenter, SetBounds फॉर्म की पिछली स्थिति और आकार को पुनर्स्थापित नहीं करता है।TForm.SetBounds केवल तभी काम करता है जब TForm.Position डिजाइन समय पर poDefault पर सेट किया गया है

यहां अजीब हिस्सा है। इससे कोई फर्क नहीं पड़ता कि स्थिति संपत्ति डिजाइन स्थिति पर निर्धारित की जाती है। मैं इस संपत्ति का मूल्य रनटाइम पर poDefault पर बदल सकता हूं और सेटबाउंड पर कॉल अभी भी सही तरीके से काम नहीं करता है। मैं दोनों प्रपत्र की OnCreate ईवेंट हैंडलर में, और साथ ही एक ओवरराइड निर्माता से निम्नलिखित

if Self.Position <> poDefault then 
    Self.Position := poDefault; 

की तरह कुछ की कोशिश की है (और OnCreate ईवेंट हैंडलर में निर्माता में poDefault को स्थिति की स्थापना की है, और कहा जाता है SetBounds)। सभी मामलों में, रनटाइम पर poDefault में फॉर्म की स्थिति प्रॉपर्टी को बदलना उस समस्या को ठीक नहीं करता है जिसे मैंने सेटबाउंड के साथ देखा है। मुझे मिला एकमात्र संगत पैटर्न यह है कि सेटबाउंड काम करता है क्योंकि यह केवल तभी होना चाहिए जब फॉर्म की स्थिति संपत्ति डिजाइन समय पर poDefault थी।

अन्य चीजें हैं जिनके बारे में मैंने देखा है कि सेटबाउंड कैसे काम करता है जब किसी फॉर्म की स्थिति संपत्ति डिज़ाइन समय पर poDefault पर सेट नहीं होती है। उदाहरण के लिए, एक फॉर्म जिसका खाता संपत्ति डिज़ाइन समय पर poScreenCenter पर सेट की जाती है, यदि आप सेटबाउंड को कॉल करते हैं तो स्क्रीन पर केंद्रित नहीं होना चाहिए। हालांकि, यह सेटबाउंड द्वारा परिभाषित शीर्ष-बाएं स्थान में दिखाई नहीं देता है, न ही यह सेटबाउंड को कॉल में निर्दिष्ट चौड़ाई और ऊंचाई का सम्मान करता है। हालांकि, मुझे दोहराएं, कि मैं सेटबाउंड को कॉल करने से पहले फॉर्म की स्थिति संपत्ति को poDefault पर सेट कर रहा हूं। मैंने एप्लिकेशन पर एक कॉल भी फंस लिया है। दो ऑपरेशन के बीच प्रोसेस मैसेज, लेकिन इससे समस्या ठीक नहीं होती है।

मैंने विंडोज 10 पर चल रहे डेल्फी 10.1 बर्लिन के साथ बड़े पैमाने पर इसका परीक्षण किया है। मैंने विंडोज 7 पर डेल्फी एक्सई 6 का उपयोग करके इसका परीक्षण भी किया है।

यदि आपको संदेह है, तो चार रूपों के साथ एक वीसीएल आवेदन बनाएं। जहां निर्माता TForm2, तो TForm3 और TForm4 बनाता

with TForm2.Create(nil) do 
try 
    ShowModal; 
finally 
    Release; 
end; 

: पहले फार्म पर तीन बटन रखें, और प्रत्येक बटन के लिए निम्न OnClick की तरह कुछ जोड़ सकते हैं। poScreenCenter को स्थिति सेट form3 पर

if Self.Position <> poDefault then 
    Self.Position := poDefault; 
Self.SetBounds(500,500,500,500); 

Form2 पर, poDefault को स्थिति निर्धारित करते हैं, और form4 पर स्थिति को डिफ़ॉल्ट पर सेट छोड़ देते हैं,:

रूपों 2 की OnCreate पर 4 के माध्यम से, निम्नलिखित कोड जोड़ने poDefaultPosOnly। केवल फॉर्म 2 500, 500 की चौड़ाई और 500 की ऊंचाई के साथ 500, 500 पर दिखाई देगा।

क्या किसी के पास इस परिणाम के लिए तार्किक स्पष्टीकरण है?

+0

'प्रक्रिया CreateParams (var Params: TCreateParams) जोड़ने की कोशिश करें; ओवरराइड; 'फॉर्मेट परिभाषा के _protected_ सेक्शन और विरासत में मिला; यदि स्वयं। स्थिति <> poDefault तो स्व। स्थिति: = poDefault; '_CreateParams_ कार्यान्वयन में। – Miamy

+0

मियामी: CreateParams को ओवरराइड करना, और poDefault को स्थिति सेट करना! बहुत अच्छा! यह जवाब नहीं है (क्योंकि मैं एक स्पष्टीकरण मांग रहा था), लेकिन यह समस्या का एक बहुत अच्छा समाधान है। और, चूंकि मेरे सभी रूपों में एक आम पूर्वज है, इसलिए मैं इस विधि को पूर्वजों में ओवरराइड कर सकता हूं और फिर ऑनक्रेट ईवेंट हैंडलर (या ओवरराइड कन्स्ट्रक्टर) में सेटबाउंड को कॉल करने के लिए स्वतंत्र हो सकता हूं। सलाह के लिये धन्यवाद। –

उत्तर

2

poDefault और दोस्तों का मतलब है "माइक्रोसॉफ्ट विंडोज को इस फॉर्म की विंडो स्थिति दें जब फॉर्म बनायेगा और दिखाएगा"।

आपने अभी डेल्फी ऑब्जेक्ट बनाया है - लेकिन मुझे आश्चर्य है कि यह विंडोज ऑब्जेक्ट (HWND हैंडल और सभी संबंधित विंडोज आंतरिक संरचनाओं को भी बनाया/दिखाया गया है)।विशेष रूप से थीम वाले अनुप्रयोगों के साथ, मानक प्री-एक्सपी लुक और महसूस करने वाले लोग नहीं - वे दिखाते समय ReCreateHWND पर जाते हैं, क्योंकि उन फैंसी विंडोज थीम्स को प्री-लोड करना अपेक्षाकृत महंगी ऑपरेशन है और केवल आवश्यकता होने पर ही किया जाना चाहिए।

मैं अपने डिफ़ॉल्ट सीमा (निर्माता में सेट हर संपत्ति के मूल्य एक डिफ़ॉल्ट गैर देखते मूल्य पर विचार किया जा सकता है, के बाद वस्तु निर्माण किया जा रहा बाद में नियोजित किया जा करने के लिए) सही ढंग से ध्यान नहीं दिया जाता लगता है जब आप (या TApplication - उस के लिए थोड़ा फर्क नहीं पड़ता विषय) अंत में FormXXX.Show करें।

यह "मुझे एक खिड़की बनाओ और इसे प्रदर्शित करें" अनुक्रम के दौरान होता है जब आपका फॉर्म इसकी गुणों को देखता है और एमएस विंडोज को कुछ ऐसा कहता है "अब मैं अपनी आंतरिक एचडब्ल्यूएनडी-ऑब्जेक्ट बनाना चाहता हूं और इसे डिफ़ॉल्ट निर्देशांक/आकार पर रखना चाहता हूं आपके स्वविवेक पर निर्भर है"।

और यह बिल्कुल सही व्यवहार है - अन्यथा कब और कैसे TFormPosition संपत्ति लागू कर सकते हैं ??? विंडोज़ से एक विंडो के निर्देशांक के लिए यह पूछने का कोई मतलब नहीं है कि स्क्रीन पर मौजूद नहीं है और शायद कभी नहीं होगा। Windows यह पूछे जाने वाले दूसरे सेकंड के लिए डिफ़ॉल्ट कॉर्ड/आकार प्रदान करता है, यह देखकर कि कितनी अन्य खिड़कियां हैं और जहां वे स्थित हैं (और एएमडी/एनवीडिया वीडियो ड्राइवर भी इसमें सुधार लागू कर सकते हैं)।

यह अब कुछ हद तक लागू होगा, और दो घंटे बाद लागू होगा जब सबकुछ शायद अलग होगा - अन्य खिड़कियों की अलग-अलग मात्रा और उनसे अलग-अलग स्थितियों, अलग-अलग मॉनीटर संलग्न और विभिन्न संकल्पों के साथ आदि।

बस नोटबुक की "डेस्कटॉप प्रतिस्थापन" प्रकार पर विचार करें। यह बड़ी स्थिर बाहरी मॉनिटर से जुड़ी तालिका पर सेट किया गया था। फिर - आइए कल्पना करें - मैं आपका आवेदन चलाता हूं और यह टॉर्फ डेल्फी ऑब्जेक्ट बनाता है और कन्स्ट्रक्टर में उसने एमएस विंडोज को स्थिति के लिए कहा - और विंडोज ने उस माध्यमिक बड़े मॉनीटर पर सही स्थिति की पेशकश की। लेकिन फिर एक घंटे बाद मैंने नोटबुक को अनप्लग किया और इसके साथ चले गए। अब एक घंटे बाद मैं आपके आवेदन को फॉर्म दिखाने के लिए कहता हूं - और यह क्या करेगा? इसे अब-अलग बाहरी डिस्प्ले से संबंधित निर्देशांक के साथ प्रदर्शित करें? नोटबुक के आंतरिक प्रदर्शन के व्यूपोर्ट के बाहर जो मेरे पास अभी इस समय है? क्या यह फ़ॉर्म अब "अदृश्य" स्थिति में प्रदर्शित होना चाहिए क्योंकि जब मैंने एप्लिकेशन को वापस शुरू किया था तब भी वह जगह अभी भी दिखाई दे रही थी ??? मुझे लगता है कि उपयोगकर्ताओं को कोई लाभ नहीं है, मुझे लगता है।

तो एकमात्र सही व्यवहार विंडोज़ को डिफ़ॉल्ट कॉर्ड के लिए पूछना होगा जब यह फ़ॉर्म छुपा से दृश्यमान हो रहा है और दूसरा नहीं।

और इसका मतलब है कि यदि आप अपना फॉर्म ले जाना चाहते हैं - तो इसे दिखाने के बाद आपको इसे करना चाहिए। अपने Self.SetBounds(500,500,500,500); को OnShow ईवेंट हैंडलर में रखें। तो एमएस विंडोज़ को Position संपत्ति में आवश्यक रूप से अपने फॉर्म को डिफ़ॉल्ट स्थिति में पूरा करने दें - और इसके बाद अपनी विंडो को ले जाएं। खिड़की को स्थानांतरित करने का प्रयास जो अस्तित्व में नहीं है, फिर भी मेरे लिए सही तरीके से व्यर्थ दिखता है।

या तो पूर्व निर्धारित अपने रूप को स्पष्ट रूप से एमएस विंडोज चूक की अनदेखी करने और (poDesigned मूल्य के माध्यम से) पूर्व निर्धारित तार का उपयोग करें, या रूप पूछना विंडोज निर्देशांक, लेकिन साथ SetBounds के बाद यह दिखाई मिला इसे स्थानांतरित (अनुक्रम के निर्माण में) OnShow हैंडलर के माध्यम से।

+0

यह 'सेटबाउंड' से पहले' हैंडलनिड 'कॉल करने के लिए पर्याप्त प्रतीत होता है। –

+0

आरंभ करने के लिए, मेरा कोड Iplied से अधिक जटिल है। स्थिति बहाल करते समय, मैं मॉनिटर रिज़ॉल्यूशन और मॉनीटर की संख्या मॉनिटर करने के लिए खाता परिवर्तनों को ध्यान में रखता हूं। लेकिन वह बिंदु के बगल में है। यह सही उत्तर प्रतीत होता है (सिवाय इसके कि सेटबाउंड ऑनशो में काम नहीं करता है, लेकिन ऑनएक्टिवेट के साथ काम करता है - हालांकि मैं इन दोनों ईवेंट हैंडलर का उपयोग करने से बचने की कोशिश करता हूं)। हालांकि, यह देखते हुए कि CreateParams विधि को ओवरराइड करना (जैसा कि मियामी द्वारा टिप्पणी में सुझाया गया है) को स्थिति को poDefault में बदलने की अनुमति देता है, जिसके बाद SetBounds ऑनक्रेट (या ओवरराइड कन्स्ट्रक्टर) से काम करता है, यह स्पष्टीकरण समझ में आता है। –

+0

@ ओन्ड्रेजकेले - हाँ, शायद। लेकिन आप गंदे हैक का उपयोग क्यों करेंगे, कन्स्ट्रक्टर में ** अप्रत्याशित ** कॉम्प्लेक्स कॉल कर सकते हैं और संभावित रूप से आधे से बने विंडो पर इवेंट हैंडलर की लंबी श्रृंखला को ट्रिगर कर सकते हैं, जब आप बस वीसीएल के स्थान पर मूव विंडो कार्रवाई को स्थानांतरित कर सकते हैं तो वास्तव में इसकी उम्मीद है हो सकता है? –

संबंधित मुद्दे

 संबंधित मुद्दे