📄 isbutton.ctl
字号:
End Sub
'======================================================================================================
'These z??? routines are exclusively called by the Subclass_??? routines.
'Worker sub for Subclass_AddMsg
Private Sub zAddMsg(ByVal uMsg As Long, ByRef aMsgTbl() As Long, ByRef nMsgCnt As Long, ByVal When As eMsgWhen, ByVal nAddr As Long)
Dim nEntry As Long 'Message table entry index
Dim nOff1 As Long 'Machine code buffer offset 1
Dim nOff2 As Long 'Machine code buffer offset 2
If uMsg = ALL_MESSAGES Then 'If all messages
nMsgCnt = ALL_MESSAGES 'Indicates that all messages will callback
Else 'Else a specific message number
Do While nEntry < nMsgCnt 'For each existing entry. NB will skip if nMsgCnt = 0
nEntry = nEntry + 1
If aMsgTbl(nEntry) = 0 Then 'This msg table slot is a deleted entry
aMsgTbl(nEntry) = uMsg 'Re-use this entry
Exit Sub 'Bail
ElseIf aMsgTbl(nEntry) = uMsg Then 'The msg is already in the table!
Exit Sub 'Bail
End If
Loop 'Next entry
nMsgCnt = nMsgCnt + 1 'New slot required, bump the table entry count
ReDim Preserve aMsgTbl(1 To nMsgCnt) As Long 'Bump the size of the table.
aMsgTbl(nMsgCnt) = uMsg 'Store the message number in the table
End If
If When = eMsgWhen.MSG_BEFORE Then 'If before
nOff1 = PATCH_04 'Offset to the Before table
nOff2 = PATCH_05 'Offset to the Before table entry count
Else 'Else after
nOff1 = PATCH_08 'Offset to the After table
nOff2 = PATCH_09 'Offset to the After table entry count
End If
If uMsg <> ALL_MESSAGES Then
Call zPatchVal(nAddr, nOff1, VarPtr(aMsgTbl(1))) 'Address of the msg table, has to be re-patched because Redim Preserve will move it in memory.
End If
Call zPatchVal(nAddr, nOff2, nMsgCnt) 'Patch the appropriate table entry count
End Sub
'Return the memory address of the passed function in the passed dll
Private Function zAddrFunc(ByVal sDLL As String, ByVal sProc As String) As Long
zAddrFunc = GetProcAddress(GetModuleHandleA(sDLL), sProc)
Debug.Assert zAddrFunc 'You may wish to comment out this line if you're using vb5 else the EbMode GetProcAddress will stop here everytime because we look for vba6.dll first
End Function
'Worker sub for Subclass_DelMsg
Private Sub zDelMsg(ByVal uMsg As Long, ByRef aMsgTbl() As Long, ByRef nMsgCnt As Long, ByVal When As eMsgWhen, ByVal nAddr As Long)
Dim nEntry As Long
If uMsg = ALL_MESSAGES Then 'If deleting all messages
nMsgCnt = 0 'Message count is now zero
If When = eMsgWhen.MSG_BEFORE Then 'If before
nEntry = PATCH_05 'Patch the before table message count location
Else 'Else after
nEntry = PATCH_09 'Patch the after table message count location
End If
Call zPatchVal(nAddr, nEntry, 0) 'Patch the table message count to zero
Else 'Else deleteting a specific message
Do While nEntry < nMsgCnt 'For each table entry
nEntry = nEntry + 1
If aMsgTbl(nEntry) = uMsg Then 'If this entry is the message we wish to delete
aMsgTbl(nEntry) = 0 'Mark the table slot as available
Exit Do 'Bail
End If
Loop 'Next entry
End If
End Sub
'Get the sc_aSubData() array index of the passed hWnd
Private Function zIdx(ByVal lng_hWnd As Long, Optional ByVal bAdd As Boolean = False) As Long
'Get the upper bound of sc_aSubData() - If you get an error here, you're probably Subclass_AddMsg-ing before Subclass_Start
zIdx = UBound(sc_aSubData)
Do While zIdx >= 0 'Iterate through the existing sc_aSubData() elements
With sc_aSubData(zIdx)
If .hwnd = lng_hWnd Then 'If the hWnd of this element is the one we're looking for
If Not bAdd Then 'If we're searching not adding
Exit Function 'Found
End If
ElseIf .hwnd = 0 Then 'If this an element marked for reuse.
If bAdd Then 'If we're adding
Exit Function 'Re-use it
End If
End If
End With
zIdx = zIdx - 1 'Decrement the index
Loop
If Not bAdd Then
Debug.Assert False 'hWnd not found, programmer error
End If
'If we exit here, we're returning -1, no freed elements were found
End Function
'Patch the machine code buffer at the indicated offset with the relative address to the target address.
Private Sub zPatchRel(ByVal nAddr As Long, ByVal nOffset As Long, ByVal nTargetAddr As Long)
Call RtlMoveMemory(ByVal nAddr + nOffset, nTargetAddr - nAddr - nOffset - 4, 4)
End Sub
'Patch the machine code buffer at the indicated offset with the passed value
Private Sub zPatchVal(ByVal nAddr As Long, ByVal nOffset As Long, ByVal nValue As Long)
Call RtlMoveMemory(ByVal nAddr + nOffset, nValue, 4)
End Sub
'Worker function for Subclass_InIDE
Private Function zSetTrue(ByRef bValue As Boolean) As Boolean
zSetTrue = True
bValue = True
End Function
'*************************************************************
'
' Private Auxiliar Subs
'
'*************************************************************
'draw a Line Using API call's
Private Sub APILine(X1 As Long, Y1 As Long, X2 As Long, Y2 As Long, lColor As Long)
'Use the API LineTo for Fast Drawing
Dim pt As POINT
Dim hPen As Long, hPenOld As Long
hPen = CreatePen(0, 1, lColor)
hPenOld = SelectObject(UserControl.hDC, hPen)
MoveToEx UserControl.hDC, X1, Y1, pt
LineTo UserControl.hDC, X2, Y2
SelectObject UserControl.hDC, hPenOld
DeleteObject hPen
End Sub
' full version of APILine
Private Sub APILineEx(lhdcEx As Long, X1 As Long, Y1 As Long, X2 As Long, Y2 As Long, lColor As Long)
'Use the API LineTo for Fast Drawing
Dim pt As POINT
Dim hPen As Long, hPenOld As Long
hPen = CreatePen(0, 1, lColor)
hPenOld = SelectObject(lhdcEx, hPen)
MoveToEx lhdcEx, X1, Y1, pt
LineTo lhdcEx, X2, Y2
SelectObject lhdcEx, hPenOld
DeleteObject hPen
End Sub
Private Sub APIFillRect(hDC As Long, rc As RECT, Color As Long)
Dim OldBrush As Long
Dim NewBrush As Long
NewBrush& = CreateSolidBrush(Color&)
Call FillRect(hDC&, rc, NewBrush&)
Call DeleteObject(NewBrush&)
End Sub
Private Sub APIFillRectByCoords(hDC As Long, ByVal X As Long, ByVal Y As Long, ByVal w As Long, ByVal h As Long, Color As Long)
Dim OldBrush As Long
Dim NewBrush As Long
Dim tmprect As RECT
NewBrush& = CreateSolidBrush(Color&)
SetRect tmprect, X, Y, X + w, Y + h
Call FillRect(hDC&, tmprect, NewBrush&)
Call DeleteObject(NewBrush&)
End Sub
Private Function APIRectangle(ByVal hDC As Long, ByVal X As Long, ByVal Y As Long, ByVal w As Long, ByVal h As Long, Optional lColor As OLE_COLOR = -1) As Long
Dim hPen As Long, hPenOld As Long
Dim R
Dim pt As POINT
hPen = CreatePen(0, 1, lColor)
hPenOld = SelectObject(hDC, hPen)
MoveToEx hDC, X, Y, pt
LineTo hDC, X + w, Y
LineTo hDC, X + w, Y + h
LineTo hDC, X, Y + h
LineTo hDC, X, Y
SelectObject hDC, hPenOld
DeleteObject hPen
End Function
Private Sub DrawCtlEdgeByRect(hDC As Long, rt As RECT, Optional Style As Long = EDGE_RAISED, Optional flags As Long = BF_RECT)
DrawEdge hDC, rt, Style, flags
End Sub
Private Sub DrawCtlEdge(hDC As Long, ByVal X As Single, ByVal Y As Single, ByVal w As Single, ByVal h As Single, Optional Style As Long = EDGE_RAISED, Optional ByVal flags As Long = BF_RECT)
Dim R As RECT
With R
.Left = X
.Top = Y
.Right = X + w
.Bottom = Y + h
End With
DrawEdge hDC, R, Style, flags
End Sub
'Blend two colors
Private Function BlendColors(ByVal lcolor1 As Long, ByVal lcolor2 As Long)
BlendColors = RGB(((lcolor1 And &HFF) + (lcolor2 And &HFF)) / 2, (((lcolor1 \ &H100) And &HFF) + ((lcolor2 \ &H100) And &HFF)) / 2, (((lcolor1 \ &H10000) And &HFF) + ((lcolor2 \ &H10000) And &HFF)) / 2)
End Function
'System color code to long rgb
Private Function TranslateColor(ByVal lColor As Long) As Long
If OleTranslateColor(lColor, 0, TranslateColor) Then
TranslateColor = -1
End If
End Function
'Make Soft a color
Private Function SoftColor(lColor As OLE_COLOR) As OLE_COLOR
Dim lRed As OLE_COLOR
Dim lGreen As OLE_COLOR
Dim lBlue As OLE_COLOR
Dim lr As OLE_COLOR, lg As OLE_COLOR, lb As OLE_COLOR
lr = (lColor And &HFF)
lg = ((lColor And 65280) \ 256)
lb = ((lColor) And 16711680) \ 65536
lRed = (76 - Int(((lColor And &HFF) + 32) \ 64) * 19)
lGreen = (76 - Int((((lColor And 65280) \ 256) + 32) \ 64) * 19)
lBlue = (76 - I
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -