我正在更新一个需要在文本框和只读组合框中添加提示横幅的VB.net项目(DropDownStyle = DropDownList)。我正在开发的机器是Windows 7.我在一个扩展组合框的类中添加了提示文本并添加了一个提示文本属性。这是提示文本添加到组合框的方式:
'"Me" refers to a combobox that has been extended to include a Cue Text property
SendMessage(New HandleRef(Me, Me.Handle), CB_SETCUEBANNER, IntPtr.Zero, _cueText)
上面的代码来自这个博客:http://www.aaronlerch.com/blog/page/7/,它位于C#中;我把它翻译成VB。我尝试了其他类似的变种,我在其他地方找到了,都有相同的结果:当我在Windows 7中运行程序时,它适用于文本框和组合框;它仅适用于Windows XP中的文本框。
我在不同论坛上阅读了很多关于确保选择视觉样式并禁用东亚语言和复杂脚本的评论。我已经完成了所有这些,但仍然没有在XP上工作。
有没有人获得组合框的cue横幅才能在XP上工作?
答案 0 :(得分:2)
使用各种博客和论坛帖子,我创建了一个扩展ComboBox控件的类,并实现了一个适用于Windows 7和XP的CueText属性。我在这里找到了最相关的信息:
简而言之,Windows 7和XP设置cue横幅文本的方式略有不同,因此您需要检查程序运行的操作系统,然后适当地处理提示文本。对于Windows 7,您需要使用EM_SETCUEBANNER As Integer = &H1501
,对于Windows 7,您需要使用CB_SETCUEBANNER As UInteger = &H1703
。如果应用程序在XP上运行,您还需要单击组合框的文本部分。您可以在下面的代码中查看详细信息。要确定正在运行的操作系统,请参阅MS知识库文章304289(VB)或304283(C#)。 (我会发布链接,但我没有足够的声望点来发布超过两个。)
有一点需要注意,如果组合框是只读的(DropDownStyle = DropDownList),这将无法在XP上运行。 Windows 7似乎无论如何都可以正常工作。如果您的应用程序需要在XP上运行,并且您需要只读取组合框但仍显示提示文本,那么您可以执行以下操作:
e.Handled = True.
这将阻止输入文本。这是继承ComboBox控件的类的VB代码,并添加了适用于XP和7的CueText属性。您唯一需要做的就是找出正在运行的操作系统:
Imports System.ComponentModel
Imports System.Runtime.InteropServices
Public Class CueComboBox
Inherits ComboBox
' Occurs when the CueText property value changes.
Public Event CueTextChanged As EventHandler
'Windows XP
Private Shared EM_SETCUEBANNER As Integer = &H1501
'Windows 7
Private Shared CB_SETCUEBANNER As UInteger = &H1703
<DllImport("user32.dll", CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As Integer, <MarshalAs(UnmanagedType.LPWStr)> ByVal lParam As String) As Int32
End Function
<DllImport("user32.dll")> _
Private Shared Function GetComboBoxInfo(ByVal hwnd As IntPtr, ByRef pcbi As COMBOBOXINFO) As Boolean
End Function
<StructLayout(LayoutKind.Sequential)> _
Private Structure COMBOBOXINFO
Public cbSize As Integer
Public rcItem As RECT
Public rcButton As RECT
Public stateButton As IntPtr
Public hwndCombo As IntPtr
Public hwndItem As IntPtr
Public hwndList As IntPtr
End Structure
<StructLayout(LayoutKind.Sequential)> _
Private Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
End Structure
Private Shared Function GetComboBoxInfo(ByVal control As Control) As COMBOBOXINFO
Dim info As New COMBOBOXINFO()
'a combobox is made up of three controls, a button, a list and textbox;
'we want the textbox
info.cbSize = Marshal.SizeOf(info)
GetComboBoxInfo(control.Handle, info)
Return info
End Function
Private _cueText As String = [String].Empty
' Gets or sets the text that will display as a cue to the user.
<Description("The text value to be displayed as a cue to the user.")> _
<Category("Appearance")> <DefaultValue("")> <Localizable(True)> _
Public Property CueText() As String
Get
Return _cueText
End Get
Set(ByVal value As String)
If value Is Nothing Then
value = [String].Empty
End If
If Not _cueText.Equals(value, StringComparison.CurrentCulture) Then
_cueText = value
UpdateCue()
OnCueTextChanged(EventArgs.Empty)
End If
End Set
End Property
<EditorBrowsable(EditorBrowsableState.Advanced)> _
Protected Overridable Sub OnCueTextChanged(ByVal e As EventArgs)
RaiseEvent CueTextChanged(Me, e)
End Sub
Protected Overrides Sub OnHandleCreated(ByVal e As EventArgs)
UpdateCue()
MyBase.OnHandleCreated(e)
End Sub
Private Sub UpdateCue()
' If the handle isn't yet created, this will be called when it is created
If Me.IsHandleCreated Then
' Windows XP sets the cue banner differently than Windows 7
If Form1.OPERATING_SYSTEM = "Windows XP" Then
Dim info As COMBOBOXINFO = GetComboBoxInfo(Me)
SendMessage(info.hwndItem, EM_SETCUEBANNER, 0, _cueText)
Else
SendMessage(New HandleRef(Me, Me.Handle), CB_SETCUEBANNER, IntPtr.Zero, _cueText)
End If
End If
End Sub
End Class