2013-12-09 6 views
4

VCL TMemo 컨트롤이있어서 텍스트를 스크롤 할 때마다 알림을 받아야합니다. OnScroll 이벤트가없고 스크롤 메시지가 상위 폼으로 전파되지 않는 것처럼 보입니다.TMemo 컨트롤에서 스크롤바 알림을받는 방법?

알림을받는 방법에 대한 아이디어가 있으십니까? 마지막 수단으로 나는 ... 외부 TScrollBar을 배치하고 OnScroll 이벤트에 TMemo를 업데이트,하지만 난 커서를 이동하거나 TMemo에서 마우스 휠을 스크롤 할 때 동기화에 보관해야 할 수 있습니다

+0

AFAICT, 자신의 자손을 작성하고'WM_VSCROLL' 및'WM_HSCROLL' 메시지를 잡기 위해'WndProc'를 오버라이드해야하고, 그 (것)들에 응하여 당신이 필요로하는 것을하십시오. –

+0

@KenWhite, 이것은 델파이 애플리케이션이 아닙니다 ... 태그를 다시 변경했습니다. –

+0

태그가 처음에는 델파이가 아니라고 표시하지 않았습니다. VCL은 단순히 델파이 라고만 말했습니다. 대답은 똑같습니다. –

답변

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

메시지를 받지만 스크롤 메시지가 없습니다. 메모 스크롤바의 위/아래 버튼을 누르면 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

Interposer 클래스가 C++에서 작동하지 않습니다. 하지만 런타임에 표준'TMemo' 컴포넌트의'WindowProc' 속성을 서브 클래스화할 수 있습니다. –

+0

'TMemo.WMVScroll' 프로 시저의'WM_VSCROLL' (지금은'WM_HSCROLL')이 있습니다. –

관련 문제