工具提示:错误的位置和缩放

时间:2021-01-20 08:14:31

标签: windows winforms user-interface devexpress

我有一个 Windows 窗体应用程序和一个多显示器配置:

  1. 主显示器(笔记本): 分辨率:1980x1080(推荐) 缩放比例:125%(推荐)

  2. 外部显示: 分辨率:1980x1080(推荐) 缩放:100%(推荐)

Windows 版本:Windows 10 版本 1909(操作系统内部版本 18363.1198)

应用:

  • 目标框架:4.7.2(或 4.5)
  • DevExpress 18.2.9.19199(或 18.1.5)
  • DPI 意识:不知道

场景 1:

  • 在主显示器上启动应用程序: 应用:模糊(可能按系统缩放到 125%)。 工具提示:模糊、预期大小、预期位置。 => 好的。

  • 将正在运行的应用程序移动到外部显示器: 应用程序:清除(可能不再缩放)=> 好的 工具提示:模糊、比预期大、位置错误甚至屏幕外 - 鼠标光标向左越远,向左的位置越偏离。 => 不行。

场景 2:

  • 在外部显示器上启动应用程序: 应用:透明(可能没有缩放)。 工具提示:清晰、预期大小、预期位置。 => 好的。

  • 将正在运行的应用程序移至主显示屏: 应用程序:模糊(可能缩放到 125%)=> 好的 工具提示:清晰、比预期小、位置错误甚至离开屏幕 - 鼠标光标向右移动得越远,向左移动的位置越远。 => 不行。

我知道缩放出现在主显示器上以及为什么不在外部显示器上的原因。参见示例:https://support.microsoft.com/en-us/help/3025083/windows-scaling-issues-for-high-dpi-devices 但我不明白为什么工具提示会在外部显示器上缩放,即使应用程序的其余部分不是,并且外部显示器的缩放设置为 100%。 我的目标是修复外部显示器上的工具提示大小和位置。

我曾尝试用一个简单的测试应用程序来重现该问题,该应用程序使用相同的 .NET Framework 目标版本和 DevExpress 版本,但尚未成功。

[编辑]:如果您在应用程序已经运行时休眠 Windows,从休眠状态唤醒后,问题似乎消失了:工具提示的大小和位置符合预期。

[EDIT2]:我已经与 DevExpress 支持人员讨论过这个问题,我们已经创建了一个测试项目来重现该问题,该项目不包含任何 DevExpress 组件,而只包含标准的 Winforms 控件。

DevExpress 似乎使用具有 WS_POPUP 窗口样式的窗口来显示工具提示。

重现问题的第二个必需部分是另一种显示在不同显示器上的表单(即不是主表单显示工具提示的那个),具有不同的缩放比例。

这是一个几乎完整的示例来重现这一点。我想知道这是否应该被视为 Windows 或 WinForms 错误?

Result of test application

Form1.cs:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WrongTooltipLocation
{
    public partial class Form1 : Form
    {
        /* Windows Display Settings:
         * - Main Screen
         * Scaling: 125%
         * 
         * - Second Screen
         * Scaling: 100%
         * 
         * To show the tooltip, move the mouse cursor over Button2.
         */ 

        public Form1()
        {
            InitializeComponent();
            button2.MouseEnter += Button2_MouseEnter;
        }

        private void Button2_MouseEnter(object sender, EventArgs e) {
            _messageForm.Activate();

            // Show tooltip
            TooltipForm tooltipForm = new TooltipForm();            
            tooltipForm.Location = Cursor.Position;
            tooltipForm.Size = new Size(100, 100);
            tooltipForm.Visible = true;
        }

        protected override void OnShown(EventArgs e) {
            base.OnShown(e);

            ShowMessage();

            // After the ShowMessage method is called, move the main form to the second screen and keep the message form on the main screen
            // => tooltips are displayed at the wrong location
        }

        Form _messageForm;
        private void ShowMessage()
        {
            _messageForm = new Form()
            {
                TopLevel = true,
                ControlBox = false,
                StartPosition = FormStartPosition.Manual,
                FormBorderStyle = FormBorderStyle.None,
                ShowInTaskbar = false,
                Visible = false
            };

            Label label = new Label()
            {
                Location = new Point(20, 20),
                Text = "Message Form",
                ForeColor = Color.Green
            };
            _messageForm.Controls.Add(label);

            _messageForm.Show();
            _messageForm.Activate();
        }
    }

    public class TooltipForm : Form {

        public TooltipForm() {
            this.StartPosition = FormStartPosition.Manual;
            BackColor = Color.Red;

            // This label is blurry on the second screen and clear on the main screen.
            // Shouldn't that be the other way around?
            Label label = new Label()
            {
                Location = new Point(20, 20),
                Text = "My Tooltip",
                ForeColor = Color.Yellow
            };
            Controls.Add(label);
        }
        
        protected override CreateParams CreateParams {
            get {
                CreateParams cp = base.CreateParams;
                cp.Style = unchecked((int)0x80000000); //WS_POPUP
                return cp;
            }
        }        
    }
}

Form1.designer.cs

using System;

namespace WrongTooltipLocation
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
            this.button2 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // button2
            // 
            this.button2.Location = new System.Drawing.Point(65, 84);
            this.button2.Name = "button2";
            this.button2.Size = new System.Drawing.Size(75, 23);
            this.button2.TabIndex = 1;
            this.button2.Text = "button2";
            this.toolTip1.SetToolTip(this.button2, "Button 2");
            this.button2.UseVisualStyleBackColor = true;
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(632, 278);
            this.Controls.Add(this.button2);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }

        

        #endregion
        private System.Windows.Forms.ToolTip toolTip1;
        private System.Windows.Forms.Button button2;
    }
}

程序.cs

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Windows.Forms;

namespace WrongTooltipLocation
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
  </appSettings>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
  </startup>

  <runtime>
    <generatePublisherEvidence enabled="false" />
    <loadFromRemoteSources enabled="true" />
  </runtime>
</configuration>

应用程序清单

<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />
      </requestedPrivileges>
    </security>
  </trustInfo>

  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
    </application>
  </compatibility>

  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
    </windowsSettings>
  </application>
 
</assembly>

0 个答案:

没有答案