|:一个32位的Windows XP(SP2)的Windows.Forms.ComboBox项目的工具提示
{S0}简介
这是一个快速的文章显示了如何创建一个混合Windows.Forms.ComboBox要解决的问题,其中一个项目的文本宽度超过下拉区的宽度。背景
一个前两天,我的一个客户问我如何完成这项任务。最初,我惊讶地发现,控制本身没有公开此功能,然后在无法找到一个简单的在线例子更惊讶。使用代码
只需添加到您的项目代码,并使用任何下拉Windows.Forms.ComboBox ComboBoxToolTip控制。
为了让事情简短的示例代码不支持。DropDownStyle = ComboBoxStyle.Simple或所有者绘制的组合项目。应该延长,以支持它的代码一个简单的锻炼,但如果有人需要就这一点帮助,请喊。
您将需要进口System.Drawing和System.Windows.Forms命名空间。Private Class ToolTipWindow
Inherits Control
Private Declare Function SetParent Lib "user32" _
(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As Integer
Private Declare Function ShowWindow Lib "user32" _
(ByVal hWnd As IntPtr, ByVal nCmdShow As Integer) As Integer
Private Declare Function SendMessage Lib "user32" _
(ByVal hWnd As IntPtr, ByVal Msg As Integer, _
ByVal wParam As IntPtr, ByRef lParam As IntPtr) As IntPtr
Public Sub New()
MyBase.New()
Me.BackColor = SystemColors.Info
End Sub
Public Overloads Sub Show()
If (Me.Handle.Equals(IntPtr.Zero)) Then Me.CreateControl()
Dim h As IntPtr = Me.Handle
If Not Me.Visible Then SetParent(h, IntPtr.Zero)
ShowWindow(h, 1)
Me.Invalidate()
End Sub
Protected Overrides ReadOnly Property CreateParams() As _
System.Windows.Forms.CreateParams
Get
Const WS_EX_TOOLWINDOW As Integer = &H80
Const WS_EX_NOACTIVATE As Integer = &H8000000
Const WS_EX_TOPMOST As Integer = &H8
Dim p As CreateParams = MyBase.CreateParams
p.ExStyle = p.ExStyle Or (WS_EX_NOACTIVATE Or _
WS_EX_TOOLWINDOW Or WS_EX_TOPMOST)
p.Parent = IntPtr.Zero
Return p
End Get
End Property
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
MyBase.OnPaint(e)
If String.IsNullOrEmpty(Me.Text) Then Return
Using brush As Brush = New SolidBrush(Me.ForeColor)
e.Graphics.DrawString(Me.Text, Me.Font, brush, Me.ClientRectangle)
End Using
e.Graphics.DrawRectangle(SystemPens.ControlDarkDark, 0, 0, _
Me.ClientRectangle.Width - 1, Me.ClientRectangle.Height - 1)
End Sub
End Class
我们在这个项目中有两个班。我们将看看第一个是我用来取代Windows.Forms.ToolTip框架为我们提供了一个。
这一切漂亮的selfexplanatory东西,所以我就迅速覆盖的基础。类继承Windows.Forms.Control。我这样做,因为它是一个简单的操作来描述一个适当的窗口类(的CreateParams)和油漆,而不调用本地代码(OnPaint中)。当然,高级用户可以调整的风格,更使油漆清洁等,但在这里,我的目标是保持代码的简单遵循尽可能。
这里的利益点.....
父窗口设置为IntPtr.Zero。这意味着我们的工具提示窗口可以"浮动",因为在桌面上拥有。请注意,我们所要做的显示方法(SetParent)如果窗口已经隐藏,否则Z -顺序低于活性形式。我们的工具提示是所有者绘制的,这意味着我们能够制作任何工具提示我们要的风格。
第二类是我们的ComboBox控件。{C}
这个类的混合型的本质是保持跟踪,当鼠标指针向下下拉ListBox控件的Y轴移动。因为它是确定的,鼠标在该项目的索引,然后项目文本的宽度计算。如果文本的宽度超过降下来列表框,刷新和显示工具提示。当工具提示不再需要,它是简单的隐藏,而不是销毁,并重复使用下一次。
也许,最棘手的位是方法,计算出该项目的鼠标下的指数。我用GetScrollPos的本地方法来考虑滚动偏移,但是这是32位机上唯一真正支持。 64位安全的方法,但不必要的复杂/扩展的示例代码,因此我的选择。那么,我做一个有点手册数学计算最终的指数。
我想唯一的其他有趣的一点是我选择的消息... ... WM_CTLCOLORLISTBOX。这是一个简单的选择,因为它是适合大多数始终与我们的模型,而消息的lParam值实际上是下拉列表框的窗口句柄的消息。可能的改进
毫无疑问,许多,但这里有几个春天在我脑海中... ...我主要是基于TreeView控件的工具提示行为。缺少的一件事是一个计时器,自动隐藏工具提示。我没有把这个,因为我喜欢它,不要隐瞒,但它会为这个漂亮的是开发商的选项。这可能是一个好主意,允许开发人员选择销毁工具提示,而不是简单地隐藏它。支持从右到左的地区。兴趣点
Windows.Forms.ComboBox控制仅仅是一个为母语的CComboBox类的包装。 CComboBox使用一个CListBox的下拉区域。我最初的方法是使用管理NativeWindow类继承这个窗口。虽然这工作得很好,我认为这将是尝试让事情尽可能多了几分乐趣。NET托管代码。历史2007年5月在CodeProject发布。混合动力版与所有者绘制的超级工具提示,2007年6月发布的文章。