📄 mctoolbar.ctl
字号:
.lpStr = StrPtr(m_ButtonItem(m_Button_Index).TB_ToolTipText)
.lpRect = lpRect
End With
''add the tooltip structure
SendMessage m_ToolTipHwnd, TTM_ADDTOOLW, 0&, m_ToolTipInfo
''if we want a title or we want an icon
SendMessage m_ToolTipHwnd, TTM_SETTIPTEXTCOLOR, TranslateColor(m_ToolTipForeCol), 0&
SendMessage m_ToolTipHwnd, TTM_SETTIPBKCOLOR, TranslateColor(m_ToolTipBackCol), 0&
SendMessage m_ToolTipHwnd, TTM_SETTITLEW, m_ButtonItem(m_Button_Index).TB_ToolTipIcon, ByVal StrPtr(m_ButtonItem(m_Button_Index).TB_Caption)
Exit Sub
Handle:
'debug.Print "Error " & Err.Description
End Sub
'------------------------------------------------------------------------------------------------------------------------------------------
' Procedure : FillGradient
' Auther : Jim Jose
' Input : Hdc + Parameters
' OutPut : None
' Purpose : Middleout Gradients with Carls's DIB solution
'------------------------------------------------------------------------------------------------------------------------------------------
Private Sub FillGradient(ByVal hdc As Long, _
ByVal X As Long, _
ByVal Y As Long, _
ByVal Width As Long, _
ByVal Height As Long, _
ByVal Col1 As Long, _
ByVal Col2 As Long, _
ByVal GradientDirection As GradientDirectionEnum, _
Optional Right2Left As Boolean = True)
Dim tmpCol As Long
' Exit if needed
If GradientDirection = Fill_None Then Exit Sub
' Right-To-Left
If Right2Left Then
tmpCol = Col1
Col1 = Col2
Col2 = tmpCol
End If
' Translate system colors
Col1 = TranslateColor(Col1)
Col2 = TranslateColor(Col2)
Select Case GradientDirection
Case Fill_HorizontalMiddleOut
DIBGradient hdc, X, Y, Width / 2, Height, Col1, Col2, Fill_Horizontal
DIBGradient hdc, X + Width / 2 - 1, Y, Width / 2, Height, Col2, Col1, Fill_Horizontal
Case Fill_VerticalMiddleOut
DIBGradient hdc, X, Y, Width, Height / 2, Col1, Col2, Fill_Vertical
DIBGradient hdc, X, Y + Height / 2 - 1, Width, Height / 2 + 1, Col2, Col1, Fill_Vertical
Case Else
DIBGradient hdc, X, Y, Width, Height, Col1, Col2, GradientDirection
End Select
End Sub
'------------------------------------------------------------------------------------------------------------------------------------------
' Procedure : DIBGradient
' Auther : Carls P.V.
' Input : Hdc + Parameters
' OutPut : None
' Purpose : DIB solution for fast gradients
'------------------------------------------------------------------------------------------------------------------------------------------
Private Sub DIBGradient(ByVal hdc As Long, _
ByVal X As Long, _
ByVal Y As Long, _
ByVal vWidth As Long, _
ByVal vHeight As Long, _
ByVal Col1 As Long, _
ByVal Col2 As Long, _
ByVal GradientDirection As GradientDirectionEnum)
Dim uBIH As BITMAPINFOHEADER
Dim lBits() As Long
Dim lGrad() As Long
Dim R1 As Long
Dim G1 As Long
Dim B1 As Long
Dim R2 As Long
Dim G2 As Long
Dim B2 As Long
Dim dR As Long
Dim dG As Long
Dim dB As Long
Dim Scan As Long
Dim i As Long
Dim iEnd As Long
Dim iOffset As Long
Dim j As Long
Dim jEnd As Long
Dim iGrad As Long
'-- A minor check
If (vWidth < 1 Or vHeight < 1) Then Exit Sub
'-- Decompose Cols'
R1 = (Col1 And &HFF&)
G1 = (Col1 And &HFF00&) \ &H100&
B1 = (Col1 And &HFF0000) \ &H10000
R2 = (Col2 And &HFF&)
G2 = (Col2 And &HFF00&) \ &H100&
B2 = (Col2 And &HFF0000) \ &H10000
'-- Get Col distances
dR = R2 - R1
dG = G2 - G1
dB = B2 - B1
'-- Size gradient-Cols array
Select Case GradientDirection
Case [Fill_Horizontal]
ReDim lGrad(0 To vWidth - 1)
Case [Fill_Vertical]
ReDim lGrad(0 To vHeight - 1)
Case Else
ReDim lGrad(0 To vWidth + vHeight - 2)
End Select
'-- Calculate gradient-Cols
iEnd = UBound(lGrad())
If (iEnd = 0) Then
'-- Special case (1-pixel wide gradient)
lGrad(0) = (B1 \ 2 + B2 \ 2) + 256 * (G1 \ 2 + G2 \ 2) + 65536 * (R1 \ 2 + R2 \ 2)
Else
For i = 0 To iEnd
lGrad(i) = B1 + (dB * i) \ iEnd + 256 * (G1 + (dG * i) \ iEnd) + 65536 * (R1 + (dR * i) \ iEnd)
Next i
End If
'-- Size DIB array
ReDim lBits(vWidth * vHeight - 1) As Long
iEnd = vWidth - 1
jEnd = vHeight - 1
Scan = vWidth
'-- Render gradient DIB
Select Case GradientDirection
Case [Fill_Horizontal]
For j = 0 To jEnd
For i = iOffset To iEnd + iOffset
lBits(i) = lGrad(i - iOffset)
Next i
iOffset = iOffset + Scan
Next j
Case [Fill_Vertical]
For j = jEnd To 0 Step -1
For i = iOffset To iEnd + iOffset
lBits(i) = lGrad(j)
Next i
iOffset = iOffset + Scan
Next j
Case [Fill_DownwardDiagonal]
iOffset = jEnd * Scan
For j = 1 To jEnd + 1
For i = iOffset To iEnd + iOffset
lBits(i) = lGrad(iGrad)
iGrad = iGrad + 1
Next i
iOffset = iOffset - Scan
iGrad = j
Next j
Case [Fill_UpwardDiagonal]
iOffset = 0
For j = 1 To jEnd + 1
For i = iOffset To iEnd + iOffset
lBits(i) = lGrad(iGrad)
iGrad = iGrad + 1
Next i
iOffset = iOffset + Scan
iGrad = j
Next j
End Select
'-- Define DIB header
With uBIH
.biSize = 40
.biPlanes = 1
.biBitCount = 32
.biWidth = vWidth
.biHeight = vHeight
End With
'-- Paint it!
Call StretchDIBits(hdc, X, Y, vWidth, vHeight, 0, 0, vWidth, vHeight, lBits(0), uBIH, DIB_RGB_ColS, vbSrcCopy)
End Sub
'------------------------------------------------------------------------------------------------------------------------------------------
' Procedure : TileBitmap
' Auther : Carls P.V.
' Input : Hdc + Parameters
' OutPut : None
' Purpose : Draw tiled picture to a DC
'------------------------------------------------------------------------------------------------------------------------------------------
Private Function TileBitmap(Picture As StdPicture, ByVal hdc As Long, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Boolean
Dim tBI As BITMAP
Dim tBIH As BITMAPINFOHEADER
Dim Buff() As Byte 'Packed DIB
Dim lhDC As Long
Dim lhOldBmp As Long
Dim TileRect As RECT
Dim PtOrg As POINTAPI
Dim m_hBrush As Long
If (GetObjectType(Picture) = 7) Then
' -- Get image info
GetObject Picture, Len(tBI), tBI
' -- Prepare DIB header and redim. Buff() array
With tBIH
.biSize = Len(tBIH) '40
.biPlanes = 1
.biBitCount = 24
.biWidth = tBI.bmWidth
.biHeight = tBI.bmHeight
.biSizeImage = ((.biWidth * 3 + 3) And &HFFFFFFFC) * .biHeight
End With
ReDim Buff(1 To Len(tBIH) + tBIH.biSizeImage) '[Header + Bits]
' -- Create DIB brush
lhDC = CreateCompatibleDC(0)
If (lhDC <> 0) Then
lhOldBmp = SelectObject(lhDC, Picture)
' -- Build packed DIB:
' - Merge Header
CopyMemory Buff(1), tBIH, Len(tBIH)
' - Get and merge DIB Bits
GetDIBits lhDC, Picture, 0, tBI.bmHeight, Buff(Len(tBIH) + 1), tBIH, 0
SelectObject lhDC, lhOldBmp
DeleteDC lhDC
' -- Create brush from packed DIB
m_hBrush = CreateDIBPatternBrushPt(Buff(1), 0)
End If
End If
If (m_hBrush <> 0) Then
SetRect TileRect, X1, Y1, X2, Y2
SetBrushOrgEx hdc, X1, Y1, PtOrg
' -- Tile image
FillRect hdc, TileRect, m_hBrush
DeleteObject m_hBrush
m_hBrush = 0
End If
End Function
'---------------------------------------------------------------------------------------------------------------------------------------------
' The following bytes are donated exclusively for Paul Caton's Subclassing
' We need this to track the movement information of the m_picCalendar and
' sizing/positioning of parent form
'---------------------------------------------------------------------------------------------------------------------------------------------
' Auther : Paul Caton
' Purpose : Advanced subclassing for UserControls (Self subclasser)
' Comment : Thanks a Billion for this ever green piece of code on subclassing!!!
'---------------------------------------------------------------------------------------------------------------------------------------------
'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 Subclass_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
'Delete a message from the table of those that will invoke a callback.
Private Sub Subclass_DelMsg(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 removed from the callback table
'uMsg - The message number that will be removed from the callback table. NB Can also be ALL_MESSAGES, ie all messages will callback
'When - Whether the msg is to be removed from the before, after or both callback tables
With sc_aSubData(zIdx(lng_hWnd))
If When And eMsgWhen.MSG_BEFORE Then
Call zDelMsg(uMsg, .aMsgTblB, .nMsgCntB, eMsgWhen.MSG_BEFORE, .nAddrSub)
End If
If When And eMsgWhen.MSG_AFTER Then
Call zDelMsg(uMsg, .aMsgTblA, .nMsgCntA, eMsgWhen.MSG_AFTER, .nAddrSub)
End If
End With
End Sub
'Return whether we're running in the IDE.
Private Function Subclass_InIDE() As Boolean
'debug.Assert zSetTrue(Subclass_InIDE)
End Function
'Start subclassing the passed window handle
Private Function Subclass_Start(ByVal lng_hWnd As Long) As Long
'Parameters:
'lng_hWnd - The handle of the window to be subclassed
'Returns;
'The sc_aSubData() index
Const CODE_LEN As Long = 200 'Length of the machine code in bytes
Const FUNC_CWP As String = "CallWindowProcA" 'We use CallWindowProc to call the original WndProc
Const FUNC_EBM As String = "EbMode" 'VBA's EbMode function allows the machine code thunk to know if the IDE has stopped or is on a breakpoint
Const FUNC_SWL As String = "SetWindowLongA" 'SetWindowLongA allows the cSubclasser machine code thunk to unsubclass the subclasser itself if it detects via the EbMode function that the IDE has stopped
Const MOD_USER As String = "user32" 'Location of the SetWindowLongA & CallWindowProc functions
Const MOD_VBA5 As String = "vba5" 'Location of the EbMode function if running VB5
Const MOD_VBA6 As String = "vba6" 'Location of the EbMode function if running VB6
Const PATCH_01 As Long = 18 'Code buffer offset to the location of the relative address to EbMode
Const PATCH_02 As Long = 68 'Address of the previous WndProc
Const PATCH_03 As Long = 78 'Relative address of SetWindowsLong
Const PATCH_06 As Long = 116 'Address of the previous WndProc
Const PATCH_07 As Long = 121 'Relative address of CallWindowProc
Const PATCH
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -