找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 2988|回复: 0

ToolBar的模样自己画(五)

[复制链接]

1214

主题

352

回帖

11

精华

管理员

菜鸟

积分
93755

贡献奖关注奖人气王精英奖乐于助人勋章

发表于 2010-1-30 09:16:17 | 显示全部楼层 |阅读模式

  1. '最后一部分,也是最核心的消息处理代码与主绘图过程
  2. Function MsgProc(lParam As Long, MouseDown As Boolean) As Long
  3. Dim tHDR As NMHDR
  4. Dim className As String * 32
  5. Dim retval As Long
  6.     CopyMemory tHDR, ByVal lParam, Len(tHDR)
  7.     If tHDR.hwndFrom <> 0 Then
  8.         retval = GetClassName(tHDR.hwndFrom, className, 33)
  9.         If retval > 0 Then
  10.             If Left$(className, retval) = "msvb_lib_toolbar" Then
  11.                 MsgProc = OnCustomDraw(lParam, MouseDown)
  12.             End If
  13.         End If
  14.     End If
  15. End Function
  16. Private Function OnCustomDraw(lParam As Long, MouseDown As Boolean) As Long
  17. Dim tTBCD As NMTBCUSTOMDRAW
  18. Dim hBrush As Long
  19.     CopyMemory tTBCD, ByVal lParam, Len(tTBCD)
  20.     With tTBCD.nmcd
  21.         Select Case .dwDrawStage
  22.         Case CDDS_ITEMPREPAINT
  23.             OnCustomDraw = CDRF_SKIPDEFAULT
  24.             DrawToolbarButton .hdr.hwndFrom, .hdc, .dwItemSpec, .uItemState, .rc, MouseDown
  25.         Case CDDS_PREPAINT
  26.             OnCustomDraw = CDRF_NOTIFYITEMDRAW
  27.             GetClientRect .hdr.hwndFrom, .rc
  28.             If mpicBk Is Nothing Then
  29.                 hBrush = CreateSolidBrush(m_lngBackColor)
  30.             Else
  31.                 hBrush = CreatePatternBrush(mpicBk)
  32.             End If
  33.             FillRect .hdc, .rc, hBrush
  34.             DeleteObject hBrush
  35.         End Select
  36.     End With
  37. End Function
  38. Private Sub DrawToolbarButton(ByVal hWnd As Long, ByVal hdc As Long, itemSpec As Long, ByVal itemState As Long, tR As RECT, MouseDown As Boolean)
  39. Dim i As Long
  40. Dim bPushed As Boolean, bDropDown As Boolean, bHover As Boolean
  41. Dim bDisabled As Boolean, bChecked As Boolean
  42. Dim bSkipped As Boolean, bBottomText As Boolean, bNoDsbIcon As Boolean
  43. Dim hIcon As Long, hImageList As Long
  44. Dim tTB As TBBUTTON
  45. Dim szText As Size, rcDrop As RECT, rcIcon As RECT
  46. Dim hOldPen As Long, hPen As Long
  47. Dim hFont As Long, hOldFont As Long
  48. Dim sCaption As String, bFirstSetBk As Boolean
  49. Dim lDropWidth As Long, lTxtColor As Long
  50.     sCaption = String$(128, vbNullChar)
  51.     i = SendMessage(hWnd, TB_GETBUTTONTEXTA, itemSpec, ByVal sCaption)
  52.     If i > 0 Then
  53.         sCaption = Left$(sCaption, i)
  54.     Else
  55.         sCaption = ""
  56.     End If
  57.     i = GetWindowLong(hWnd, GWL_STYLE)
  58.     bBottomText = ((i And TBSTYLE_LIST) = 0)
  59.     i = SendMessage(hWnd, TB_COMMANDTOINDEX, itemSpec, ByVal 0)
  60.     SendMessage hWnd, TB_GETBUTTON, i, tTB
  61.     bDisabled = (itemState And CDIS_DISABLED)
  62.     bChecked = (itemState And CDIS_CHECKED)
  63.     bHover = (itemState And CDIS_HOT)
  64.     bPushed = (itemState And CDIS_SELECTED)
  65.     If tTB.fsStyle And TBSTYLE_SEP Then    '分隔线按钮
  66.         hPen = CreatePen(PS_SOLID, 1, vb3DShadow)
  67.         hOldPen = SelectObject(hdc, hPen)
  68.         MoveToEx hdc, tR.Left + 2&, tR.Top + 1&, ByVal 0
  69.         LineTo hdc, tR.Left + 2&, tR.Bottom - 1&
  70.         SelectObject hdc, hOldPen
  71.         DeleteObject hPen
  72.         Exit Sub
  73.     Else
  74.         hImageList = SendMessage(hWnd, TB_GETIMAGELIST, 0, ByVal 0)
  75.         If hImageList <> 0 Then    '取得主图像列表
  76.             If mlngImgList <> hImageList Then
  77.                 mlngImgList = hImageList
  78.                 bFirstSetBk = True
  79.                 mlngIconWidth = 0
  80.             End If
  81.             If bDisabled Then    '取得禁用图像列表
  82.                 i = SendMessage(hWnd, TB_GETDISABLEDIMAGELIST, 0, ByVal 0)
  83.                 If i <> 0 And i <> hImageList Then
  84.                     hImageList = i
  85.                     If mlngDsbImgList <> i Then
  86.                         mlngDsbImgList = i
  87.                         bFirstSetBk = True
  88.                     End If
  89.                 Else
  90.                     bNoDsbIcon = True
  91.                 End If
  92.             ElseIf bHover Then    '取得热图像列表
  93.                 i = SendMessage(hWnd, TB_GETHOTIMAGELIST, 0, ByVal 0)
  94.                 If i <> 0 And i <> hImageList Then
  95.                     hImageList = i
  96.                     If mlngHotImgList <> i Then
  97.                         mlngHotImgList = i
  98.                         bFirstSetBk = True
  99.                     End If
  100.                 End If
  101.             End If
  102.             If bFirstSetBk Then    '首次使用需设定背景色
  103.                 If ImageList_GetBkColor(hImageList) <> -1 Then
  104.                     ImageList_SetBkColor hImageList, CLR_NONE
  105.                 End If
  106.             End If
  107.             hIcon = ImageList_GetIcon(hImageList, tTB.iBitmap, ILD_NORMAL)
  108.             If mlngIconWidth = 0 Then GetIconSize hIcon
  109.         End If
  110.         '根据状态创建不同刷子与画笔
  111.         lTxtColor = m_lngTextColor
  112.         If bChecked Or bPushed Then
  113.             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
  114.         ElseIf bHover Then
  115.             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
  116.             lTxtColor = m_lngTextHiColor
  117.         Else
  118.             bSkipped = True
  119.         End If
  120.         SetTextColor hdc, lTxtColor
  121.         If tTB.fsStyle And TBSTYLE_DROPDOWN Then
  122.             lDropWidth = 14
  123.             bDropDown = bHover And MouseDown And Not bPushed
  124.             SetRect rcDrop, tR.Right - lDropWidth, tR.Top, tR.Right, tR.Bottom
  125.             tR.Right = tR.Right - lDropWidth
  126.         End If
  127.     End If
  128.     SetBkMode hdc, 1    '文本背景透明
  129.     If bSkipped = False Then    '根据样式不同,画不同边框并填充
  130.         If bChecked Or bPushed Then
  131.             DrawRect hdc, tR, 2
  132.         Else
  133.             DrawRect hdc, tR, 1
  134.         End If
  135.     Else
  136.         DrawRect hdc, tR, 0
  137.     End If
  138.     If tTB.fsStyle And TBSTYLE_DROPDOWN Then    '处理下拉菜单的小按钮
  139.         If bSkipped = False Or m_lngBrdStyle > 0 Then
  140.             If bDropDown Then
  141.                 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
  142.             End If
  143.             If bDropDown Or bPushed Then
  144.                 DrawRect hdc, rcDrop, 2, True
  145.             ElseIf bHover Then
  146.                 DrawRect hdc, rcDrop, 1, True
  147.             Else
  148.                 DrawRect hdc, rcDrop, 0, True
  149.                 MouseDown = False
  150.             End If
  151.         Else
  152.             MouseDown = False
  153.         End If
  154.         DrawPloy3 hdc, rcDrop, bHover And Not (bDropDown Or bPushed)
  155.     End If
  156.     '画图标与文本
  157.     With rcIcon
  158.         '计算图标区域
  159.         .Top = tR.Top + 3
  160.         If bBottomText = False Then .Left = tR.Left + 3
  161.         If mlngIconWidth < 16 Then
  162.             If bBottomText Then .Left = tR.Left + (tR.Right - tR.Left - 16) \ 2
  163.             .Right = .Left + 16
  164.         Else
  165.             If bBottomText Then .Left = tR.Left + (tR.Right - tR.Left - mlngIconWidth) \ 2
  166.             .Right = .Left + mlngIconWidth
  167.         End If
  168.         If mlngIconHeight < 16 Then
  169.             .Bottom = .Top + 16
  170.         Else
  171.             .Bottom = .Top + mlngIconHeight
  172.         End If
  173.         If bHover And (Not (bPushed Or bChecked)) Then
  174.             .Left = .Left - 1
  175.             .Top = .Top - 1
  176.             .Right = .Right - 1
  177.             .Bottom = .Bottom - 1
  178.         End If
  179.         If hImageList <> 0 Then
  180.             If bDisabled And bNoDsbIcon Then
  181.                 If hIcon Then
  182.                     DrawState hdc, 0, 0, hIcon, 0, .Left, .Top, 0, 0, DST_ICON Or DSS_DISABLED
  183.                 End If
  184.             Else
  185.                 ImageList_Draw hImageList, tTB.iBitmap, hdc, .Left, .Top, ILD_NORMAL
  186.             End If
  187.         End If
  188.         If Len(sCaption) > 0 Then
  189.             hFont = CreateFontIndirect(Font)
  190.             hOldFont = SelectObject(hdc, hFont)
  191.             If bBottomText Then
  192.                 If bDisabled Then
  193.                     SetTextAlign hdc, TA_LEFT
  194.                     GetTextExtentPoint32 hdc, sCaption, lstrlen(sCaption), szText
  195.                     DrawState hdc, 0, 0, StrPtr(StrConv(sCaption, vbFromUnicode)), lstrlen(sCaption), (.Right + .Left - szText.cx) \ 2, .Bottom + 1, 0, 0, DST_TEXT Or DSS_DISABLED
  196.                 Else
  197.                     SetTextAlign hdc, TA_CENTER
  198.                     TextOut hdc, (.Right + .Left) \ 2, .Bottom + 1, sCaption, lstrlen(sCaption)
  199.                 End If
  200.             Else
  201.                 SetTextAlign hdc, TA_LEFT
  202.                 If bDisabled Then
  203.                     'GetTextExtentPoint32 hdc, sCaption, lstrlen(sCaption), szText
  204.                     DrawState hdc, 0, 0, StrPtr(StrConv(sCaption, vbFromUnicode)), lstrlen(sCaption), .Right + 1, (.Top + .Bottom - Font.lfHeight) \ 2, 0, 0, DST_TEXT Or DSS_DISABLED
  205.                 Else
  206.                     TextOut hdc, .Right + 1, (.Top + .Bottom - Font.lfHeight) \ 2, sCaption, lstrlen(sCaption)
  207.                 End If
  208.             End If
  209.             SelectObject hdc, hOldFont
  210.             DeleteObject hFont
  211.         End If
  212.     End With
  213.     If hIcon <> 0 Then DestroyIcon hIcon
  214. End Sub
  215. '初涉Custom Draw消息处理,ToolBar本来我就很少用,所以我的兴趣是处理过程本身,而不是应用需求,很难静心深入研究它。

复制代码
【VB】QQ群:1422505加的请打上VB好友
【易语言】QQ群:9531809  或 177048
【FOXPRO】QQ群:6580324  或 33659603
【C/C++/VC】QQ群:3777552
【NiceBasic】QQ群:3703755
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表