📄 extooltip.cls
字号:
'==================================================================================================
'ExTooltip Class Private Constants
'==================================================================================================
'=====================================================
'WINDOW STYLES
Private Const GWL_STYLE As Long = -16
Private Const GWL_EXSTYLE As Long = -20
'=====================================================
'=====================================================
'WINDOWS SUBCLASS MESSAGES
Private Const WM_DESTROY As Long = &H2
Private Const WM_TIMER As Long = &H113
Private Const WM_MOUSEMOVE As Long = &H200
Private Const WM_MOUSEACTIVATE As Long = &H21
'=====================================================
'=====================================================
'EXTENDED WINDOW STYLES
Private Const WS_EX_TOOLWINDOW As Long = &H80&
Private Const WS_EX_CLIENTEDGE As Long = &H200
'=====================================================
'=====================================================
'WINDOWS STYLES
Private Const WS_BORDER As Long = &H800000
Private Const SWP_NOMOVE As Long = &H2
Private Const SWP_NOSIZE As Long = &H1
Private Const SWP_FRAMECHANGED As Long = &H20
Private Const SWP_NOACTIVATE As Long = &H10
Private Const SWP_NOZORDER As Long = &H4
'=====================================================
'=====================================================
'TEXT FORMAT CONST
Private Const DT_CALCRECT As Long = &H400
'=====================================================
'=====================================================
'SHADOW CONSTS
Private Const CS_DROPSHADOW As Long = &H20000
Private Const GCL_STYLE As Long = (-26)
'=====================================================
'=====================================================
'AREA REGION CONSTS
Private Const RGN_DIFF As Long = 4
'=====================================================
'=====================================================
'DRAWICONEX CONSTS
Private Const DI_NORMAL As Long = &H3
'=====================================================
'=====================================================
'VARIABLES USED IN PROCESS
'=====================================================
Private iFnt As IFont '//-- Font Value
Private m_fnt As IFont '//-- Font Value
Private hFntOld As Long '//-- Font Value
Private CPOS As POINTAPI '//-- Coordinate Values of the Position of the Mouse
Private CMOS As POINTAPI '//-- Memory Coordinate Values of the Position of the Mouse
Private bTime As Long '//-- API Timer Variable Counter
Private LWnd As Long '//-- Control Handle Window
Private sc_aSubData() As tSubData '//-- Array of Subclass Values
Private M_ExWindow As EXWINDOW '//-- Ex Window Tooltip Values
Private mToolTipStyle As ttStyleEnum
Private mIconSize As ttIconSize
Private mTextColor As Long
Private mBackColor As Long
Private mGCEnd As Long
Private mGCStart As Long
Private mBackStyle As Long
Private mDelayTime As Long
Private mShadow As Boolean
Private mKillTime As Long
Private mAlive As Boolean
Private mCP(100, 255) As Byte '//-- Holds the percent calculation
Private mCC(255, 255) As Byte '//-- Holds the Add Colors math
'=====================================================
'VARIABLES USED TO DRAW TEMP DC
'=====================================================
Private m_Hdc As Long
Private m_ThDC As Long
Private m_hBmp As Long '//-- Temporary DC (Where All The Drawings are made)
Private m_hBmpOld As Long '//-- It Also Provides an Anti-Flicker Draw
Private m_lWidth As Long
Private m_lHeight As Long
'=====================================================
'=====================================================
'VARIABLES USED TO DRAW REGION
Private rgnNorm As Long
Private rgn2 As Long
Private rgn1 As Long
'=====================================================
'======================================================================================================
'Subclass handler - MUST be the first Public routine in this file. That includes public properties also
Public Sub zSubclass_Proc(ByVal bBefore As Boolean, ByRef bHandled As Boolean, ByRef lReturn As Long, ByRef lng_hWnd As Long, ByRef uMsg As Long, ByRef wParam As Long, ByRef lParam As Long)
'Parameters:
'bBefore - Indicates whether the the message is being processed before or after the default handler - only really needed if a message is set to callback both before & after.
'bHandled - Set this variable to True in a 'before' callback to prevent the message being subsequently processed by the default handler... and if set, an 'after' callback
'lReturn - Set this variable as per your intentions and requirements, see the MSDN documentation for each individual message value.
'hWnd - The window handle
'uMsg - The message number
'wParam - Message related data
'lParam - Message related data
Select Case uMsg
'==============================================================================================
'==============================================================================================
'The WM_MOUSEMOVE message is posted to a window when the cursor moves.
'If the mouse is not captured, the message is posted to the window that contains the cursor.
'Otherwise, the message is posted to the window that has captured the mouse.
'==============================================================================================
'==============================================================================================
Case WM_MOUSEMOVE
'//-- If the User is Over the Calling Control Turn 'ON' The Hover Flag.
If InsideArea(LWnd) Then
If M_ExWindow.Hover = False Then
M_ExWindow.Hover = True '/-- If The Mouse Enter The Control Area
SetTimer LWnd, 1, 1, 0 '/-- Start API Timer
End If
Else
M_ExWindow.Hover = False '/-- If The Mouse Left The Control Area
End If
'==============================================================================================
'==============================================================================================
'The WM_TIMER message is posted to the installing thread's message queue when a timer expires.
'You can process the message by providing a WM_TIMER case in the window procedure.
'Otherwise, the default window procedure will call the TimerProc callback function specified
'in the call to the SetTimer function used to install the timer.
'==============================================================================================
'==============================================================================================
Case WM_TIMER
If M_ExWindow.Hover And Not M_ExWindow.Flag Then
CMOS.X = CPOS.X '//-- Assign Memory X POS.
CMOS.Y = CPOS.Y '//-- Assign Memory Y POS.
GetCursorPos CPOS '//-- Capture New X-Y Mouse Coordinates.
'//-- ToolTips Don't Popup Just When the mouse is moving,
' they do so until the mouse is "still" for a few moments.
' Lets do it until that's 1 second.
If (CMOS.X = CPOS.X) And (CMOS.Y = CPOS.Y) Then
bTime = bTime + 1
If bTime > mDelayTime Then '//-- At This Point The Mouse Cursor Has been still for 1 second in the same position
bTime = 0 '//-- Lets Reset the Timer, To count the time that the Tooltip is going to be Alive.
If mAlive = True Then '//-- Ensure no child controls are on same Mouse Coords(in case Lwnd has Child Controls)
CreateToolTip '//-- Begin The ToolTip Drawing.
M_ExWindow.Flag = True '//-- We Now Know That We are ready to draw the ToolTip.
End If
Exit Sub
End If
Else
bTime = 0 '//-- At This Point, the Mouse Cursor has not been still for 1 second in the same position, let's reset the timer.
End If
End If
If InsideArea(LWnd) = False Then
KillTimer LWnd, 1 '//-- Destroy the API Timer
DestroyWindow M_ExWindow.hwnd '//-- Destroy the ToolTip Window when the Mouse Leaves the Control
M_ExWindow.hwnd = 0 '//-- Reset the HWnd Value
M_ExWindow.Hover = False '//-- Reset the Hover Value
M_ExWindow.Flag = False '//-- Reset the Flag Value
Class_Initialize '//-- Reset Default Values for next Instance.
ElseIf bTime >= mKillTime Then
DestroyWindow M_ExWindow.hwnd '//-- AT This Point, the Tool tip as past out the visible time, and must be Destroyed.
Class_Initialize '//-- Reset Default Values for next Instance.
ElseIf M_ExWindow.Hover And M_ExWindow.hwnd <> 0 Then
bTime = bTime + 1
End If
'==============================================================================================
'==============================================================================================
'The WM_MOUSEACTIVATE message is sent when the cursor is in an inactive window and the user
'presses a mouse button.
'==============================================================================================
'==============================================================================================
Case WM_MOUSEACTIVATE
'//-- At This Point, the Tool tip has to be destroyed,
' because the user click on the calling control (natural Tooltip behavior).
KillTimer LWnd, 1 '//-- Destroy the API Timer
DestroyWindow M_ExWindow.hwnd '//-- Send WM_DESTROY Message.
M_ExWindow.Hover = False '//-- Reset the Hover Value
Class_Initialize '//-- Reset Default Values for next Instance.
mAlive = True '//-- Force User To Move Mouse Outside Control Before another Tooltip is Displayed.
'==============================================================================================
'==============================================================================================
'The WM_DESTROY message is sent when a window is being destroyed. It is sent to the window procedure
'of the window being destroyed after the window is removed from the screen.
'==============================================================================================
'==============================================================================================
Case WM_DESTROY
mAlive = False
End Select
End Sub
'======================================================================================================
'Subclass code - The programmer may call any of the following Subclass_??? routines
'Add a message to the table of those that will invoke a callback. You should Subclass_Start first and then add the messages
Private Sub AddMsg(ByVal lng_hWnd As Long, ByVal uMsg As Long, Optional ByVal When As eMsgWhen = MSG_AFTER)
'Parameters:
'lng_hWnd - The handle of the window for which the uMsg is to be added to the callback table
'uMsg - The message number that will invoke a callback. NB Can also be ALL_MESSAGES, ie all messages will callback
'When - Whether the msg is to callback before, after or both with respect to the the default (previous) handler
With sc_aSubData(zIdx(lng_hWnd))
If When And eMsgWhen.MSG_BEFORE Then
Call zAddMsg(uMsg, .aMsgTblB, .nMsgCntB, eMsgWhen.MSG_BEFORE, .nAddrSub)
End If
If When And eMsgWhen.MSG_AFTER Then
Call zAddMsg(uMsg, .aMsgTblA, .nMsgCntA, eMsgWhen.MSG_AFTER, .nAddrSub)
End If
End With
End Sub
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -