बाहर कर देता है समारोह जो सब कुछ टूट जाता है UpdateAnchorRules
है। TControl
स्टोर FOriginalParentSize
और FAnchorRules
में इसका मूल आकार है, और इसका उपयोग माता-पिता के आकार के रूप में स्वत: आकार बदलने के लिए करता है। UpdateAnchorRules()
वर्तमान मूल आकार और वर्तमान नियंत्रण Width
और Height
लेता है और उन्हें FOriginalParentSize
और FAnchorRules
में सहेजता है।
यदि सब कुछ ठीक से काम करता है जो सामान्य आकार के दौरान कोई प्रभाव नहीं पड़ेगा, क्योंकि नियंत्रण और उसके माता-पिता के आकार के अनुसार आकार बदलता है।
लेकिन जब नियंत्रण Width
एंकरिंग, विंडोज के कारण शून्य से कम है, और इसके परिणामस्वरूप डेल्फी अभी भी 0
मानता है। यदि उस बिंदु पर UpdateAnchorRules
कहा जाता है, तो यह मूल चौड़ाई के लिए 0
मान से बाहर, गलत-से-समझौता करता है। इसके बाद लेआउट मरम्मत से परे है।यह के रूप में WinAPI CreateWindow
में पहली:
जो कुछ भी एक खिड़की संभाल बनाना शामिल कॉल UpdateAnchorRules
बाहर बदल जाता है दो बार (यदि यह कहा जाता है नहीं कर रहा है, Width
माता पिता Width
के लिए उचित संबंध में अद्यतन करने की मूल आकार संरक्षित की वजह से जारी है) लौटने से पहले WM_SIZE
प्रेषित करता है (और WM_SIZE
हैंडलर UpdateAnchorRules
पर कॉल करता है), और दूसरे, स्पष्ट रूप से निर्माण के बाद CreateHandle
में।
ऐसा लगता है कि जब तक हम UpdateAnchorRules
को CreateHandle
की अवधि के लिए अक्षम कर सकते हैं, हम सफल होंगे। लेकिन UpdateAnchorRules
पर CreateHandle
में स्पष्ट कॉल हैं, जिसका अर्थ है कि किसी ने सोचा था कि को सृजन के बाद एंकर नियमों के समायोजन के लिए की आवश्यकता है।
तो शायद मुझे कुछ याद आ रहा है, और इसे अक्षम करके कुछ तोड़ देगा?
वैसे भी, UpdateAnchorRules
को अक्षम करने के दो तैयार तरीके हैं: FAnchorMove
सेट करने के लिए या csLoading
सेट करने के लिए। सबसे पहले कोई अच्छा नहीं है क्योंकि कोड है जो इसे RecreateWnd
के माध्यम से मिडवे साफ़ करता है और फिर UpdateAnchorRules
को फिर से कॉल करता है।
type
TComponentHack = class helper for TComponent
public
procedure SetCsLoading(Value: boolean);
end;
procedure TComponentHack.SetCsLoading(Value: boolean);
var i: integer;
begin
if Value then
Self.FComponentState := Self.FComponentState + [csLoading]
else
Self.FComponentState := Self.FComponentState - [csLoading];
for i := 0 to Self.ComponentCount-1 do
if Self.Components[i] is TControl then
TControl(Self.Components[i]).SetCsLoading(Value);
end;
procedure SafeRecreateWnd();
begin
MyControl.SetCsLoading(true);
try
MyControl.RecreateWnd(); //or any operation which triggers it -- such as docking or making the window visible first time after RecreateWnd()
finally
MyControl.SetCsLoading(false);
end;
end;
अस्वीकरण:
मुझे पता नहीं और क्या csLoading सेट के साथ TControl
आपरेशन चला कर ध्वस्त किया जा सकता है
दूसरा एक काम करता है और यहाँ एक समाधान है।
बेहतर विकल्प UpdateAnchorRules
प्रक्रिया हुक और इस उद्देश्य के लिए विशेष रूप से एक और झंडा जांच जोड़ने के लिए होगा, लेकिन है कि आवश्यकता होती है या तो पूरी तरह से UpdateAnchorRules
reimplementing या किसी तरह की खोज (प्रवण अलग मूल UpdateAnchorRules
साथ डेल्फी के विभिन्न संस्करणों पर तोड़ने के लिए) चाहते हैं मूल UpdateAnchorRules
पर कॉल करें जिसे आमतौर पर इसे हुक के साथ फिर से लिखकर नष्ट कर दिया जाता है।
"उपयोग करने के लिए असंभव" मुझे लगता है कि शीर्ष पर थोड़ा सा है। उपयोग के बहुत सारे मामले जहां फॉर्म के हैंडल को कभी भी पुनर्निर्मित नहीं किया जाता है। –
मुझे ऐसा नहीं लगता है। यहां तक कि जब आप प्रतीत होता है कि अब ऐसा नहीं करते हैं, तो एक महीने बाद आप कुछ ऐसा करते हैं जो पुन: उत्पन्न होता है और बैंग करता है, आपने बिना बगैर बग पेश किए हैं। एंकर अप्रत्याशित हैं। – himself
हम्म हाँ, निश्चित रूप से, यही कारण है कि उनका बहुत उपयोग किया जाता है ... एंकर बहुत अच्छी तरह से काम करते हैं और कई वर्षों से मेरे और कई अन्य लोगों के लिए ऐसा करते हैं। स्पष्ट रूप से आपका लाभ अलग है, लेकिन इनका उपयोग करने में आपकी असमर्थता उन्हें हर किसी के लिए उपयोग करना असंभव नहीं बनाती है। –