2011-03-10 7 views
1

TLabel 자손을 만들려고합니다. 텍스트 너비가 레이블 폭을 초과하면 전체 캡트와 함께 힌트가 표시됩니다. EllipsisPosition 속성을 epEndEllipsis로 설정 했으므로 캡션이 끝에있는 줄임표로 자동으로 단락됩니다. 괜찮아.TLabel (TGraphicControl)에 대한 크기 조정 이벤트를 만드는 방법

그러나 힌트를 설정하기 위해 텍스트가 짧게 설정되었음을 알리는 메시지가 필요합니다.. 텍스트가 변경되고 (메시지 CM_TEXTCHANGED) 구성 요소의 크기가 조정 된 경우에만 이러한 경우가 발생할 수 있습니다.

그리고 내 질문 - 내 TLabel의 크기가 조정되었음을 어떻게 알릴 수 있습니까? 나는 앵커를 가지고 있으므로 폼과 함께 크기가 조정되지만 별도의 TLabel 자손으로 감싸고 싶습니다.

이 코드는 작동하지만 더 좋은 방법이 아닙니까? WM_EXITSIZEMOVE와 같은 것이지만 TGraphicControl에서 작동합니까?

procedure TEllipsisLabel.WMWindowPosChanged(var Message: TWMWindowPosChanged); 
begin 
    inherited; 

    if Assigned(Parent) then 
    if Canvas.TextWidth(Caption) > Width then 
     begin 
     ShowHint := True; 
     Hint := Caption; 
     end 
    else 
     begin 
     ShowHint := False; 
     Hint := ''; 
     end; 
end; 

고마워 :) 내가 WM_WINDOWPOSCHANGED보다 더 나은 아무것도 생각할 수 없다

+1

'Set_bounds'를 오버라이드 할 수 있는데, 여기서'WM_WINDOWPOSCHANGED'가 수행된다. 또는 코드를 이벤트 핸들러에 넣으려면 자손의 OnResize 속성을 게시하면됩니다. 어느 쪽이 메시지 처리기보다 좋을지 아무 이유도 보지 마라. –

답변

1

자손이 TLabel 자손의 크기가 조정되었다는 통지를 받고 싶지 않다고 생각합니다. 대신 문자가으로 단축되었음을 알리 길 원합니다. 나는 그것들이 동일하게 보입니다. 그러나 그것들은 그렇지 않습니다. 라벨이 여전히 텍스트보다 넓을 수도 있고, WordWrap이 켜져있을 수도 있습니다.또한 TCustomLabel 자손은 theming/Vista/Aero glow 관련 항목 (즉, DrawThemeTextExDrawText으로 종결 됨)을 기반으로 텍스트를 그리는 데 몇 가지 다른 방법을 사용할 수 있으므로 텍스트가 무엇인지 정확히 알기 위해서는 해당 시스템에 연결해야합니다. 렌더링 된 텍스트의 크기를 포함하여 드로잉이 수행됩니다.

초보자 용이 아닌 델파이 에디션을 사용하는 경우 소스를 stdctrls.pas으로보십시오. 관심의 두 가지 방법이 있습니다 :

  • TCustomLabel.AdjustBounds -이 경계의 구형이 설정되어있는 경우이며, 그것은 호출하여 줄 바꿈 등 그것은이 작업을 수행하기위한 조정 관심있는 다른 방법 (그림처럼) :
  • TCustomLabel.DoDrawText -이 텍스트를 칠하거나 줄 바꿈을 설명하는 텍스트 경계 사각형을 계산합니다. 내부적으로 실제로 그려지는 텍스트 인 변경된 문자열을 생성합니다. 즉,이 방법의 기능은 텍스트가 맞는지 여부를 알려줍니다.

둘 다 dynamic이며 의미 상으로는 virtual과 같습니다. 즉, 재정의 할 수 있습니다.

DoDrawText 불행히도 최종 텍스트 문자열을 반환하지 않습니다. 그랬다면 무시하고 상속 된 버전을 호출하고 칠한 텍스트를 실제 텍스트와 비교할 수 있습니다. 그러나 재정의하고 다시 구현할 수 있으며 직접 수행하십시오. VCL 코드를 가이드로 사용하십시오 (동일한 기능을 원하지만, Embarcadero 소유이므로 직접 복사해서는 안됩니다). dynamic이므로 자손 클래스의 버전은 AdjustBounds에 의해 호출됩니다. 코드에서 텍스트를 줄이면 깃발을 짧게 설정하거나 힌트를 즉시 생성하십시오. Voila. 정확히 언제 단축되었는지 정확하게 알 수있다 :

