>最小化
>最大化
>恢复
它的行为不正确:
与正确行为正确的应用程序进行比较:
重现步骤
>单击文件,新建,VCL表单应用程序 – Delphi
>单击运行(F9)
>将鼠标悬停在最小化,最大化或关闭按钮上。
怎么修?
> Windows 10,64位(在台式机上本机运行)
> Delphi XE6
编辑 – 它也失败了与Delphi 7:
并在德尔福5:
并在德尔福4:
我假设(即害怕)它是由ThemeServices引擎引起的;在那里他们可能以为很高兴不尊重用户的喜好。但是看起来更像是更根本的东西。
兼容性模式
>无:失败
> Windows 8:失败
> Windows 7:失败
> Windows Vista(Service Pack 2):失败
> Windows Vista(Service Pack 2):失败
> Windows Vista:失败
> Windows XP(Service Pack 3)(非客户端区域禁用):工作
> Windows XP(Service Pack 2)(非客户端区域禁用):工作
> Windows 98 / Windows Me(非客户端区域禁用):工作
> Windows 95(非客户端区域禁用):作品
Skype的
Skype也失败;也写在德尔福:
高DPI是触发器
我终于弄清楚为什么它在每个使用的Windows 10机器上都失败了但不是每个人高dpi。
将dpi设置为97(101%)或更高。
足够近
达利亚的解决方案有:
我们会忽略这个工具提示的问题,并且为了争取一天而活下去。
还应该注意的是,Windows 10会建议您在更改DPI后,可能需要注销并重新登录才能使某些应用程序正常工作。德尔福绝对是这样的。
还应该指出的是,德尔福不会容忍这样的DPI背后的变化。这包括调整缩放滑块。这也包括将应用放在除主显示器之外的任何显示器上。
解决方法
展示该问题的应用程序不是高DPI感知。悬停问题的解决方案是通过使用1,2或3之间的解决方案,使他们知道或打开相关的兼容性模式。
注意:当高DPI意识被打开时,是否其余的应用程序会正常运行是另一个问题,并且将因应用而异。
>在兼容模式下,检查“在高DPI设置上禁用显示缩放”
>调用SetProcessDPIAware作为第一次调用.dpr文件 – 如Ian Boyd所指出的,调用此函数可以进行竞争条件,首选方式是使用清单。 SetProcessDPIAware
>使用true或true / PM设置的自定义清单(“启用运行时主题”中包含的默认Delphi清单不高DPI)
当前版本的Delphi VCL和FMX框架缺乏对每个监视器DPI感知的支持,因此只有当您自己处理每个监视器DPI时,才使用true / PM清单。报告为QP为VCL and FireMonkey lack Per-Monitor DPI support for Windows 8.1 (and Windows 10)
<asmv3:application> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <dpiAware>true</dpiAware> </asmv3:windowsSettings> </asmv3:application>
要么
<asmv3:application> <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings"> <dpiAware>true/PM</dpiAware> </asmv3:windowsSettings> </asmv3:application>
更新:
Delphi VCL是错误行为的来源,具体问题是TForm类或其祖先的某个地方。当使用直接的Windows API时,窗口的行为正常。
Windows API代码行为正常:
MessageBox(0,'Correct','Caption',MB_OK); ShowMessage('Correct'); // if themes are enabled -> Windows Task dialog is used
完整的Delphi示例应用程序,创建主窗口而不使用VCL – 行为正常
program win; {$R *.res} uses Windows,Messages,SysUtils; var Msg: TMSG; LWndClass: TWndClass; hMainHandle: HWND; function WindowProc(HWND,Msg: Longint; wParam: wParam; lParam: lParam): Longint; stdcall; begin if Msg = WM_DESTROY then PostQuitMessage(0); Result := DefWindowProc(HWND,Msg,wParam,lParam); end; begin LWndClass.hInstance := hInstance; with LWndClass do begin lpszClassName := 'WinApiWnd'; Style := CS_PARENTDC or CS_BYTEALIGNCLIENT; hIcon := LoadIcon(hInstance,'MAINICON'); lpfnWndProc := @WindowProc; hbrBackground := COLOR_BTNFACE + 1; hCursor := LoadCursor(0,IDC_ARROW); end; RegisterClass(LWndClass); hMainHandle := CreateWindow(LWndClass.lpszClassName,'Window Title',WS_CAPTION or WS_MINIMIZEBox or WS_SYSMENU or WS_VISIBLE,360,200,hInstance,nil); while GetMessage(Msg,0) do begin TranslateMessage(Msg); DispatchMessage(Msg); end; end.
行为失调的VCL形式:
var f: TForm; f := CreateMessageDialog('Broken',mtWarning,mbOKCancel,mbOk); f.ShowModal; f.Free; f := TForm.Create(nil); f.ShowModal; f.Free;