2011-08-19 8 views
7

मेरे पास एक TScrollBox है जिसमें RichEdit है जो स्क्रॉलबॉक्स से बड़ा है, इसलिए दोनों तरफ स्क्रॉलबॉक्स स्क्रॉलबॉक्स में दिखाई देते हैं। तब मेरे पास एक कार्य DoTask है जो RichEdit.SetFocus पर कॉल करता है।मैं TScrollBox के स्क्रॉल-इन-व्यू व्यवहार को कैसे अक्षम कर सकता हूं?

जब मैं नीचे स्क्रॉल करता हूं जहां मैं टेक्स्ट नियंत्रण का हिस्सा देखना चाहता हूं, और फिर DoTask पर कॉल करें, तो स्क्रॉलबॉक्स स्वचालित रूप से RichEdit के शीर्ष पर स्क्रॉल हो जाएगा। मैं इससे कैसे बच सकता हूं?

+0

हाँ, यह स्पष्ट है। –

+1

स्क्रॉल बॉक्स का उपयोग न करें स्पष्ट समाधान प्रतीत होता है क्योंकि आपके पास आवश्यक –

+0

@ डेविड से अधिक स्क्रॉल बार हैं: यदि RichEdit स्क्रॉलबॉक्स पर एकमात्र घटक है, तो मैं सहमत हूं। बेशक हम नहीं जानते कि यह है या नहीं। स्क्रॉलबॉक्स पर अपने एकल स्क्रॉलबार रखने वाले एक घटक को थोड़ा सा ... अजीब, वास्तव में होगा। –

उत्तर

6

जैसा तुम चाहो, यहाँ कुछ सुझाव हैं:

  • अवहेलना SetFocusedControl रूप में:

    function TForm1.SetFocusedControl(Control: TWinControl): Boolean; 
    begin 
        if Control = RichEdit then 
        Result := True 
        else 
        Result := inherited SetFocusedControl(Control); 
    end; 
    

    या:

    type 
        TCustomMemoAccess = class(TCustomMemo); 
    
    function TForm1.SetFocusedControl(Control: TWinControl): Boolean; 
    var 
        Memo: TCustomMemoAccess; 
        Scroller: TScrollingWinControl; 
        Pt: TPoint; 
    begin 
        Result := inherited SetFocusedControl(Control); 
        if (Control is TCustomMemo) and (Control.Parent <> nil) and 
        (Control.Parent is TScrollingWinControl) then 
        begin 
        Memo := TCustomMemoAccess(Control); 
        Scroller := TScrollingWinControl(Memo.Parent); 
        SendMessage(Memo.Handle, EM_POSFROMCHAR, Integer(@Pt), Memo.SelStart); 
        Scroller.VertScrollBar.Position := Scroller.VertScrollBar.Position + 
         Memo.Top + Pt.Y; 
        end; 
    end; 
    
  • लगाना TScrollBox:

    type 
        TScrollBox = class(Forms.TScrollBox) 
        protected 
        procedure AutoScrollInView(AControl: TControl); override; 
        end; 
    
    procedure TScrollBox.AutoScrollInView(AControl: TControl); 
    begin 
        if not (AControl is TCustomMemo) then 
        inherited AutoScrollInView(AControl); 
    end; 
    

    या:

    procedure TScrollBox.AutoScrollInView(AControl: TControl); 
    begin 
        if (AControl.Top > VertScrollBar.Position + ClientHeight) xor 
         (AControl.Top + AControl.Height < VertScrollBar.Position) then 
        inherited AutoScrollInView(AControl); 
    end; 
    

या ऊपर के सभी के किसी भी रचनात्मक संयोजन का उपयोग करें। आप इसे कैसे और कब स्क्रॉल करना चाहते हैं केवल आपको पता है।

+0

मुझे लगता है कि एक इंटरपोजर के बजाय, टीएसक्रॉलबॉक्स के लिए एक कक्षा सहायक, यह चाल भी करेगा। हालांकि, यह जांच नहीं कर सकता। –

+1

मुझे नहीं लगता कि यह काम करेगा, @ रुडी। आप क्लास हेल्पर्स के साथ वर्चुअल विधियों को ओवरराइड नहीं कर सकते हैं। विधि की मूल कॉल साइट क्लास हेल्पर मौजूद नहीं है, इसलिए यह मूल विधि को कॉल करना जारी रखेगी। –

+0

@ रोब: आप सही हैं। मूल कॉल साइट सहायक विधि का उपयोग नहीं करेगा। –

2

simpliest समाधान होगा

var a, b : Integer; 
begin 
    a := ScrollBox1.VertScrollBar.Position; 
    b := ScrollBox1.HorzScrollBar.Position; 
    richEdit1.SetFocus; 
    ScrollBox1.VertScrollBar.Position:=a ; 
    ScrollBox1.HorzScrollBar.Position:=b ; 
end; 
1

वीसीएल/कस्टम घटकों को प्राप्त करने के बिना हैकिंग के बिना केवल एक ही समाधान है - TForm.SetFocusedControl ओवरराइड + ऊपर बताए गए स्क्रॉलबार की स्थिति को फिर से सेट करना। एक चीज जिसे मैंने जोड़ा है वह बदसूरत कूद से बचने के लिए विंडो रेड्रो को अक्षम/सक्षम कर रहा है। यहां मेरा अंतिम स्निपेट है:

एसबीकॉन्टेनर टीएसक्रॉलबॉक्स है और नोएससीआरआरटीआरटी इसके अंदर एक नियंत्रण बिछा रहा है जो फोकस करता है लेकिन हम इसे स्क्रॉल-इन-व्यू नहीं करना चाहते हैं।

function TForm1.SetFocusedControl(Control: TWinControl): Boolean; 
var hpos, vpos: integer; 
begin 
    if Control = NoScrCtrl then 
    begin 
    sbContainer.Perform(WM_SETREDRAW, WPARAM(False), 0); 
    hpos := sbContainer.HorzScrollBar.Position; 
    vpos := sbContainer.VertScrollBar.Position; 
    Result := inherited SetFocusedControl(Control); 
    sbContainer.HorzScrollBar.Position := hpos; 
    sbContainer.VertScrollBar.Position := vpos; 
    sbContainer.Perform(WM_SETREDRAW, WPARAM(True), 0); 
    sbContainer.Refresh; 
    end 
    else 
    Result := inherited SetFocusedControl(Control); 
end; 
संबंधित मुद्दे