在MDI父无边框表格边缘上移动时,停止MDI子窗体闪烁

时间:2016-05-18 14:08:11

标签: vb.net

我正在开发一个包含 MDI子表单的项目。当用户尝试拖出 无边框格式的边缘时,我已经让我的MDI子窗体停止移动。但是,如果用户坚持认为,MDI儿童形成闪烁就像疯了一样!!!

注意我已将表单设置为DoubleBuffered = True,并且我还在活动结束时添加了me.Refresh()me.parentform.Refresh()

知道我还能做什么?

以下是我的代码的已修改示例...

首先我们有自定义标题栏控件,这是代码所需的部分:

Imports System.Windows.Forms
Imports System.ComponentModel

Public Class cmosTitleBar

Region "Custom events."
    Public Event FormTitleBar_DoubleClick_Plus(sender As Object, e As EventArgs)
    Public Event FormTitleBar_MouseDown_Plus(sender As Object, e As EventArgs)
    Public Event FormTitleBar_MouseMove_Plus(sender As Object, e As EventArgs)
    Public Event FormTitleBar_MouseEnter_Plus(sender As Object, e As EventArgs)
    Public Event FormTitleBar_MouseLeave_Plus(sender As Object, e As EventArgs)
End Region

Region "Form Code."

    Dim NewPoint As New System.Drawing.Point
    Dim X, Y As Integer

Region "FormTitleBar Events."
    Private Sub FormTitleBar_DoubleClick(sender As Object, e As EventArgs) Handles FormTitleBar.DoubleClick
        RaiseEvent FormTitleBar_DoubleClick_Plus(sender, e)
        Call PreventFlickering()
    End Sub
    Private Sub FormTitleBar_MouseDown(sender As Object, e As MouseEventArgs) Handles FormTitleBar.MouseDown, FormIcon.MouseDown, MyBase.MouseDown
        If Not ParentForm.WindowState = FormWindowState.Maximized Then
            X = Control.MousePosition.X - ParentForm.Location.X
            Y = Control.MousePosition.Y - ParentForm.Location.Y
        End If
        RaiseEvent FormTitleBar_MouseDown_Plus(sender, e)
    End Sub
    Private Sub FormTitleBar_MouseMove(sender As Object, e As MouseEventArgs) Handles FormTitleBar.MouseMove, FormIcon.MouseMove, MyBase.MouseMove
        If Not ParentForm.WindowState = FormWindowState.Maximized Then
            If e.Button = Windows.Forms.MouseButtons.Left Then
                NewPoint = Control.MousePosition
                NewPoint.X -= (X)
                NewPoint.Y -= (Y)
                ParentForm.Location = NewPoint
            End If
        End If
        Call PreventChildMoveOut()
        RaiseEvent FormTitleBar_MouseMove_Plus(sender, e)
        RaiseEvent FormIcon_MouseMove_Plus(sender, e)
        Call PreventFlickering()
    End Sub
    Private Sub FormTitleBar_MouseEnter(sender As Object, e As EventArgs) Handles FormTitleBar.MouseEnter, FormIcon.MouseEnter
        If ParentForm.WindowState = FormWindowState.Normal Then
            FormTitleBar.Cursor = Cursors.NoMove2D
            FormIcon.Cursor = Cursors.NoMove2D
        Else
            FormTitleBar.Cursor = Cursors.Default
            FormIcon.Cursor = Cursors.Default
        End If
        RaiseEvent FormTitleBar_MouseEnter_Plus(sender, e)
    End Sub
    Private Sub FormTitleBar_MouseLeave(sender As Object, e As EventArgs) Handles FormTitleBar.MouseLeave
        RaiseEvent FormTitleBar_MouseLeave_Plus(sender, e)
    End Sub
End Region

End Region

