【问题标题】:why borderless form is flickering when resizing form top or left in vb.net?为什么在 vb.net 中调整窗体顶部或左侧的大小时,无边框窗体会闪烁?
【发布时间】:2020-09-11 17:49:38
【问题描述】:

我看到了这段代码来调整和移动我的无边框表单,我把它复制到我的项目中。

这很好我现在正在寻找类似的东西,我所能看到的都是为 c# 制作的教程。我可以知道使用它是否有缺点?当我从顶部或左侧调整它的大小时,表单会闪烁的另一件事,但如果我从右侧或底部调整它的大小,它很好,就像普通表单一样。我不知道可能是什么问题,因为老实说,我不明白下面写的是什么。它似乎使用了一些十六进制值。

我尝试设置表单double buffered = true 不起作用。

Public Class Form2
    Private Const WM_NCHITTEST As Integer = &H84
    Private Const WM_MOUSEMOVE As Integer = &H200
    Private Const WM_LBUTTONDOWN As Integer = &H201
    Private Const WM_LBUTTONUP As Integer = &H202
    Private Const MK_LBUTTON As Integer = &H1
    Private Const HTLEFT As Integer = &HA
    Private Const HTRIGHT As Integer = &HB
    Private Const HTTOP As Integer = &HC
    Private Const HTTOPLEFT As Integer = &HD
    Private Const HTTOPRIGHT As Integer = &HE
    Private Const HTBOTTOM As Integer = &HF
    Private Const HTBOTTOMLEFT As Integer = &H10
    Private Const HTBOTTOMRIGHT As Integer = &H11
    Private OffSet As Point = Point.Empty

    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.FormBorderStyle = FormBorderStyle.None
    End Sub



    Protected Overrides Sub WndProc(ByRef m As Message)
        If m.Msg = WM_NCHITTEST Then
            Dim loc As New Point(m.LParam.ToInt32 And &HFFFF, m.LParam.ToInt32 >> 16)
            loc = PointToClient(loc)
            Dim bTop As Boolean = (loc.Y < ClientRectangle.Y + 4)
            Dim bLeft As Boolean = (loc.X < ClientRectangle.X + 4)
            Dim bRight As Boolean = (loc.X > Width - 4)
            Dim bBottom As Boolean = (loc.Y > Height - 4)
            If bTop And bLeft Then
                m.Result = CType(HTTOPLEFT, IntPtr)
                Return
            ElseIf bTop And bRight Then
                m.Result = CType(HTTOPRIGHT, IntPtr)
                Return
            ElseIf bBottom And bLeft Then
                m.Result = CType(HTBOTTOMLEFT, IntPtr)
                Return
            ElseIf bBottom And bRight Then
                m.Result = CType(HTBOTTOMRIGHT, IntPtr)
                Return
            ElseIf bLeft Then
                m.Result = CType(HTLEFT, IntPtr)
                Return
            ElseIf bTop Then
                m.Result = CType(HTTOP, IntPtr)
                Return
            ElseIf bRight Then
                m.Result = CType(HTRIGHT, IntPtr)
                Return
            ElseIf bBottom Then
                m.Result = CType(HTBOTTOM, IntPtr)
                Return
            End If
        ElseIf m.Msg = WM_LBUTTONDOWN Then
            OffSet = New Point(MousePosition.X - Me.Location.X, MousePosition.Y - Me.Location.Y)
        ElseIf m.Msg = WM_MOUSEMOVE AndAlso m.WParam.ToInt32 = MK_LBUTTON Then
            Me.Location = New Point(MousePosition.X - OffSet.X, MousePosition.Y - OffSet.Y)
        End If
        MyBase.WndProc(m)
    End Sub

End Class

【问题讨论】:

  • 您还需要让它在拖动顶部/左侧时闪烁。在构造函数中设置 ResizeRedraw = True。
  • 我想知道为什么从顶部或左侧调整大小时它会闪烁而不重现闪烁。拖动是完美的。即使是无边框形式,我也可以毫无问题地拖动它。
  • 顺便说一句,您可以删除WM_LBUTTONDOWNWM_MOUSEMOVE:不需要。改为添加If loc.Y &lt; SystemInformation.CaptionHeight + 2 Then m.Result = new IntPtr(2)。这个:Dim loc As New Point(m.LParam.ToInt32 And &amp;HFFFF, m.LParam.ToInt32 &gt;&gt; 16) loc = PointToClient(loc) 可以简化为dim loc = PointToClient(new Point(m.LParam.ToInt32()))
  • 感谢@jimi 的链接,尤其是第二个,为什么我搜索这个问题时它没有出现在谷歌搜索中?总之非常感谢。就像 Saeed Sayyadipour 所做的那样,我认为闪烁是特定于机器的。除了我现在使用的一台 win 10 和 64 位笔记本电脑外,我没有另一台机器,但 Saeed Sayyadipour 重现了该问题并且不存在闪烁。

标签: .net vb.net winforms visual-studio-2017 borderless


【解决方案1】:

通常,WndProc 是一个应用程序定义的函数,用于处理发送到窗口的消息。在您的示例中, Form2 被认为是一个无框窗口。在原始无框窗口中,您不能移动或调整窗口大小,除非您覆盖其受 WndProc 保护的函数。在您的示例中,将 m.Msg(指示消息的 ID 号)与不同的操作系统消息(WM_NCHITTEST、WM_LBUTTONDOWN 等)进行比较,以确定应执行的操作(调整大小、移动、.. .)。您可以找到系统消息 ID here 的完整列表。 关于闪烁的问题。老实说,这个问题不会发生在我的系统上。这可能取决于您的操作系统和 Windows 版本。

【讨论】:

  • 非常感谢@Saeed Sayyadipour 的解释。我想知道你是否重现了这个问题?你在你的机器上试过上面的代码了吗?
  • 是的,我将您的代码复制到一个新表单中并对其进行了全面测试。一切正常,闪烁的问题不会发生在我身上。你能在另一个系统上测试它吗?例如具有不同 Windows 版本的不同机器。我在装有 64 位版本的 Windows 10 的笔记本电脑上对其进行了测试。通常,某些问题可能会在应用程序的发布版本中得到解决。再试一次,您可以检查它是否发生在您的应用程序的发布版本中。
  • 谢谢,我猜这是特定于机器的问题。我最好坚持使用可调整大小的窗口以避免这种闪烁问题,并尝试为表单设置皮肤以便更好地自定义。
  • 好。最后,如果您发现此答案有用,请接受并投票亲爱的@lelouch。谢谢! :)
猜你喜欢
  • 2022-10-13
  • 2014-01-24
  • 1970-01-01
  • 2019-01-09
  • 2019-02-27
  • 1970-01-01
  • 2018-07-27
  • 2010-11-22
  • 1970-01-01
相关资源
最近更新 更多