好吧,我本来不想在 QDAC 里添加 UI 相关的东西,不过 FMX 的树实在让人不爽,等 VirtualTreeView 的 FMX 版也等不到,FMX 的闭源实现到是有一些,但根据群友的反馈,也就那样吧。所以狠狠心,咬咬牙,花了近一周的时间,自己写了一个,命名为 TQVirtualTreeView,自己测试的结果,
月度归档: 2017年10月
[FMX]在 QPlugins 中 VCL 宿主使用 FMX DLL 需要手动处理的问题说明
由于众所周知的原因,FMX 的 DLL 在 FreeLibrary 时,会出现 AV 异常,这实际上包含了两方面的原因: FreeLibrary 时,未正确清理内部的计时器,造成 FreeLibrary 后,内部的计时器到指定的时间点后仍然运行,结果就出现了 AV 错误。 GDI+ 初始化和清理只能在宿主程序中执行
[QSecurity]QSecurity 使用入门指南
QSecurity 是 QPlugins 的安全相关插件接口及其实现, qplugins_security.pas 定义了安全相关的接口,我们在插件中使用时,只需要引用这个接口文件就可以了。而服务的实现单元并不包含在免费开源的范围内,如果您不想自己实现,或者想参考实现,需要付费购买,价格为人民币 99.00 元。 无论
[教程]解析 Web 颜色(VCL)
这段代码支持的Web颜色格式为 #RRGGBB/#RGB 以及以Web标准名称命名的颜色(需要引用单元:qstring,graphutil):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
function ParseWebColor(S: String;ADefColor:TColor=clBlack): TColor; var p: PChar; c: array [0 .. 3] of Byte absolute Result; i: Integer; begin Result := 0; p := PChar(S); i := 0; if p^ in ['a' .. 'z', 'A' .. 'Z'] then begin if IdentToColor('cl' + S, i) then Result := i else begin S := 'clWeb' + S; for I := 0 to High(WebNamedColors) do begin if CompareText(WebNamedColors[I].Name, S) = 0 then begin Result := WebNamedColors[I].Value; Exit; end; end; Result := ADefColor; end; Exit; end else if p^ = '#' then begin Inc(p); if Length(S) = 4 then // #RGB begin while p^ <> #0 do begin if IsHexChar(p^) then begin c[i] := (HexValue(p^) * 255) div 15; Inc(i); Inc(p); end else break; end; end else if Length(S) = 7 then begin while p^ <> #0 do begin if IsHexChar(p^) then begin c[i] := HexValue(p^); Inc(p); if p^ <> #0 then begin c[i] := (c[i] shl 4) + HexValue(p^); Inc(p); end; Inc(i); end else break; end; end; end; if i <> 3 then Result := ADefColor; end; |
比如#FF0000 和 #F00 都被解释为红色。
[工具]ScreenRuler,使用显示器来测量长度
运行效果: 下载:screenruler 使用说明:这么简单的软件,不需要啥说明了吧。
[FMX]在 FMX 程序中绘制单像素宽度的直线
在前面的一篇文章中,我介绍了一种绘制低品质直线的方法,但是这么做,效率上肯定要打折扣的。在和群里的朋友们一顿交流折腾后,对于绘制水平或垂直的直线,现在有两种更简单的办法来解决这一问题: 办法一:使用 FillRect 来代替 DrawLine 绘制,矩形区域的大小注意要在相应的方向上加 0.5 个像素。 [crayon
[FMX]太糊弄了,请不要使用 FMX.Platform.Win 中 GetDisplayMatrics 来获取物理信息
上官方的实现源码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
function TPlatformWin.GetDisplayMetrics: TDeviceDisplayMetrics; var R: TRect; begin Winapi.Windows.GetWindowRect(GetDesktopWindow, R); Result.PhysicalScreenSize := TSize.Create(R.Width, R.Height); Result.RawScreenSize := Result.PhysicalScreenSize; Result.LogicalScreenSize := Result.PhysicalScreenSize; if Result.PhysicalScreenSize.cx > 0 then Result.AspectRatio := Result.PhysicalScreenSize.cy / Result.PhysicalScreenSize.cx else Result.AspectRatio := 1; Result.PixelsPerInch := 96; // Windows Default Result.ScreenScale := 1; Result.FontScale := 1; end; |
对比 Android 版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
function TAndroidScreenServices.GetDisplayMetrics: TDeviceDisplayMetrics; var Metrics: JDisplayMetrics; RawScreenSize: JPoint; DensityDPI: Single; begin Metrics := TAndroidHelper.DisplayMetrics; if Metrics <> nil then begin Result.PhysicalScreenSize := TSize.Create(Metrics.widthPixels, Metrics.heightPixels); DensityDPI := Round((Metrics.xdpi + Metrics.ydpi) / 2); if DensityDPI <> 0 then begin Result.LogicalScreenSize.cx := Trunc(Metrics.widthPixels / DensityDPI); Result.LogicalScreenSize.cy := Trunc(Metrics.heightPixels / DensityDPI); end else Result.LogicalScreenSize := Result.PhysicalScreenSize; if Metrics.widthPixels <> 0 then Result.AspectRatio := Metrics.heightPixels / Metrics.widthPixels else Result.AspectRatio := 1; Result.PixelsPerInch := Round(DensityDPI); Result.ScreenScale := Metrics.density; Result.FontScale := Metrics.scaledDensity; end else Result := TDeviceDisplayMetrics.Default; RawScreenSize := MainActivity.getRawDisplaySize; if RawScreenSize <> nil then if (Result.PhysicalScreenSize.cx > Result.PhysicalScreenSize.cy) and (RawScreenSize.x > RawScreenSize.y) then Result.RawScreenSize := TSize.Create(RawScreenSize.x, RawScreenSize.y) else Result.RawScreenSize := TSize.Create(RawScreenSize.y, RawScreenSize.x) else Result.RawScreenSize := Result.PhysicalScreenSize; end; |
再对比 iOS 的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
function TCocoaTouchScreenServices.GetDisplayMetrics: TDeviceDisplayMetrics; const IOSBasePPI = 163; var ScreenSize: TPointF; ScreenScale: Single; begin ScreenSize := GetScreenSize; ScreenScale := GetScreenScale; Result.PhysicalScreenSize := TSize.Create(Round(ScreenSize.X * ScreenScale), Round(ScreenSize.Y * ScreenScale)); Result.RawScreenSize := Result.PhysicalScreenSize; Result.LogicalScreenSize := TSize.Create(Round(ScreenSize.X), Round(ScreenSize.Y)); if Abs(ScreenSize.X) > 0 then Result.AspectRatio := ScreenSize.Y / ScreenSize.X else Result.AspectRatio := 1; Result.PixelsPerInch := Round(IOSBasePPI * ScreenScale); Result.ScreenScale := ScreenScale; Result.FontScale := ScreenScale; end; |
换句话说,Windows 版的物理屏幕尺寸、逻辑屏
[杂谈]中秋月圆人团圆,国庆国安家平安
祝大家中秋国庆双节快乐,万事如意,事事顺心。祝假日还在码码的码农们节日码码无Bug,工资倍倍翻!