Region "Custom subs."
    Private Sub PreventFlickering()
        If Me.ParentForm.IsMdiChild = True Then
            Me.ParentForm.Refresh()
            Me.ParentForm.ParentForm.Refresh()
        Else
            Me.ParentForm.Refresh()
        End If
    End Sub
    Private Sub PreventChildMoveOut()
        If ParentForm.IsMdiChild = True Then
            If ParentForm.Left < ParentForm.MdiParent.ClientRectangle.Left Then
                ParentForm.Left = ParentForm.MdiParent.ClientRectangle.Left
                If ParentForm.Top < ParentForm.MdiParent.ClientRectangle.Top Then
                    ParentForm.Top = ParentForm.MdiParent.ClientRectangle.Top
                ElseIf ParentForm.Bottom > ParentForm.MdiParent.ClientRectangle.Height - 98 Then
                    ParentForm.Top = ParentForm.MdiParent.ClientRectangle.Bottom - ParentForm.Height - 98
                End If
            ElseIf ParentForm.Right > ParentForm.MdiParent.ClientRectangle.Width Then
                ParentForm.Left = ParentForm.MdiParent.ClientRectangle.Right - ParentForm.Width
                If ParentForm.Top < ParentForm.MdiParent.ClientRectangle.Top Then
                    ParentForm.Top = ParentForm.MdiParent.ClientRectangle.Top
                ElseIf ParentForm.Bottom > ParentForm.MdiParent.ClientRectangle.Height - 98 Then
                    ParentForm.Top = ParentForm.MdiParent.ClientRectangle.Bottom - ParentForm.Height - 98
                End If
            ElseIf ParentForm.Top < ParentForm.MdiParent.ClientRectangle.Top Then
                ParentForm.Top = ParentForm.MdiParent.ClientRectangle.Top
            ElseIf ParentForm.Bottom > ParentForm.MdiParent.ClientRectangle.Height - 98 Then
                ParentForm.Top = ParentForm.MdiParent.ClientRectangle.Bottom - ParentForm.Height - 98
            End If
        End If
    End Sub
End Region

End Class

以下是我的无边距MDI父表单所需的代码,其中包含自定义标题栏控件

Public Class MainForm

Region "Form Code."
        Private Sub SettingsToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SettingsToolStripMenuItem.Click
            SettingsForm.MdiParent = Me
            SettingsForm.Show()
        End Sub
    End Region

End Class

进入我的无边框MDI子表单,其中还包含我的自定义标题栏控件,此操作没有代码,因为所有内容(直到现在)都发生在自定义中标题栏控件的代码。

1 个答案:

答案 0 :(得分:1)

它正在闪烁,因为你试图将位置限制为&gt; = 0,并且位置移动到-1然后是0.然后当你试图强制超出边界的形式时,位置实际上是-1,0, - 1,0,等等。你不想让它首先达到-1。因此,在移动mdi子项时,请限制光标区域。

要测试,请使用两种形式制作项目。

  • MdiParentForm Public Class MdiParentForm Private child As Form Private Sub MdiParentForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load child = New MdiChildForm() child.MdiParent = Me child.Show() End Sub End Class
  • MdiChildForm

MdiParentForm代码:

Public Class MdiChildForm

    Private mouseIsDown As Boolean = False
    Private myParent As Form
    Private myRectangle As System.Drawing.Rectangle
    Private myCursorLocation As System.Drawing.Point
    Private myBorderWidth As Integer
    Private myTitlebarHeight As Integer

    Private Sub MdiChildForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        myParent = Me.MdiParent
    End Sub

    Private Sub MdiChildForm_MouseCaptureChanged(sender As Object, e As EventArgs) Handles Me.MouseCaptureChanged
        If mouseIsDown Then
            myRectangle = myParent.Bounds
            myCursorLocation = Me.PointToClient(Cursor.Position)
            myBorderWidth = (Me.Width - Me.ClientSize.Width) / 2
            myTitlebarHeight = Me.Height - Me.ClientSize.Height - 2 * myBorderWidth
        End If
    End Sub

    Private Sub MdiChildForm_Move(sender As Object, e As EventArgs) Handles Me.Move
        If mouseIsDown Then
            Cursor.Clip = New Rectangle(myRectangle.Left + myCursorLocation.X + myBorderWidth,
                                        myRectangle.Top + myCursorLocation.Y + myTitlebarHeight,
                                        myRectangle.Width - Me.Width - myBorderWidth,
                                        myRectangle.Height - Me.Height)
        Else
            Cursor.Clip = Nothing
        End If
    End Sub

    ' there is no event for title bar click, so use WndProc
    Protected Overrides Sub WndProc(ByRef m As Message)
        MyBase.WndProc(m)
        Select Case m.Msg
            Case &H21
                mouseIsDown = True
            Case &H22
                mouseIsDown = False
        End Select
    End Sub

End Class

MdiChildForm代码:

MdiChildForm_Move

由于您使用的是自定义控件,因此您可能需要调整MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); mRootLayout = new QVBoxLayout(this); setLayout(mRootLayout); mRootLayout->addWidget(new QPushButton("Button1", this)); mRootLayout->addWidget(new QPushButton("Button2", this)); } 内的Cursor.Clip矩形尺寸和坐标。