以下代码是关闭我的应用程序。
procedure TfrmMain.btnClose1Click(Sender: TObject);
var
i : Integer;
begin
for i := 255 downto 0 do begin
frmMain.AlphaBlendValue := i;
application.ProcessMessages;
end;
Close;
end;
将Windows性能设置为“让Windows选择...”
如果我将性能选项设置为“调整以获得最佳性能”
我在Delphi 2010和DelphiXE2上测试了这一点,结果是一样的。 这在Windows 7 Ultimate 64bit上进行了测试,如果这有任何区别的话。
至少可以说这种行为让我很困惑。
就这一点而言,我不确定这是一个Windows 7错误,一个Delphi错误还是我缺乏知识。
至于解决方案...... 有没有办法判断Windows是否在垃圾图形/最高性能模式下运行,以便我可以在我的应用程序中禁用Alpha淡入淡出效果?
为清晰起见编辑: 虽然我想修复淡入淡出我真正想要的是一种确定Windows性能设置的方法。
我正在寻找如何确定特定的Windows设置 - 当您进入Windows性能选项时,有3个选项卡。在第一个“视觉效果”选项卡上,有3个固定选项和第4个“自定义”选项。我最不想确定所选的选项是否为“调整以获得最佳性能”,如果我可以更好地确定此选项卡上的设置。
感谢任何帮助。
答案 0 :(得分:7)
您的代码的根本问题在于,无论计算机的性能特征如何,您都在强制进行256次不同的更新。您不必使用255和0之间的每个alpha混合值。您可以跳过某些值并仍然具有平滑淡入淡出。
您需要考虑机器的实际图形性能。由于您无法预测,您应该在淡入淡出代码中考虑实时。无论机器的性能特性如何,这样做都能为您提供一致的褪色速率。
所以,这是一个简单的例子来演示将淡入淡出率与实时联系起来:
procedure TfrmMain.btnClose1Click(Sender: TObject);
var
Stopwatch: TStopwatch;
NewAlphaBlendValue: Integer;
begin
Stopwatch := TStopwatch.StartNew;
while True do
begin
NewAlphaBlendValue := 255-(Stopwatch.ElapsedMilliseconds div 4);
if NewAlphaBlendValue>0 then
AlphaBlendValue := NewAlphaBlendValue
else
break;
end;
Close;
end;
淡入淡出的持续时间为1秒。您可以随时调整数学,以根据您的要求修改持续时间。即使在低性能机器上,此代码也会产生平滑的淡入淡出。
我还要评论您不应在drmMain
方法中使用全局变量TfrmMain
。 TfrmMain
方法已经可以访问该实例。它是Self
。当然,您可以省略Self
。对ProcessMessages
的调用更糟糕。这允许重新处理排队的输入消息。你不希望这种情况发生。因此,请移除对ProcessMessages
的调用。
您实际上询问有关检测调整以获得最佳性能的设置。但我认为那是错误的问题。首先,您应该修复淡入淡出代码,以使淡入淡出持续时间与图形性能无关。
完成此操作后,如果用户要求较低质量的外观设置,您仍可能希望禁用淡入淡出。我认为你不应该寻找你提到的3个罐装选项中的一个。它们很可能是特定于Windows版本的。我个人会在最小化和最大化设置时将行为建立在 Animate窗口上。我的理由是,如果用户不希望最小化和最大化动画,那么可能他们不希望窗口接近褪色。
以下是阅读该设置的方法:
function GetWindowAnimation: Boolean;
var
AnimationInfo: TAnimationInfo;
begin
AnimationInfo.cbSize := SizeOf(AnimationInfo);
if not SystemParametersInfo(SPI_GETANIMATION, AnimationInfo.cbSize,
@AnimationInfo, 0) then
RaiseLastOSError;
Result := AnimationInfo.iMinAnimate<>0;
end;
我认为您可能关注的大多数其他设置也可以使用SystemParametersInfo
来阅读。您应该可以按照documentation。
答案 1 :(得分:0)
对于迟到的跟进感到抱歉,我花了一段时间才弄清楚我的问题及其背后的一些问题。
首先,感谢David Heffernan对Delphi诊断部门处理淡入循环和TStopWatch功能信息的更好方法有所了解,非常感谢。
关于能否确定Windows的“性能设置......”
使用以下未优化的淡入淡出循环时
procedure TfrmMain.btnFadeNCloseClick(Sender: TObject);
var
i : Integer;
begin
for i := 255 downto 0 do
frmMain.AlphaBlendValue := i;
Close;
end;
导致性能问题的实际 Windows性能选项设置是“ 启用桌面合成 ”和“ 使用视觉效果Windows和按钮上的样式 “。如果两个选项都启用,则没有问题,如果未启用任何设置,则循环爬行**(如果表单最大化,则在我的系统上大约12秒)。
原来打开或关闭 Aero Glass 会影响这两个相同的设置。因此能够检测Aero Glass是否打开使我能够确定是否在我的应用程序中不启用表单效果,例如过渡淡化和其他眼睛糖果。此外,我现在还可以在我的错误报告中捕获这些信息。
**请注意,这似乎是一个NVidia问题/错误,或者至少是一个在使用NVidia显卡的系统上更严重的问题。 2 不同的NVidia系统(最新的,如果不是最新的驱动程序)我 对于混合形式淡化得到类似的结果 - 小于 如果Aero Glass开启,则为0.001秒,如果是Aero Glass,则为12秒 关闭。在具有Intel显卡的系统上 - 小于.001秒 如果Aero Glass打开,如果Aero Glass关闭,大约需要3.7秒。现在 授予我的测试样本很小,3个NVidia系统(算上我的 最初报告该问题的客户)和一个非NVidia系统 但如果我使用的是体面的NVidia显卡我就不会打扰了 关闭航空玻璃。
以下是检测Aero Glass是否通过Delphi启用的工作代码: 此功能已在Windows7 64位系统上进行了测试,可与Delphi 2007,2010和Xe2(32&amp; 64bit)配合使用。 以下我在网上找到的所有Delphi功能版本都被打破了 - 以及有人抱怨获取访问冲突错误的评论。 最后阐明修复坏代码的是Gerry Coll对:AccessViolationException in Delphi - impossible (check it, unbelievable...)的回应,这是关于尝试修复同一类型函数中的AV错误。
function ISAeroEnabled: Boolean;
type
_DwmIsCompositionEnabledFunc = function(var IsEnabled: Bool): HRESULT; stdcall;
var
Flag : BOOL;
DllHandle : THandle;
OsVersion : TOSVersionInfo;
DwmIsCompositionEnabledFunc: _DwmIsCompositionEnabledFunc;
begin
Result:=False;
ZeroMemory(@OsVersion, SizeOf(OsVersion));
OsVersion.dwOSVersionInfoSize := SizeOf(TOSVERSIONINFO);
if ((GetVersionEx(OsVersion)) and (OsVersion.dwPlatformId = VER_PLATFORM_WIN32_NT) and
(OsVersion.dwMajorVersion = 6) and (OsVersion.dwMinorVersion < 2)) then //Vista&Win7 only (no Win8)
begin
DllHandle := LoadLibrary('dwmapi.dll');
try
if DllHandle <> 0 then
begin
@DwmIsCompositionEnabledFunc := GetProcAddress(DllHandle, 'DwmIsCompositionEnabled');
if (@DwmIsCompositionEnabledFunc <> nil) then
begin
if DwmIsCompositionEnabledFunc(Flag)= S_OK then
Result:= Flag;
end;
end;
finally
FreeLibrary(DllHandle);
end;
end;
end;