Windows.Forms.Panel 32767大小限制
本文关键字:32767 Forms Panel Windows | 更新日期: 2023-09-27 18:14:09
我有一个应用程序,它使用Windows.Forms.Panel
来显示图片列表。当面板的高度超过32767像素时,其余的内容被简单地切断。
的例子:
Windows.Forms.Panel myPanel;
ArrayList pictureList;
foreach(pic in pictureList) {
myPanel.Controls.Add(pic) // adds all the objects without complaints
}
在这个例子中,所有的元素都被添加到面板中,没有抛出错误,但是当面板的大小达到32767之后,就不再显示图像了。
我的问题是:是否有可能打破这个限制,在面板中显示更多的内容?
我知道这种方法在任何方面都不方便,但是现在没有时间重新设计整个应用程序。
这是Windows的架构限制。指示窗口位置的各种消息,如WM_MOUSEMOVE,以32位整数形式报告位置,其中16位为X位置,16位为y位置。因此,不能创建大于short.MaxValue的窗口。这并不是一个真正的问题,没有人有超过32,767像素的显示器,而且在很长一段时间内都不会。
你必须用不同的方法来做这件事。就像在Paint方法中使用Graphics.TranslateTransform()一样
LPARAM - Windows的一种数据类型,用于向Windows过程传递消息参数。它是一个32位的指针,传递消息分为两部分,即高阶(32位的前16位)和低阶(32位的后16位)。
Where
High order is used to pass the height of the control and
Low order is used to pass the width of the control
如果控件的高度或宽度超过32762size,就会显示错误,因为
32767是16位有符号整数所能表示的最大值。
不使用paint方法的解决方案
我就有这个问题。我不想重新编写已经编码到子控件中的功能。此例程通过滚动条管理子控件,并将未播放的控件隐藏并仅在屏幕外。
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
然后,对于每个子控件(我的是动态添加的,听起来像OP正在做同样的事情)进行此调用:
CType(Parent, ManuallyScrollingPanel).RegisterChildSize(Me, PanelObject.Bounds)
注意,当我从dto构建控件以允许相同的应用程序+视图作为web应用程序和windows应用程序呈现时,我分别传递了子控件的边界。将其限制为面板也是如此。
为什么不给面板添加一个滚动条呢
just set AutoScrollbar = true
并将rightolleft属性设置为true