Windows.Forms.Panel 32767 size limit

前端 未结 4 1714
陌清茗
陌清茗 2020-11-30 14:01

I have an application that uses Windows.Forms.Panel to display a list of pictures. When the height of the panel exceeds 32767 pixels the rest of the content is

相关标签:
4条回答
  • 2020-11-30 14:30

    This is an architectural limitation in Windows. Various messages that indicate positions in a window, like WM_MOUSEMOVE, report the position in a 32-bit integer with 16-bits for the X and 16-bits for the Y-position. You therefore cannot create a window that's larger than short.MaxValue. This isn't exactly a real problem, nobody has a monitor that's wider than 32,767 pixels and won't for a long time to come.

    You'll have to do this differently. Like using Graphics.TranslateTransform() in a Paint method.

    0 讨论(0)
  • 2020-11-30 14:32

    Solution without a paint method

    I had this exact problem. I didn't want to have to re-write functionality that was already coded into my child controls. This routine manages the child controls via a scrollbar, and keeps the out-of-play ones hidden and just offscreen.

    Public Class ManuallyScrollingPanel
      Inherits Panel
    
      Public WithEvents sbar As New System.Windows.Forms.VScrollBar
    
      Sub New()
        MyBase.New()
        Controls.Add(sbar)
        sbar.Visible = True
        Me.AutoScroll = False
      End Sub
    
      Sub SetScrollParams()
        If PanelPositions.Any Then
          Dim NewMax = CInt((From item In PanelPositions.Values Select item.Bottom).Max + 500) - Height
          If sbar.Maximum <> NewMax Then
            sbar.Maximum = NewMax
          End If
        End If
      End Sub
    
      Public Sub RegisterChildSize(pnl As Panel, DesiredBounds As Drawing.Rectangle)
        PanelPositions(pnl) = DesiredBounds
        SetScrollParams()
      End Sub
    
      Dim PanelPositions As New Dictionary(Of Panel, Drawing.Rectangle)
    
      Private Sub ManuallyScrollingPanel_SizeChanged(sender As Object, e As EventArgs) Handles Me.SizeChanged
        sbar.Top = 0
        sbar.Left = Width - sbar.Width
        sbar.Height = Me.Height
        SetScrollParams()
        sbar.LargeChange = CInt(Height * 0.9)
        sbar.SmallChange = CInt(Height * 0.2)
      End Sub
    
      Private Sub sb_Scroll(sender As Object, e As ScrollEventArgs) Handles sbar.Scroll
        ScrollTo(e.NewValue)
      End Sub
    
      Private Sub sb_ValueChanged(sender As Object, e As EventArgs) Handles sbar.ValueChanged
        ScrollTo(sbar.Value)
      End Sub
    
      Sub ScrollTo(pos As Integer)
        Me.AutoScroll = False
        For Each kvp In PanelPositions
          Dim VirtBounds = New Drawing.Rectangle(CInt(kvp.Value.Left), CInt(kvp.Value.Top - pos), CInt(kvp.Value.Width), CInt(kvp.Value.Height))
          If VirtBounds.Bottom < 0 Or VirtBounds.Top > Height Then
            ' it's not visible - hide it and position offscreen
            kvp.Key.Visible = False
            kvp.Key.Top = VirtBounds.Top
          Else
            ' Visible, position it
            kvp.Key.Top = VirtBounds.Top
            kvp.Key.Visible = True
          End If
        Next
      End Sub
    
    End Class
    

    Then, for each child control (mine were dynamically added, sounds like the OP was doing the same thing) make this call:

    CType(Parent, ManuallyScrollingPanel).RegisterChildSize(Me, PanelObject.Bounds)
    

    Note I pass in the child's bounds separately as I build the controls from DTOs to allow the same app+views to render as a web app and a windows app. Same with limiting it to panels. Refactor out as needed.

    0 讨论(0)
  • 2020-11-30 14:35

    LPARAM - A Data type of Windows used to pass message parameters to Windows Procedure. It is a 32 bit pointer which passes message as two parts i.e in High order(First 16 bits of 32 bits) and Low order(Second 16 bits of 32 bits).

      Where 
           High order is used to pass the height of the control and
           Low order is used to pass the width of the control
    

    So if the height or width of the control exceeds 32762size, it shows error because

    32767 is the highest number that can be represented in a signed 16bit integer.

    0 讨论(0)
  • 2020-11-30 14:47

    Why don't you add a scrollbar to your panel

    just set AutoScrollbar = true

    and just set the RightToLeft property to true.

    0 讨论(0)
提交回复
热议问题