2013-12-09 34 views
4

我有一個VCL TMemo控件,每次滾動文本時都需要通知。沒有事件,滾動消息似乎不會傳播到父窗體。如何從TMemo控件獲取滾動條通知?

任何想法如何獲得通知? 作爲最後的手段,我可​​以把外部TScrollBar並更新OnScroll事件TMemo,但我必須保持同步,當我將光標移動或滾動TMemo鼠標滾輪...

+0

AFAICT,你必須編寫自己的後代並覆蓋WndProc來捕獲WM_VSCROLL和WM_HSCROLL消息,做你需要的東西來回應他們。 –

+0

@KenWhite,這不是一個Delphi應用程序...我改變了標籤。 –

+0

您的標籤最初並未表明它不是德爾福。它只是說VCL,它是* Delphi。但答案是一樣的。 –

回答

2

您可以在運行時繼承備忘錄的WindowProc屬性來捕獲所有發送到備忘錄的消息,例如:

private: 
    TWndMethod PrevMemoWndProc; 
    void __fastcall MemoWndProc(TMessage &Message); 

__fastcall TMyForm::TMyForm(TComponent *Owner) 
    : TForm(Owner) 
{ 
    PrevMemoWndProc = Memo1->WindowProc; 
    Memo1->WindowProc = MemoWndProc; 
} 

void __fastcall TMyForm::MemoWndProc(TMessage &Message) 
{ 
    switch (Message.Msg) 
    { 
     case CN_COMMAND: 
     { 
      switch (reinterpret_cast<TWMCommand&>(Message).NotifyCode) 
      { 
       case EN_VSCROLL: 
       { 
        //... 
        break; 
       } 

       case EN_HSCROLL: 
       { 
        //... 
        break; 
       } 
      } 

      break; 
     } 

     case WM_HSCROLL: 
     { 
      //... 
      break; 
     } 

     case WM_VSCROLL: 
     { 
      //... 
      break; 
     } 
    } 

    PrevMemoWndProc(Message); 
} 
+0

我確實收到消息,但沒有任何消息是SCROLL消息。如果我按備註滾動條的向上和向下按鈕,則不會獲得Notifycode 0x0602(WParamHi),不會有其他CN_COMMANDS。 –

+0

@MaxKielland:NotifyCode 0x0602是'EN_VSCROLL'('EN_HSCROLL'是0x0601)。 –

+0

謝謝!代碼由於某種原因被優化了。當我做了更適當的實施時,它工作得很好。通過使用WM_xSCROLL消息,我捕獲了所有的滾動條行爲,而不僅僅是箭頭按鈕。但是,有沒有辦法在備忘錄因光標移動而滾動時捕獲?滾動條被更新,但我沒有得到任何滾動條消息。我試圖聽SBM_SETPOS,但我想它會直接發送到嵌入的滾動條。在最壞的情況下,我想我必須聽取關鍵事件。 –

3

您可以使用插入程序類來處理WM_VSCROLLWM_HSCROLL消息以及EN_VSCROLLEN_HSCROLL通知代碼(通過WM_COMMAND消息顯示)。

試試這個樣本

type 
    TMemo = class(Vcl.StdCtrls.TMemo) 
    private 
    procedure CNCommand(var Message: TWMCommand); message CN_COMMAND; 
    procedure WMVScroll(var Msg: TWMHScroll); message WM_VSCROLL; 
    procedure WMHScroll(var Msg: TWMHScroll); message WM_HSCROLL; 
    end; 

    TForm16 = class(TForm) 
    Memo1: TMemo; 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form16: TForm16; 

implementation 

{$R *.dfm} 


{ TMemo } 

procedure TMemo.CNCommand(var Message: TWMCommand); 
begin 
    case Message.NotifyCode of 
    EN_VSCROLL : OutputDebugString('EN_VSCROLL'); 
    EN_HSCROLL : OutputDebugString('EN_HSCROLL'); 
    end; 

    inherited ; 
end; 

procedure TMemo.WMHScroll(var Msg: TWMHScroll); 
begin 
    OutputDebugString('WM_HSCROLL') ; 
    inherited; 
end; 

procedure TMemo.WMVScroll(var Msg: TWMHScroll); 
begin 
    OutputDebugString('WM_HSCROLL') ; 
    inherited; 
end; 
+0

對不起,忘記提及我正在使用C++ Builder,但我會看看是否可以翻譯您的示例... –

+0

插頁器類不能在C++中工作。但是,您可以在運行時繼承標準「TMemo」組件的'WindowProc'屬性。 –

+0

只是一個小小的更正:'TMemo.WMVScroll'程序中的'WM_VSCROLL'(現在有一個'WM_HSCROLL')。 –