Windows 10 中的 Win32 工具提示灰线错误
Win32 tooltip gray line bug in Windows 10
自 Windows XP 时代以来,多年来,我们一直在使用在遗留 VB6 组件中创建经典 Win32 多行工具提示的代码。它在除 Windows 10 以外的所有最新版本的 MS Windows (7, 8.1) 中工作正常。在此 OS 的工具提示中出现一条寄生水平灰线。此问题的最佳演示是包含多行文本的工具提示 window(主要提示文本是多行 and/or 工具提示的标题为粗体):
正确的工具提示应如下所示(来自 Windows 8.1 的屏幕):
下面是工具提示 window 没有 tile/icon 但仅包含多行文本时出现的同一问题的另一个示例:
这条寄生灰线也出现在 single-line 工具提示中 - 虽然乍一看并不明显:
它可能是什么?是 Windows 10 中的错误,还是工具提示中的某些内容已更改 API?
下面是用于初始化工具提示的方法的代码:
Public Function Create(ByVal ParentHwnd As Long) As Boolean
Dim lWinStyle As Long
If m_lTTHwnd <> 0 Then
DestroyWindow m_lTTHwnd
End If
m_lParentHwnd = ParentHwnd
lWinStyle = TTS_ALWAYSTIP Or TTS_NOPREFIX
m_lTTHwnd = CreateWindowExA(0&, _
TOOLTIPS_CLASS, _
vbNullString, _
lWinStyle, _
CW_USEDEFAULT, _
CW_USEDEFAULT, _
CW_USEDEFAULT, _
CW_USEDEFAULT, _
0&, _
0&, _
App.hInstance, _
0&)
'now set our tooltip info structure
Dim tiA As TOOLINFOA
Dim tiW As TOOLINFOW
If g_bIsNt Then
With tiW
.lSize = Len(tiW)
.lFlags = TTF_SUBCLASS Or TTF_IDISHWND
.hWnd = m_lParentHwnd
.lId = m_lParentHwnd '0
.hInstance = App.hInstance
.lpStr = StrPtr(mvarTipText)
End With
Else
With tiA
.lSize = Len(tiA)
.lFlags = TTF_SUBCLASS Or TTF_IDISHWND
.hWnd = m_lParentHwnd
.lId = m_lParentHwnd
.hInstance = App.hInstance
.lpStr = mvarTipText
End With
End If
'add the tooltip structure
If g_bIsNt Then
SendMessage m_lTTHwnd, TTM_ADDTOOLW, 0&, tiW
Else
SendMessage m_lTTHwnd, TTM_ADDTOOLA, 0&, tiA
End If
'if we want a title or we want an icon
If mvarTitle <> vbNullString Or mvarIcon <> igToolTipIconNone Then
If g_bIsNt Then
SendMessage m_lTTHwnd, TTM_SETTITLEW, mvarIcon, ByVal StrPtr(mvarTitle)
Else
SendMessage m_lTTHwnd, TTM_SETTITLEA, mvarIcon, ByVal mvarTitle
End If
End If
' set the time parameters
SendMessageByLongA m_lTTHwnd, TTM_SETDELAYTIME, TTDT_AUTOPOP, mvarVisibleTime
SendMessageByLongA m_lTTHwnd, TTM_SETDELAYTIME, TTDT_INITIAL, mvarDelayTime
'according to MSDN, we should set TTM_SETMAXTIPWIDTH to a positive value
'to enable multiline tooltips
SendMessageByLongA m_lTTHwnd, TTM_SETMAXTIPWIDTH, 0, 100000
End Function
为了解决这个问题,我们应该不设置TOOLINFO结构的hwnd字段。代码的相应部分应如下所示:
'now set our tooltip info structure
Dim tiA As TOOLINFOA
Dim tiW As TOOLINFOW
If g_bIsNt Then
With tiW
.lSize = Len(tiW)
.lFlags = TTF_SUBCLASS Or TTF_IDISHWND
.lId = m_lParentHwnd
.hInstance = App.hInstance
.lpStr = StrPtr(mvarTipText)
End With
Else
With tiA
.lSize = Len(tiA)
.lFlags = TTF_SUBCLASS Or TTF_IDISHWND
.lId = m_lParentHwnd
.hInstance = App.hInstance
.lpStr = mvarTipText
End With
End If
自 Windows XP 时代以来,多年来,我们一直在使用在遗留 VB6 组件中创建经典 Win32 多行工具提示的代码。它在除 Windows 10 以外的所有最新版本的 MS Windows (7, 8.1) 中工作正常。在此 OS 的工具提示中出现一条寄生水平灰线。此问题的最佳演示是包含多行文本的工具提示 window(主要提示文本是多行 and/or 工具提示的标题为粗体):
正确的工具提示应如下所示(来自 Windows 8.1 的屏幕):
下面是工具提示 window 没有 tile/icon 但仅包含多行文本时出现的同一问题的另一个示例:
这条寄生灰线也出现在 single-line 工具提示中 - 虽然乍一看并不明显:
它可能是什么?是 Windows 10 中的错误,还是工具提示中的某些内容已更改 API?
下面是用于初始化工具提示的方法的代码:
Public Function Create(ByVal ParentHwnd As Long) As Boolean
Dim lWinStyle As Long
If m_lTTHwnd <> 0 Then
DestroyWindow m_lTTHwnd
End If
m_lParentHwnd = ParentHwnd
lWinStyle = TTS_ALWAYSTIP Or TTS_NOPREFIX
m_lTTHwnd = CreateWindowExA(0&, _
TOOLTIPS_CLASS, _
vbNullString, _
lWinStyle, _
CW_USEDEFAULT, _
CW_USEDEFAULT, _
CW_USEDEFAULT, _
CW_USEDEFAULT, _
0&, _
0&, _
App.hInstance, _
0&)
'now set our tooltip info structure
Dim tiA As TOOLINFOA
Dim tiW As TOOLINFOW
If g_bIsNt Then
With tiW
.lSize = Len(tiW)
.lFlags = TTF_SUBCLASS Or TTF_IDISHWND
.hWnd = m_lParentHwnd
.lId = m_lParentHwnd '0
.hInstance = App.hInstance
.lpStr = StrPtr(mvarTipText)
End With
Else
With tiA
.lSize = Len(tiA)
.lFlags = TTF_SUBCLASS Or TTF_IDISHWND
.hWnd = m_lParentHwnd
.lId = m_lParentHwnd
.hInstance = App.hInstance
.lpStr = mvarTipText
End With
End If
'add the tooltip structure
If g_bIsNt Then
SendMessage m_lTTHwnd, TTM_ADDTOOLW, 0&, tiW
Else
SendMessage m_lTTHwnd, TTM_ADDTOOLA, 0&, tiA
End If
'if we want a title or we want an icon
If mvarTitle <> vbNullString Or mvarIcon <> igToolTipIconNone Then
If g_bIsNt Then
SendMessage m_lTTHwnd, TTM_SETTITLEW, mvarIcon, ByVal StrPtr(mvarTitle)
Else
SendMessage m_lTTHwnd, TTM_SETTITLEA, mvarIcon, ByVal mvarTitle
End If
End If
' set the time parameters
SendMessageByLongA m_lTTHwnd, TTM_SETDELAYTIME, TTDT_AUTOPOP, mvarVisibleTime
SendMessageByLongA m_lTTHwnd, TTM_SETDELAYTIME, TTDT_INITIAL, mvarDelayTime
'according to MSDN, we should set TTM_SETMAXTIPWIDTH to a positive value
'to enable multiline tooltips
SendMessageByLongA m_lTTHwnd, TTM_SETMAXTIPWIDTH, 0, 100000
End Function
为了解决这个问题,我们应该不设置TOOLINFO结构的hwnd字段。代码的相应部分应如下所示:
'now set our tooltip info structure
Dim tiA As TOOLINFOA
Dim tiW As TOOLINFOW
If g_bIsNt Then
With tiW
.lSize = Len(tiW)
.lFlags = TTF_SUBCLASS Or TTF_IDISHWND
.lId = m_lParentHwnd
.hInstance = App.hInstance
.lpStr = StrPtr(mvarTipText)
End With
Else
With tiA
.lSize = Len(tiA)
.lFlags = TTF_SUBCLASS Or TTF_IDISHWND
.lId = m_lParentHwnd
.hInstance = App.hInstance
.lpStr = mvarTipText
End With
End If