2017-12-01 8 views
0

내가 개발하도록 지시 받았던 하나의 이전 프로젝트에는 TScrollBox 유형의 필드가 있습니다.TScrollBox에 추가 된 도우미 메서드가 작동하지 않습니다.

탐색 단추의 이벤트를 처리하려면 클래스에 WM_GETDLGCODE 메시지 처리기가 있어야합니다. 그래서 새로운 클래스 생성 :

TScrollBoxArrowBtn = class(TScrollBox) 
protected 
    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE; 
end; 

구현

procedure TScrollBoxArrowBtn.WMGetDlgCode(var Message: TWMGetDlgCode); 
begin 
    Message.Result := DLGC_WANTARROWS; 
end; 

을 그리고 TScrollBoxArrowBtn와 TScrollBox 유형을 대체했다.

FScroll : TScrollBoxArrowBtn; 

구성 요소가 화살표 버튼을 눌러 응답하기 시작했습니다. 그러나 copy, delete, SelectAll 메소드는 작동을 멈췄습니다. 이전 개발자가이 같은 검증 방법에 추가하기 때문에 무슨 일이 있었 :

"VariableName".ClassType = TScrollBox 

나는 검증을 위해 그들을 대체 : 편집의 방법 후

"VariableName" is TScrollBox 

이 작동하기 시작했다. 그러나 그러한 테스트가 프로젝트의 다른 곳에 적용되지 않을지 확신하지 못합니다. 그래서

FScroll : TScrollBox; 

을 떠나기로 결심 그리고 TScrollBoxArrowBtn 헬퍼 클래스 제작 :
TScrollBoxArrowBtn = class helper for TScrollBox 
protected 
    procedure WMGetDlgCode(var Message: TWMGetDlgCode); message WM_GETDLGCODE; 
end; 

불행하게도이 방법이 작동하지 않습니다. "VariableName".ClassType = TScrollBox과 같은 인증은 완벽하게 작동하기 시작했지만 프로젝트는 이벤트 화살표 버튼에 응답하지 않습니다. 나는 무엇을 잘못 했는가?

내 버전의 IDE가 도우미 메서드를 지원한다고 확신합니다.

답변

1

헬퍼 클래스의 메시지 메서드에 대한 답변을 찾지 못했지만 문제를 해결할 수있는 방법을 찾았습니다. 또한 헬퍼 클래스의 많은 다른 나쁜 기능에 대해서도 배웠습니다. 결국 헬퍼 클래스의 사용을 포기하게되었습니다. 그래서 내 대답은 - 클래스 도우미를 사용하지 마십시오. 이 때 이것은 매우 불안정한 도구입니다. 아마도 앞으로는 개선 될 것입니다.

내 결정에 대해. 내가 두려워, 다음과 같은 종류의 유형을 확인하는 문제 : 이전에 생성 된 지점을 병합 할 때

"VariableName".ClassType = TScrollBox 

다시 나타났다. 그래서 TScrollBox 윈도우 프로 시저를 대체하기로 결정했습니다. 나는 TScrollBox 필드 컨테이너 클래스에 필드를 추가하고 난 컨테이너 클래스에 TScrollBox 필드에 대한 새 창 프로 시저를 추가 :

TCADParamsGroupBlockBaseScheme = class (TCADGroupBlockParams) 
..................................................... 
protected 

    Old_FScroll_WindowProc : TWndMethod; 
    procedure New_FScroll_WindowProc(var Message: TMessage); 
..................................................... 
end; 

implementation 

procedure TCADParamsGroupBlockBaseScheme.New_FScroll_WindowProc(var Message: 
TMessage); 
begin 
    //Для обработки событий нажатий Key_Up/Down/Left/Right в DoKeyDown 
    if Message.Msg = WM_GETDLGCODE then 
    Message.Result := DLGC_WANTARROWS 
    else Old_FScroll_WindowProc(Message); 
end; 

그리고 컨테이너 클래스의 생성자에서, 나는 이전 TScrollBox에 대한 포인터를 저장 -field 윈도우 프로 시저를 만들고 새 윈도우 프로 시저를 할당했습니다.

constructor TCADParamsGroupBlockBaseScheme.Create(const AOwner: TWinControl); 
begin 
........................................... 
FScroll := TScrollBox.Create(FHost.Owner); 

Old_FScroll_WindowProc := FScroll.WindowProc; 
FScroll.WindowProc := New_FScroll_WindowProc; 
............................................ 
end;