+0

예, 내 TLabel이 epEndEllipsis 3 점 문자열로 단축 될 때 알림을 받아야합니다. 그것을하는 방법? –

+0

내 대답 마지막 단락은 설명해야합니다 (구체적으로 "재정의하고 다시 구현하십시오 ... 텍스트를 줄이면 플래그를 짧게 설정하거나 ..."). 그게 당신이 이해하지 못하는/당신을 위해 확장 할 수 있습니까? –

+0

코멘트 주셔서 감사합니다, 그냥 속임수 질문이었습니다 :) –

1

: 누구의 크기, 위치, 또는 장소에있는 창으로 전송

Z 순서가 SetWindowPos 함수 또는 다른 창 관리 함수 호출 결과로 변경되었습니다.

이상적입니다. 그것을 사용하는 것에 대해 당신은 무엇을 가지고 있습니까?

+0

사실 (부모가 알려지기 전에) 너무 일찍 전화를 받았고 부모 할당을 수행해야한다. 그렇지 않으면 액세스 위반이 발생한다. 그래서 나는이 검사를 필요로하지 않고 크기 변경을 위해서만 호출되는 특정 메시지 나 방법을 요구하고 있었다. –

+0

학부모가 배정 된 후 학부모에게 필요한 작업 만 할 수 있습니까? –

+0

네,하지만 컨트롤 크기 조정이 끝나면 WM_EXITSIZEMOVE 같은 것을 한 번만 호출 할 수 있기를 바랍니다. –

0

AdjustBounds 메서드를 재정의해야한다고 생각합니다. 다음 코드를 시도하십시오. TButtonTLabel이있는 양식을 만들고 .pas을이 코드로 바꿉니다. 이 예제는 텍스트가 변경된 경우 레이블 크기 변경을 감지하는 방법을 보여줍니다. 자신 만의 이벤트를 만들어야합니다.

unit unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls; 

type 
    TSizeNotifyLabel = class(TLabel) 
    public 
    procedure AdjustBounds; override; 

end; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    Label1: TLabel; 
    procedure FormCreate(Sender: TObject); 
    procedure Button1Click(Sender: TObject); 
    private 
    { Private declarations } 

    SizeNotifyLabel: TSizeNotifyLabel; 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 


procedure TSizeNotifyLabel.AdjustBounds; 
begin 
    inherited; 
    form1.label1.caption := 'Width of Label:'+inttostr(form1.SizeNotifyLabel.Width); 
end; 

{$R *.dfm} 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    SizeNotifyLabel.Caption := SizeNotifyLabel.Caption + ' Change My Size'; 
end; 

procedure TForm1.FormCreate(Sender: TObject); 

begin 
    SizeNotifyLabel := TSizeNotifyLabel.Create(self); 
    with SizeNotifyLabel do begin 
    caption := 'Hello World'; 
    left := 10; 
    top := 10; 
    autosize := true; 
    parent := self; 
    end; 

end; 

end. 
+3

OP에서 AutoSize를 사용하고 있다고 생각하지 않습니다. 그렇다면 왜 줄임표가 필요한 것일까 요? –

+0

@David - 당신 말이 맞아요.하지만 어쨌든 AdjustBounds도 해결책이 될 수 있습니다. –

0

Resize 방법을 간단하게 무시할 수 있습니다. 그러나 코드

if Canvas.TextWidth(Caption) > Width then 

당신이 예상치 못한 결과를 얻을 수 있도록 타원을 그릴 때 TCustomLabel.DoDrawText이 결정하는 방법과 다른 점에 유의.

또한 타원 그림은 글꼴 변경, 테마 설정 변경 및 기타 이벤트로 인해 발생할 수 있습니다.

+0

필자의 의견에 동의하지만 필자의 경우 필자는이 방법으로 폭을 계산하기에 충분하다. 왜냐하면 글꼴은 테마에 의존하지 않기 때문에 (나는 희망한다.) 라벨에 프레임이 없다. 그리고 언급 된 Resize 메서드는 나에게 잘 어울립니다. 가능한 빨리 검사 할 것입니다. 그리고 내 마음 속에 가지고있는 글꼴 변경, 그러나 이것은 결코 일어나지 않을 것입니다. 왜냐하면 나를 위해서만 텍스트 변경과 크기 조정이 중요합니다. –