ToolBar的模样自己画(五)

王朝other·作者佚名  2006-01-09
宽屏版  字体: |||超大  

'最后一部分,也是最核心的消息处理代码与主绘图过程

Friend Function MsgProc(lParam As Long, MouseDown As Boolean) As Long

Dim tHDR As NMHDR

Dim className As String * 32

Dim retval As Long

CopyMemory tHDR, ByVal lParam, Len(tHDR)

If tHDR.hwndFrom <> 0 Then

retval = GetClassName(tHDR.hwndFrom, className, 33)

If retval > 0 Then

If Left$(className, retval) = "msvb_lib_toolbar" Then

MsgProc = OnCustomDraw(lParam, MouseDown)

End If

End If

End If

End Function

Private Function OnCustomDraw(lParam As Long, MouseDown As Boolean) As Long

Dim tTBCD As NMTBCUSTOMDRAW

Dim hBrush As Long

CopyMemory tTBCD, ByVal lParam, Len(tTBCD)

With tTBCD.nmcd

Select Case .dwDrawStage

Case CDDS_ITEMPREPAINT

OnCustomDraw = CDRF_SKIPDEFAULT

DrawToolbarButton .hdr.hwndFrom, .hdc, .dwItemSpec, .uItemState, .rc, MouseDown

Case CDDS_PREPAINT

OnCustomDraw = CDRF_NOTIFYITEMDRAW

GetClientRect .hdr.hwndFrom, .rc

If mpicBk Is Nothing Then

hBrush = CreateSolidBrush(m_lngBackColor)

Else

hBrush = CreatePatternBrush(mpicBk)

End If

FillRect .hdc, .rc, hBrush

DeleteObject hBrush

End Select

End With

End Function

Private Sub DrawToolbarButton(ByVal hWnd As Long, ByVal hdc As Long, itemSpec As Long, ByVal itemState As Long, tR As RECT, MouseDown As Boolean)

Dim i As Long

Dim bPushed As Boolean, bDropDown As Boolean, bHover As Boolean

Dim bDisabled As Boolean, bChecked As Boolean

Dim bSkipped As Boolean, bBottomText As Boolean, bNoDsbIcon As Boolean

Dim hIcon As Long, hImageList As Long

Dim tTB As TBBUTTON

Dim szText As Size, rcDrop As RECT, rcIcon As RECT

Dim hOldPen As Long, hPen As Long

Dim hFont As Long, hOldFont As Long

Dim sCaption As String, bFirstSetBk As Boolean

Dim lDropWidth As Long, lTxtColor As Long

sCaption = String$(128, vbNullChar)

i = SendMessage(hWnd, TB_GETBUTTONTEXTA, itemSpec, ByVal sCaption)

If i > 0 Then

sCaption = Left$(sCaption, i)

Else

sCaption = ""

End If

i = GetWindowLong(hWnd, GWL_STYLE)

bBottomText = ((i And TBSTYLE_LIST) = 0)

i = SendMessage(hWnd, TB_COMMANDTOINDEX, itemSpec, ByVal 0)

SendMessage hWnd, TB_GETBUTTON, i, tTB

bDisabled = (itemState And CDIS_DISABLED)

bChecked = (itemState And CDIS_CHECKED)

bHover = (itemState And CDIS_HOT)

bPushed = (itemState And CDIS_SELECTED)

If tTB.fsStyle And TBSTYLE_SEP Then '分隔线按钮

hPen = CreatePen(PS_SOLID, 1, vb3DShadow)

hOldPen = SelectObject(hdc, hPen)

MoveToEx hdc, tR.Left + 2&, tR.Top + 1&, ByVal 0

LineTo hdc, tR.Left + 2&, tR.Bottom - 1&

SelectObject hdc, hOldPen

DeleteObject hPen

Exit Sub

Else

hImageList = SendMessage(hWnd, TB_GETIMAGELIST, 0, ByVal 0)

If hImageList <> 0 Then '取得主图像列表

If mlngImgList <> hImageList Then

mlngImgList = hImageList

bFirstSetBk = True

mlngIconWidth = 0

End If

If bDisabled Then '取得禁用图像列表

i = SendMessage(hWnd, TB_GETDISABLEDIMAGELIST, 0, ByVal 0)

If i <> 0 And i <> hImageList Then

hImageList = i

If mlngDsbImgList <> i Then

mlngDsbImgList = i

bFirstSetBk = True

End If

Else

bNoDsbIcon = True

End If

ElseIf bHover Then '取得热图像列表

i = SendMessage(hWnd, TB_GETHOTIMAGELIST, 0, ByVal 0)

If i <> 0 And i <> hImageList Then

hImageList = i

If mlngHotImgList <> i Then

mlngHotImgList = i

bFirstSetBk = True

End If

End If

End If

If bFirstSetBk Then '首次使用需设定背景色

If ImageList_GetBkColor(hImageList) <> -1 Then

ImageList_SetBkColor hImageList, CLR_NONE

End If

End If

hIcon = ImageList_GetIcon(hImageList, tTB.iBitmap, ILD_NORMAL)

If mlngIconWidth = 0 Then GetIconSize hIcon

End If

'根据状态创建不同刷子与画笔

