2013-02-06 7 views
6

TCustomButton에서 파생 된 사용자 지정 단추 구성 요소가 있습니다.CreateParams를 동적으로 변경 하시겠습니까?

것은 내가 지금처럼 CreateParams을을 오버라이드 한을 ownerdrawn 만들려면 :

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

내 버튼 등 내 자신의 그림과 작품을 좋아하지만, 내가 뭘하고 싶은 것은 오브젝트 인스펙터에서 부울 속성을 제공하다 그것이 ownerdrawn해야하는지 여부 내 버튼을 말하는 데 사용할 수 있습니다.

예를 들어, 속성이 활성화 된 경우 단추는 내 자신의 페인트 루틴으로 ownerdrawn 버튼으로 페인트됩니다. 속성이 해제 된 경우 일반 Windows 단추 스타일 (일반 TButton처럼)으로 페인트해야합니다.

CreateParams는 내 버튼에 ownerdawn이 있어야한다는 것을 알려주지 만 버튼에 ownerdrawn 여부를 알려주고 싶습니다. 런타임에 디자인 타임이나 코드를 통해 속성을 변경함으로써, 내 버튼에 ownerdraw 여부를 알려주고 싶습니다.

이렇게 할 수 있습니까? 그렇다면 어떻게 할 수 있습니까?

답변

10

속성을 추가하고 그에 따라 CreateParams을 동작시키는 것은 내가 생각하는 문제가 아닙니다. 즉시 새로운 설정을 적용하는 것이 좋습니다.

속성을 전환 할 때 RecreateWnd으로 전화하십시오. 이렇게하면 재정의 된 CreateParams 루틴을 사용하는 것을 포함하여 현재 Windows 핸들을 삭제하고 다시 생성하게됩니다. 모두

전체 :

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

'페인트 사이클을 강제합니다. '라는 말은 컨트롤에 무효화를 보내는 것을 의미합니까? 당신의 대답과 NGLN의 가치가 정확히 무엇인지 알고 싶다면 RecreateWnd는 CreateParams를 호출하고 간단한 체크를 통해 네이티브 스타일로 변경하여 속성의 상태를 테스트합니다. –

+1

'Invalidate'는 페인트 사이클을 강제합니다. 'RecreateWnd'는'CreateParams'를 호출하지 않습니다. 그것은 단순히 창을 파괴합니다. 컨트롤이 다음에 윈도우 핸들을 필요로하면 컨트롤이 생성되고 CreateParams가 호출됩니다. 창 핸들은 필요할 때 생성됩니다. –

+0

오늘은 'RecreateWnd'에서 또 다른 키워드를 배웠던 것처럼 보입니다. :) –

관련 문제