如何使一个成形的窗口窗体始终将自己定位在另一个窗体上的同一个位置?

Posted

技术标签:

【中文标题】如何使一个成形的窗口窗体始终将自己定位在另一个窗体上的同一个位置?【英文标题】:How to make a shaped windows form always position itself in the same place on another form? 【发布时间】:2017-09-28 00:06:14 【问题描述】:

我在一个项目中有两个 Windows 窗体:一个名为 frm1 的普通矩形窗体和一个名为 frm2 的异形窗体窗体。在frm1 中有一个名为themeBtn 的按钮,用于控制frm2 的可见性。现在我想让frm2始终显示在frm1的同一位置(themeBtn下方)(frm1可以移动,但它的大小是固定的))。怎么办?

下面是frm2的形状代码:

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)

    System.Drawing.Drawing2D.GraphicsPath shape = new System.Drawing.Drawing2D.GraphicsPath();
    Point point1 = new Point(0, 12);
    Point point2 = new Point(133, 12);
    Point point3 = new Point(141, 0);
    Point point4 = new Point(149, 12);
    Point point5 = new Point(282, 12);
    Point point6 = new Point(282, 238);
    Point point7 = new Point(0, 238);
    Point[] curvePoints =
             
         point1,
         point2,
         point3,
         point4,
         point5,
         point6,
         point7
     ;

    shape.AddPolygon(curvePoints);
    this.Region = new System.Drawing.Region(shape);

我尝试了以下代码徒劳:

   protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
        
            Point p = new Point();
            p = Properties.Settings.Default.themeBtnLocation;
            System.Drawing.Drawing2D.GraphicsPath shape = new System.Drawing.Drawing2D.GraphicsPath();
            Point point1 = new Point(0, p.Y+12);
            Point point2 = new Point(p.X-8, p.Y+12);
            Point point3 = new Point(p.X, p.Y);
            Point point4 = new Point(p.X+8, p.Y+12);
            Point point5 = new Point(2*p.X, p.Y+12);
            Point point6 = new Point(2*p.X, s.Height);//height of frm2
            Point point7 = new Point(0, s.Height);
            Point[] curvePoints =
                     
                 point1,
                 point2,
                 point3,
                 point4,
                 point5,
                 point6,
                 point7
             ;

            shape.AddPolygon(curvePoints);
            this.Region = new System.Drawing.Region(shape);
        

我尝试做的是很多软件中的thmem select。见下图

enter image description here

当我点击主题按钮时,无论主窗体是否移动,按钮下方都会显示一个新的自定义形状。)

【问题讨论】:

该代码非常错误,永远不要在 OnPaint 中执行任何需要重新绘制窗口的操作。就像设置 Region 属性一样。这样做会导致 UI 线程燃烧 100% 内核。它属于构造函数,如果要使形状适合窗口,可能在 OnLoad 或 OnResize 中。 Location 和 ClientSize 属性仍然很重要,您必须使其足够大,这样形状才不会被剪裁。然后通过设置 Location 将其移动到正确的位置。 谢谢。我已经编辑了我的问题,以便更清楚一点。你的意思是我应该在frm1的LocationChanged事件中设置frm2的位置吗? 是的。请注意 ToolTip 类具有 OwnerDraw 属性。没有 OwnerDraw 已经看起来像这样了。 谢谢。我想在单击按钮时显示一个新的自定义形状表单而不是几句话,因此 UI 非常不同。可能我的英文不太好给你描述清楚。我已经将ui设计上传到githublink,你可以检查一下吗?基本上,我想做同样的事情。(当我单击主题按钮时,无论主窗体是否移动,按钮下方都会显示一个新的自定义形状。)。再次感谢您的患者回答我的问题。 【参考方案1】:

我已经在下面的代码中解决了这个问题:

frm8.Location = themeButton.PointToScreen(new Point(Point.Empty.X-(int)(0.680*frm8.Size.Width), Point.Empty.Y+24));

see reference

上面的代码比下面的代码更好,表单会根据被点击的确切位置稍微改变它的位置。

this.Cursor = new Cursor(Cursor.Current.Handle);
frm8.Location = new Point(Cursor.Position.X - (int)(0.726 * frm8.Size.Width),
   Cursor.Position.Y+15); 

【讨论】:

以上是关于如何使一个成形的窗口窗体始终将自己定位在另一个窗体上的同一个位置?的主要内容,如果未能解决你的问题,请参考以下文章

Qt 如何获取滚动窗体中鼠标点击的坐标

QT怎么设置控件在窗口大小发生变化的时候,使控件始终居于右上角

当我从另一个窗体调用一个窗口时,它显示两个窗口一个在另一个的顶部

有空delphi子窗体关闭触发父窗体做出一系列改变的操作,主要就是子窗体关闭时能改变父窗体组件状态

有空delphi子窗体关闭触发父窗体做出一系列改变的操作,主要就是子窗体关闭时能改变父窗体组件状态

c# 如何保持一个MDI子窗口永远最大化?