日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Delphi:窗體自適應屏幕分辨率

 aaie_ 2013-01-05

這是個困惑我很長時間的問題,到今天終于得到解決了。

 

話說Delphi有個很強的窗體設計器,這一點讓VC粉絲垂涎三尺而不可得。但是,Delphi里設計的窗體并沒有自動適應屏幕分辨率的屬性,也就是說,軟件設計時調整完美的窗體控件布局,在不同屏幕分辨率的機器上運行時可能會變得面目全非??丶g會相互移位,有的甚至移出窗體再也找不到了。

 

這個問題在網上搜索過多次,但大都依據(jù)控件方法ScaleBy或者ChangeScale。采用這兩個方法進行自適應調整,我自己都試過,但效果并不理想。后來我自己也寫了一個繼承自窗體的基類,覆蓋構造函數(shù),調用自己的一個設備分辨率自適應方法,該方法遍歷窗體上所有控件,并按照設計時的屏幕分辨率和當前屏幕分辨率的比值,逐一計算控件的位置和尺寸。這個想法是不錯,效果也是有的,比單純的采用ScaleBy或者ChangeScale方法要好,但也不是非常理想,沒有達到自己設想的要求。原因在哪里,一直不知道。

 

我原來的代碼曾經發(fā)布在Delphi盒子和CSDN上。

 

這個問題今天終于得以徹底解決了??!

 

原因是,我原以為將所有控件的Align屬性設為alnone,Anchors屬性設為空[],控件位置和尺寸就不會受其容器尺寸改變的影響。今天我在設計期對此進行試驗時,發(fā)現(xiàn)不是這樣。當窗體大小改變的時候,即使某個控件的Align:=alNone,Anchors:=[],它依然會隨著窗體尺度的變化而變化。這意味著我需要一個數(shù)組事先保存所有控件的原始位置和尺寸。在窗體因為屏幕分辨率的改變而自動調整時,計算的依據(jù)依然是不變的原始窗體位置尺寸數(shù)據(jù),這樣問題就解決了。

 

閑話少說,上源碼。

 

unit uMyClassHelpers;

 

interface


Uses


  SysUtils,Windows,Classes,Graphics, Controls,Forms,Dialogs,
  uMySysUtils;

 

Const   //記錄設計時的屏幕分辨率


  OriWidth=1366;
  OriHeight=768;

 

Type

 

  TfmForm=Class(TForm)   //實現(xiàn)窗體屏幕分辨率的自動調整
  Private
    fScrResolutionRateW: Double;
    fScrResolutionRateH: Double;
    fIsFitDeviceDone: Boolean;
    fPosition:Array of TRect;
    procedure FitDeviceResolution;
  Protected
    Property IsFitDeviceDone:Boolean Read fIsFitDeviceDone;
    Property ScrResolutionRateH:Double Read fScrResolutionRateH;
    Property ScrResolutionRateW:Double Read fScrResolutionRateW;
  Public
    Constructor Create(AOwner: TComponent); Override;
  End;

 

  TfdForm=Class(TfmForm)   //增加對話框窗體的修改確認
  Protected
    fIsDlgChange:Boolean;
  Public
  Constructor Create(AOwner: TComponent); Override;
  Property IsDlgChange:Boolean Read fIsDlgChange default false;
 End;

 

 

implementation

 

Constructor TfmForm.Create(AOwner: TComponent);
begin
 Inherited Create(AOwner);
  fScrResolutionRateH:=1;
  fScrResolutionRateW:=1;
  Try
    if Not fIsFitDeviceDone then
    Begin
      FitDeviceResolution;
   fIsFitDeviceDone:=True;
    End;
  Except
  fIsFitDeviceDone:=False;
  End;
end;

 

procedure TfmForm.FitDeviceResolution;
Var
  i:Integer;
  LocList:TList;
  LocFontSize:Integer;
  LocFont:TFont;
  LocCmp:TComponent;
  LocFontRate:Double;
  LocRect:TRect;
  LocCtl:TControl;
begin
  LocList:=TList.Create;
  Try
    Try
      if (Screen.width<>OriWidth)OR(Screen.Height<>OriHeight) then
      begin
        Self.Scaled:=False;
        fScrResolutionRateH:=screen.height/OriHeight;
        fScrResolutionRateW:=screen.Width/OriWidth;
        Try
          if fScrResolutionRateH<fScrResolutionRateW then
            LocFontRate:=fScrResolutionRateH
          Else
            LocFontRate:=fScrResolutionRateW;
        Finally
          ReleaseDC(0, GetDc(0));
        End;

        For i:=Self.ComponentCount-1 Downto 0 Do
        Begin
          LocCmp:=Self.Components[i];
          If LocCmp Is TControl Then
            LocList.Add(LocCmp);
          If PropertyExists(LocCmp,'FONT') Then
          Begin
            LocFont:=TFont(GetObjectProperty(LocCmp,'FONT'));
            LocFontSize := Round(LocFontRate*LocFont.Size);
            LocFont.Size:=LocFontSize;
          End;
        End;

        SetLength(fPosition,LocList.Count+1);
        For i:=0 to LocList.Count-1 Do
          With TControl(LocList.Items[i])Do
            fPosition[i+1]:=BoundsRect;
        fPosition[0]:=Self.BoundsRect;

        With LocRect Do
        begin
           Left:=Round(fPosition[0].Left*fScrResolutionRateW);
           Right:=Round(fPosition[0].Right*fScrResolutionRateW);
           Top:=Round(fPosition[0].Top*fScrResolutionRateH);
           Bottom:=Round(fPosition[0].Bottom*fScrResolutionRateH);
           Self.SetBounds(Left,Top,Right-Left,Bottom-Top);
        end;

        i:= LocList.Count-1;
        While (i>=0) Do
         Begin
          LocCtl:=TControl(LocList.Items[i]);
          If LocCtl.Align=alClient Then
          begin
            Dec(i);
            Continue;
          end;
          With LocRect Do
          begin
             Left:=Round(fPosition[i+1].Left*fScrResolutionRateW);
             Right:=Round(fPosition[i+1].Right*fScrResolutionRateW);
             Top:=Round(fPosition[i+1].Top*fScrResolutionRateH);
             Bottom:=Round(fPosition[i+1].Bottom*fScrResolutionRateH);
             LocCtl.SetBounds(Left,Top,Right-Left,Bottom-Top);
          end;
          Dec(i);
        End;
      End;

    Except on E:Exception Do
      Raise Exception.Create('進行屏幕分辨率自適應調整時出現(xiàn)錯誤'+E.Message);
    End;
  Finally
    LocList.Free;
  End;
end;

 

 


{ TfdForm }

constructor TfdForm.Create(AOwner: TComponent);
begin
  inherited;
  fIsDlgChange:=False;
end;

 

end.

 

上面包括兩個類,一個是普通窗體類,一個是其子類對話框型窗體類。在實際應用過程中只要自己創(chuàng)建的窗體類繼承自以上兩個類中的一個,例如 TForm1 = class(TfdForm),則不需添加任何源碼,設計出窗體會自動調整其上控件的尺寸,以適應不同的屏幕分辨率。

 

以上源碼經過驗證,效果非常好,解決了一個多年未決的問題!

 



    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多