문제

확장으로 이 질문:

tform.onresize는 형태가 처음 표시되기 전에 때때로 발사되지만 항상 그런 것은 아닙니다. 예를 들어, Borderstyle이 Bsdialog 또는 Bsnone이라면 OnResize가 발사되지 않습니다. 다른 모든 Borderstyle 값 (및 기본값의 다른 모든 속성과 함께)의 경우 OnResize는 화재를 일으 킵니다.

양식이 표시되기 전에 OnResize가 발사 될지 여부에 영향을 미치는 다른 것들이 있습니까? 예를 들어, 다른 속성 또는 특성의 조합이 이에 영향을 줄 수 있습니까?

onresize 이벤트는 결과입니다 ShowWindow API 기능 보내기 a WM_SIZE 창에 메시지. 반복되는 것은 다음과 같습니다. 메시지는 Delphi가 아닌 Windows에서 나옵니다. Windows 함수입니다 (ShowWindow)이 행사를 트리거하는 메시지를 보내는 경우가 있습니다. 따라서 VCL 소스 코드는이 경우 실제로 도움이되지 않습니다.

문서화 된 결정을 기반으로 한 결정 답변에 대한 보너스 포인트 ShowWindow / WM_SIZE 행동, 예를 들어 MSDN 문서 또는 Petzold 책에 대한 참조.

도움이 되었습니까?

해결책

어쩌면 사용자의 디스플레이 설정 또는 데스크탑 테마 또는 Windows 버전에 따라 다를 수 있습니다. onresize가 이와 같은 문제를 제시한다면, 나는 원인이 무엇인지에 관계없이 항상 그것을 기대하고 어떤 상황에서도 그것을 처리 할 프로그램을 구축 할 것입니다.

다른 팁

이벤트가 형태 크기 (왼쪽, 하단, 너비, 높이)가 수정 될 것이라는 메시지를 파견 할 때 OnResize가 발사 될 것이라고 생각합니다.

이미 해당 이벤트를 발사 한 메시지를 이미 발견 했으므로 이제 VCL에서 메시지가 전송되는 위치를 추적해야합니다.

VCL 소스 코드를보고 해당 작업을 발견 할 수 있는지 확인하십시오.

편집 : 낮은 수준으로 가자. Windows (Grossly Talk)의 양식은 "창 클래스"라고 불리는 것을 가지고 있습니다 (우리가 아는 것과 같은 클래스가 아닙니다). 양식의 창 클래스가 항상 크기가 크게 높아지고 양식이 표시되며 WM_Size가 전송됩니다.

따라서 양식이 표시되는 모든 시간이 발생하지는 않지만 기본 창 클래스와 비교하여 차원 만 변경됩니다.

당신이 관찰 한 바와 같이, 많은 속성 valuez는 양식의 크기 (몇 픽셀)를 변경합니다.

이것은 매우 피상적입니다 설명, 그것은 많은 다른 세부 사항이지만, "후드 아래"일이 어떻게 작동하는지 이해하고 있습니다.

테스트 대체는 없습니다. 코드에서 양식을 작성하고, 관심있는 속성을 설정하고, 크기 조정 이벤트가 호출 될 때 녹음하는 것은 어떻습니까?

코드의 추악함을 변명한다면, 여기에 각각을 명시 적으로 코딩하지 않고 Borderstyle과 위치의 모든 조합을 테스트하는 대략적인 개념 증명이 있습니다. 더 많은 속성을 추가하고 원하는만큼 가져갈 수 있습니다. 코드 사이트와 같은 도구는 로깅을 더 깨끗하고 쉽게 만듭니다.

두 가지 양식으로 응용 프로그램을 만듭니다. 두 번째가 자동으로 창조되지 않은지 확인하십시오.

두 번째 양식에서 속성을 추가하고 양식 크기 조정 이벤트에 작은 로깅 코드를 추가하십시오.

  private
    FOnResizeFired: TNotifyEvent;
  public
    property OnResizeFired: TNotifyEvent read FOnResizeFired write FOnResizeFired;
  end;

...

procedure TForm2.FormResize(Sender: TObject);
begin
  if Assigned(FOnResizeFired) then
    FOnResizeFired(self);
end;

기본 양식에서는 사용 절에 TypInfo를 추가하고 버튼과 메모를 양식에 떨어 뜨립니다.

간단한 절차 추가 :

procedure TForm1.ResizeDetected(Sender: TObject);
begin
  Memo1.Lines.Add('    *** Resize detected');
end;

이제 ButtonClick 이벤트에 다음을 추가하십시오.

procedure TForm1.Button1Click(Sender: TObject);
var
  lBorderStyle: TFormBorderStyle;
  lBorderStyleName: string;
  lPosition: TPosition;
  lPositionName: string;
  lForm: TForm2;
begin
  Memo1.Clear;
  for lBorderStyle in [low(TFormBorderStyle) .. high(TFormBorderStyle)] do
  begin
    for lPosition in [low(TPosition) .. high(TPosition)] do
    begin
      lBorderStyleName := GetEnumName(TypeInfo(TFormBorderStyle), Integer(lBorderStyle));
      lPositionName := GetEnumName(TypeInfo(TPosition), Integer(lPosition));
      Memo1.Lines.Add(Format('Border: %s  Position: %s', [lBorderStyleName, lPositionName]));

      Memo1.Lines.Add('  Creating form');
      lForm := TForm2.Create(self);
      try
        Memo1.Lines.Add('  Form Created');
        lForm.OnResizeFired := ResizeDetected;
        Memo1.Lines.Add('    Setting border style');
        lForm.BorderStyle := lBorderStyle;
        Memo1.Lines.Add('    Setting Position');
        lForm.Position := lPosition;
        Memo1.Lines.Add('    Showing form');
        lForm.Show;
        Memo1.Lines.Add('    Form Shown');
        lForm.Close;
        Memo1.Lines.Add('    Form Closed');
      finally
        FreeAndNil(lForm);
        Memo1.Lines.Add('    Form Freed');
      end;
    end;
  end;
end;

양식이 표시되기 전에 일부 속성이 설정 될 때 화재를 조정하는 것을 알 수 있으며, 일부 조합에서는 양식이 표시되면 크기 조정이 두 번 발사되는 것으로 보입니다. 흥미로운.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top