2013-02-06 30 views
6

मेरे पास एक कस्टम बटन घटक है जिसे मैंने TCustomButton से लिया है।गतिशील रूप से CreateParams बदल रहा है?

यह ownerdrawn बनाने के मैं बहुत तरह CreateParams overrided है

procedure TMyButton.CreateParams(var Params: TCreateParams); 
begin 
    inherited CreateParams(Params); 
    with Params do 
    begin 
    Style := Style or BS_OWNERDRAW; 
    end; 
end; 

मेरे बटन अपने ही पेंटिंग आदि के साथ ठीक काम करता है, लेकिन मुझे क्या करना चाहते हैं वस्तु इंस्पेक्टर में एक बूलियन संपत्ति प्रदान करते है जो मेरे बटन को बताने के लिए इस्तेमाल किया जा सकता है कि क्या इसे मालिकाना किया जाना चाहिए या नहीं।

उदाहरण के लिए, यदि प्रॉपर्टी किसी ownerdrawn बटन के रूप में सक्षम किया गया है अपने ही रंग दिनचर्या के साथ बटन पेंट, यदि संपत्ति बंद चालू किए जाने पर तो यह थीम पर आधारित विंडोज बटन शैली (एक नियमित TButton की तरह) के रूप में पेंट करना चाहिए।

CreateParams मेरे बटन को बताता है कि यह मालिक होना चाहिए, लेकिन मैं बटन को बताने के लिए एक विकल्प प्रदान करना चाहता हूं कि इसे मालिकाना किया जाना चाहिए या नहीं। डिज़ाइनटाइम पर या रनटाइम पर कोड के माध्यम से संपत्ति को बदलकर, मैं अपना बटन बताना चाहता हूं कि मालिकाना है या नहीं।

क्या यह संभव है और यदि ऐसा है तो कैसे?

उत्तर

10

संपत्ति जोड़ना और CreateParams तदनुसार व्यवहार करना मुझे लगता है कि समस्या नहीं है। प्रभाव में नई सेटिंग तुरंत लेना शायद है।

संपत्ति 0gपर कॉल करें जब संपत्ति टॉगल की जाती है। यह मौजूदा विंडोज हैंडल को छोड़ने और इसे पुनर्निर्मित करने का कारण बन जाएगा, जिसमें आपके ओवर्रिडेन CreateParams दिनचर्या का उपयोग शामिल है।

कुल मिलाकर:

type 
    TMyButton = class(TButtonControl) 
    private 
    FOwnerDraw: Boolean; 
    procedure SetOwnerDraw(Value: Boolean); 
    protected 
    procedure CreateParams(var Params: TCreateParams); override; 
    published 
    property OwnerDraw: Boolean read FOwnerDraw write SetOwnerDraw 
     default False; 
    end; 

procedure TMyButton.CreateParams(var Params: TCreateParams); 
const 
    OwnerDraws: array[Boolean] of DWORD = (0, BS_OWNERDRAW); 
begin 
    inherited CreateParams(Params); 
    Params.Style := Params.Style or OwnerDraws[FOwnerDraw]; 
end; 

procedure TMyButton.SetOwnerDraw(Value: Boolean); 
begin 
    if FOwnerDraw <> Value then 
    begin 
    FOwnerDraw := Value; 
    RecreateWnd; 
    end; 
end; 
+0

RecreateWnd जादू शब्द था जिसे अब मैं जानता हूं :) –

5

आप इस तरह यह कर सकते हैं:

  1. एक OwnerDraw संपत्ति करें।
  2. CreateParams में उस संपत्ति का परीक्षण करें और तदनुसार व्यवहार स्विच करें।
  3. जब भी संपत्ति बदलती है RecreateWnd पर कॉल करें।

आइटम 3 के बजाय आप आसानी से विंडो शैली को SetWindowLong पर कॉल के साथ बदल सकते हैं। यह सुनिश्चित करने के पहले सुनिश्चित करें कि आप HandleAllocated का परीक्षण करने से पहले परीक्षण करें। खिड़की को बेकार बनाने के लिए मजबूर करने का कोई मतलब नहीं है। हालांकि, जब भी ऐसा होता है तो संभवतः आपको एक पेंट चक्र को मजबूर करने की भी आवश्यकता होती है।

व्यक्तिगत रूप से, मुझे लगता है कि मैं खिड़की के मनोरंजन को मजबूर करने के इच्छुक हूं।

+0

'एक पेंट चक्र को मजबूर करें' का मतलब है कि क्या आप नियंत्रण में अमान्य भेजते हैं? आपके उत्तर के लायक होने के लिए और एनजीएलएन के बारे में मुझे क्या पता होना चाहिए, RecreateWnd CreateParams को कॉल करता है और संपत्ति की स्थिति का परीक्षण करने के लिए इसे सरल शैली के साथ देशी शैली में बदल देता है। –

+1

'अमान्य' एक पेंट चक्र को मजबूर करेगा। ध्यान दें कि 'RecreateWnd'' CreateParams 'को कॉल नहीं करता है। यह बस खिड़की को नष्ट कर देता है। जब नियंत्रण को विंडो विंडो की आवश्यकता होती है, तो इसे बनाया जाएगा, और फिर 'CreateParams' कहा जाता है। विंडो हैंडल मांग पर बनाए जाते हैं। –

+0

मुझे इसे साफ़ करने के लिए धन्यवाद दिखाई देता है, ऐसा लगता है कि मैंने आज भी एक और कीवर्ड 'RecreateWnd' में सीखा है :) –