delphi 窗体自适应屏幕分辨率
delphi 窗体自适应屏幕分辨率
这是个困惑我很长时间的问题,到今天终于得到解决了。 话说Delphi有个很强的窗体设计器,这一点让VC粉丝垂涎三尺而不可得。但是,Delphi里设计的窗体并没有自动适应屏幕分辨率的属性,也就是说,软件设计时调整完美的窗体控件布局,在不同屏幕分辨率的机器上运行时可能会变得面目全非。控件之间会相互移位,有的甚至移出窗体再也找不到了。 这个问题在网上搜索过多次,但大都依据控件方法ScaleBy或者ChangeScale。采用这两个方法进行自适应调整,我自己都试过,但效果并不理想。后来我自己也写了一个继承自窗体的基类,覆盖构造函数,调用自己的一个设备分辨率自适应方法,该方法遍历窗体上所有控件,并按照设计时的屏幕分辨率和当前屏幕分辨率的比值,逐一计算控件的位置和尺寸。这个想法是不错,效果也是有的,比单纯的采用ScaleBy或者ChangeScale方法要好,但也不是非常理想,没有达到自己设想的要求。原因在哪里,一直不知道。 我原来的代码曾经发布在Delphi盒子和CSDN上。 这个问题今天终于得以彻底解决了!! 原因是,我原以为将所有控件的Align属性设为alnone,Anchors属性设为空[],控件位置和尺寸就不会受其容器尺寸改变的影响。今天我在设计期对此进行试验时,发现不是这样。当窗体大小改变的时候,即使某个控件的Align:=alNone,Anchors:=[],它依然会随着窗体尺度的变化而变化。这意味着我需要一个数组事先保存所有控件的原始位置和尺寸。在窗体因为屏幕分辨率的改变而自动调整时,计算的依据依然是不变的原始窗体位置尺寸数据,这样问题就解决了。 闲话少说,上源码。 unit uMyClassHelpers; interface Uses SysUtils,Windows,Classes,Graphics, Controls,Forms,Dialogs,
uMySysUtils; Const //记录设计时的屏幕分辨率 OriWidth=1366;
OriHeight=768; Type TfmForm=Class(TForm) //实现窗体屏幕分辨率的自动调整
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('进行屏幕分辨率自适应调整时出现错误'+E.Message);
End;
Finally
LocList.Free;
End;
end; { TfdForm } constructor TfdForm.Create(AOwner: TComponent);
begin
inherited;
fIsDlgChange:=False;
end; end.
delphi 窗体自适应屏幕分辨率的更多相关文章
- Delphi:窗体自适应屏幕分辨率的改进
在窗体依据屏幕分辨率自适应调整尺度方面,昨天的工作可以说是一个突破点.昨天的工作找到了长期以来我的原有方案的问题所在,这是非常关键的.但是昨天晚上的解决方案并不完美,今天的这个才是比较完美的解决版. ...
- Delphi:窗体自适应屏幕分辨率(根据预设值的比例改变)
delphi 程序适应屏幕分辨率,先在表单单元的Interface部分定义两个常量, 表示设计时的屏幕的宽度和高度(以像素为单位). 在表单的Create事件中先判断 当前分辨率是否与设计分辨率相同, ...
- Delphi自动适应屏幕分辨率的属性
https://www.cnblogs.com/zhangzhifeng/category/835602.html 这是个困惑我很长时间的问题,到今天终于得到解决了. 话说Delphi有个很强的窗体设 ...
- #region 自适应屏幕分辨率
#region 自适应屏幕分辨率 [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public ...
- Unity3D NGUI自适应屏幕分辨率(2014/4/17更新)
原地址:http://blog.csdn.net/asd237241291/article/details/8126619 原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 本文链接地址: ...
- Unity NGUI根据高度自适应屏幕分辨率
Unity版本:4.5.1 NGUI版本:3.6.5 本文内容纯粹转载,转载保留参考链接和作者 参考链接:http://blog.csdn.net/asd237241291/article/detai ...
- H5自适应屏幕分辨率大小
说明: ①:H5自适应不同分辨率的设备,其实主要就一句 <meta name="viewport" content="width=device-width,init ...
- NGUI自适应屏幕分辨率
unity官方承诺的新ui系统一直没有推出来,我们的UI使用的是原生的OnGUI系统,刚好UI需要改版,索性就想迁到NGUI上面来,于是看了一下NGUI源码,发现NGUI可以大大的降低DrawCall ...
- delphi 动态更改屏幕分辨率(转)
一.如何动态更改屏幕分辨率 有许多小工具可以在不重新启动Windows的条件下,动态更改屏幕分辨率.你是不是也想自己动手做一个呢?请在interface段中加入下面一句 function Resolu ...
随机推荐
- BZOJ 1093 [ZJOI2007]最大半连通子图 - Tarjan 缩点
Description 定义一个半联通图为 : 对任意的两个点$u, v$,都有存在一条路径从$u$到$v$, 或从$v$到$u$. 给出一个有向图, 要求出节点最多的半联通子图, 并求出方案数. ...
- UVA 11324.The Largest Clique tarjan缩点+拓扑dp
题目链接:https://vjudge.net/problem/UVA-11324 题意:求一个有向图中结点数最大的结点集,使得该结点集中任意两个结点u和v满足:要目u可以到达v,要么v可以到达u(相 ...
- 大牛的距离(笑cry)精简算法
在一条数轴上有N头牛在不同的位置上,每头牛都计算到其它各头牛的距离.求这n*(n-1)个距离的总和.1<= N <= 10000.每头牛所在位置是一个范围在0到1,000,000,000之 ...
- Window7安装tensorflow整套环境详细流程
安装tensorflow方式有好多种,为了方便编译环境以及包管理,这里采用Anaconda平台安装tensorflow. tensorflow官网:http://www.tensorflow.org/ ...
- [ ZooKeeper]ZooKeeper 的功能和原理
Zookeeper功能简介: ZooKeeper 是一个开源的分布式协调服务,由雅虎创建,是 Google Chubby 的开源实现.分布式应用程序可以基于 ZooKeeper 实现诸如数据发布/订阅 ...
- wifi功能模块
1. API 10 Android2.3.3 不支持wifi代理设置. 2017-09-29 原来addOrUpdateNetwork之前,wifi配置并不会立即生效,要想立即生效,就要 wifiMa ...
- 记录一次JVM调优【GC日志的分析】
首先查看服务器版本默认信息: 修改tomcat/bin/catalina.sh,在最顶端加入JAVA_OPTS="$JAVA_OPTS -XX:+PrintGCDetails -Xloggc ...
- chmod / chown /chattr
显示了七列信息,从左至右依次为:权限.文件数.归属用户.归属群组.文件大小.创建日期.文件名称 d :第一位表示文件类型 d 文件夹 - 普通文件 l 链接 b 块设备文件 p 管道文件 c 字符设备 ...
- (6)How language shapes the way we think
https://www.ted.com/talks/lera_boroditsky_how_language_shapes_the_way_we_think/transcript 00:12So, I ...
- boost--线程
1.thread的使用 boost的thread包含了线程创建.使用.同步等内容,使用thread需要包含头文件"boost\thread.hpp". thread中使用了需要编 ...