如何将鼠标悬停在最小化,最大化和关闭按钮上?

Ian*_*oyd 20 delphi vcl delphi-xe6 windows-10

在Delphi应用程序中,当您将鼠标悬停在边框图标上时,例如:

  • 最小化
  • 最大化
  • 恢复

它行为不正确:

在此输入图像描述

与行为正确的应用程序进行比较:

在此输入图像描述

重现的步骤

  1. 单击文件,新建,VCL表单应用程序 - Delphi
  2. 单击运行(F9)
  3. 将鼠标悬停在最小化,最大化或关闭按钮上.

怎么修?

  • Windows 10,64位(在台式机上本机运行)
  • 德尔福XE6

编辑 - Delphi 7也失败了:

在此输入图像描述

在Delphi 5中:

在此输入图像描述

在Delphi 4中:

在此输入图像描述

我假设(即害怕)它是由ThemeServices引擎引起的; 他们可能认为不尊重用户的偏好很酷.但看起来它更基本.

兼容模式

  • none:失败
  • 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也失败了; 也用Delphi编写:

在此输入图像描述

高DPI是触发器

我终于找到了为什么它在我使用的每台Windows 10机器上都失败了; 但不适合所有人.高dpi.

将dpi设置为97(101%)或更高.

足够近

Dalija的解决方案有效:

在此输入图像描述

我们将忽略工具提示的问题,并在另一天进行战斗.

还应注意,Windows 10将建议您可能必须注销并重新签名才能使某些应用程序在更改DPI后正常工作.德尔福绝对是这样.

还应该指出的是,德尔福不会像这样容忍DPI背后的变化.这包括调整缩放滑块.这还包括将应用程序放在除主监视器之外的任何监视器上.

我们从未弄清楚问题是什么; 对于运行多个显示器的用户来说,它只是踢了它.

QC错误报告

因为Bor ... Impr ... CodeG ... Embarca ... Idera的QC网站是付费墙的背后,这里是错误报告的副本:

如你所见:没人在意.

Dal*_*kar 10

高DPI是触发器,它导致解决方案.

出现此问题的应用程序不支持高DPI.悬停问题的解决方案是通过使用1,2或3下的解决方案之一让他们了解或打开相关的兼容模式.

注意:当打开高DPI感知时,其余应用程序是否正常运行是另一个问题,并且因应用程序而异.

  1. 在兼容模式下,选中"在高DPI设置下禁用显示缩放"

  2. 调用SetProcessDPIAware在第一次调用.dpr文件-由伊恩·博伊德指出,调用这个函数可以真皮休闲条件,首选方法是使用清单比赛.SetProcessDPIAware

  3. 使用自定义清单truetrue/PM设置(默认Delphi清单包含"启用运行时主题"不高DPI意识)

当前版本的Delphi VCL和FMX框架缺乏对每个监视器DPI感知的支持,因此true/PM仅在您自己处理每个监视器DPI时才使用清单.向QP报告VCL和FireMonkey缺少对Windows 8.1(和Windows 10)的Per-Monitor DPI支持


  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>
Run Code Online (Sandbox Code Playgroud)

要么

  <asmv3:application>
    <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
      <dpiAware>true/PM</dpiAware>
    </asmv3:windowsSettings>
  </asmv3:application>
Run Code Online (Sandbox Code Playgroud)

更新:

Delphi VCL是错误行为的来源,具体问题是在TForm课堂或其祖先的某个地方.使用直接Windows API时,导致Windows正常运行.

行为正常的Windows API代码:

  MessageBox(0, 'Correct', 'Caption', MB_OK); 

  ShowMessage('Correct'); // if themes are enabled -> Windows Task dialog is used
Run Code Online (Sandbox Code Playgroud)

完整的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, 0, 0, 360, 200, 0, 0, hInstance, nil);

  while GetMessage(Msg, 0, 0, 0) do
    begin
      TranslateMessage(Msg);
      DispatchMessage(Msg);
    end;
end.
Run Code Online (Sandbox Code Playgroud)

行为不端的VCL表格:

var
  f: TForm;

  f := CreateMessageDialog('Broken', mtWarning, mbOKCancel, mbOk);
  f.ShowModal;
  f.Free;

  f := TForm.Create(nil);
  f.ShowModal;
  f.Free;
Run Code Online (Sandbox Code Playgroud)