lTxtColor = m_lngTextColor

If bChecked Or bPushed Then

AlphaBlend hdc, tR.Left, tR.Top, tR.Right - tR.Left, tR.Bottom - tR.Top, mdcWhite.hdc, 0, 0, tR.Right - tR.Left, tR.Bottom - tR.Top, mlngBtnDownAlpha * &H10000

ElseIf bHover Then

AlphaBlend hdc, tR.Left, tR.Top, tR.Right - tR.Left, tR.Bottom - tR.Top, mdcWhite.hdc, 0, 0, tR.Right - tR.Left, tR.Bottom - tR.Top, mlngBtnHiAlpha * &H10000

lTxtColor = m_lngTextHiColor

Else

bSkipped = True

End If

SetTextColor hdc, lTxtColor

If tTB.fsStyle And TBSTYLE_DROPDOWN Then

lDropWidth = 14

bDropDown = bHover And MouseDown And Not bPushed

SetRect rcDrop, tR.Right - lDropWidth, tR.Top, tR.Right, tR.Bottom

tR.Right = tR.Right - lDropWidth

End If

End If

SetBkMode hdc, 1 '文本背景透明

If bSkipped = False Then '根据样式不同,画不同边框并填充

If bChecked Or bPushed Then

DrawRect hdc, tR, 2

Else

DrawRect hdc, tR, 1

End If

Else

DrawRect hdc, tR, 0

End If

If tTB.fsStyle And TBSTYLE_DROPDOWN Then '处理下拉菜单的小按钮

If bSkipped = False Or m_lngBrdStyle > 0 Then

If bDropDown Then

AlphaBlend hdc, rcDrop.Left, rcDrop.Top, lDropWidth, rcDrop.Bottom - rcDrop.Top, mdcWhite.hdc, 0, 0, rcDrop.Right - rcDrop.Left, rcDrop.Bottom - rcDrop.Top, mlngBtnDownAlpha * &H10000

End If

If bDropDown Or bPushed Then

DrawRect hdc, rcDrop, 2, True

ElseIf bHover Then

DrawRect hdc, rcDrop, 1, True

Else

DrawRect hdc, rcDrop, 0, True

MouseDown = False

End If

Else

MouseDown = False

End If

DrawPloy3 hdc, rcDrop, bHover And Not (bDropDown Or bPushed)

End If

'画图标与文本

With rcIcon

'计算图标区域

.Top = tR.Top + 3

If bBottomText = False Then .Left = tR.Left + 3

If mlngIconWidth < 16 Then

If bBottomText Then .Left = tR.Left + (tR.Right - tR.Left - 16) \ 2

.Right = .Left + 16

Else

If bBottomText Then .Left = tR.Left + (tR.Right - tR.Left - mlngIconWidth) \ 2

.Right = .Left + mlngIconWidth

End If

If mlngIconHeight < 16 Then

.Bottom = .Top + 16

Else

.Bottom = .Top + mlngIconHeight

End If

If bHover And (Not (bPushed Or bChecked)) Then

.Left = .Left - 1

.Top = .Top - 1

.Right = .Right - 1

.Bottom = .Bottom - 1

End If

If hImageList <> 0 Then

If bDisabled And bNoDsbIcon Then

If hIcon Then

DrawState hdc, 0, 0, hIcon, 0, .Left, .Top, 0, 0, DST_ICON Or DSS_DISABLED

End If

Else

ImageList_Draw hImageList, tTB.iBitmap, hdc, .Left, .Top, ILD_NORMAL

End If

End If

If Len(sCaption) > 0 Then

hFont = CreateFontIndirect(Font)

hOldFont = SelectObject(hdc, hFont)

If bBottomText Then

If bDisabled Then

SetTextAlign hdc, TA_LEFT

GetTextExtentPoint32 hdc, sCaption, lstrlen(sCaption), szText

DrawState hdc, 0, 0, StrPtr(StrConv(sCaption, vbFromUnicode)), lstrlen(sCaption), (.Right + .Left - szText.cx) \ 2, .Bottom + 1, 0, 0, DST_TEXT Or DSS_DISABLED

Else

SetTextAlign hdc, TA_CENTER

TextOut hdc, (.Right + .Left) \ 2, .Bottom + 1, sCaption, lstrlen(sCaption)

End If

Else

SetTextAlign hdc, TA_LEFT

If bDisabled Then

'GetTextExtentPoint32 hdc, sCaption, lstrlen(sCaption), szText

DrawState hdc, 0, 0, StrPtr(StrConv(sCaption, vbFromUnicode)), lstrlen(sCaption), .Right + 1, (.Top + .Bottom - Font.lfHeight) \ 2, 0, 0, DST_TEXT Or DSS_DISABLED

Else

TextOut hdc, .Right + 1, (.Top + .Bottom - Font.lfHeight) \ 2, sCaption, lstrlen(sCaption)

End If

End If

SelectObject hdc, hOldFont

DeleteObject hFont

End If

End With

If hIcon <> 0 Then DestroyIcon hIcon

End Sub

初涉Custom Draw消息处理,ToolBar本来我就很少用,所以我的兴趣是处理过程本身,而不是应用需求,很难静心深入研究它。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有