虽然在VB里实现XP风格很简单,但是要使用XP风格同时又让按钮显示图片,则实现起来要麻烦一些,为此,我写了一个控件来实现前述功能,同时让读者可以从中了解XP主题界面的绘制过程。

使用办法很简单,在VB里新建一个工程,然后添加一个控件模块,粘贴以下代码,再将控件放置到窗口即可,当然,可别忘设置图片和文字属性,具体代码如下:

'* ************************************************** *
'* 模块名称:CommandButtonEx.ctl
'* 模块功能:带图片的XP风格的按钮控件
'* 编码:lyserver
'* 联系方式:http://blog.csdn.net/lyserver
'* ************************************************** *

Option Explicit

'----------------------------------------------------
'API声明
'----------------------------------------------------
Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type
Private Type POINTAPI
    x As Long
    y As Long
End Type
Private Type SIZE
    cx As Long
    cy As Long
End Type
Private Enum THEMESIZE
    TS_MIN '// minimum size
    TS_TRUE '// size without stretching
    TS_DRAW '// size that theme mgr will use to draw part
End Enum
Private Declare Function OpenThemeData Lib "uxtheme.dll" (ByVal hwnd As Long, ByVal pszClassList As Long) As Long
Private Declare Function CloseThemeData Lib "uxtheme.dll" (ByVal hTheme As Long) As Long
Private Declare Function DrawThemeBackground Lib "uxtheme.dll" (ByVal hTheme As Long, ByVal lHDC As Long, ByVal iPartId As Long, ByVal nStateId As Long, pRect As RECT, pClipRect As RECT) As Long
Private Declare Function DrawThemeParentBackground Lib "uxtheme.dll" (ByVal hwnd As Long, ByVal hdc As Long, prc As RECT) As Long
Private Declare Function GetThemePartSize Lib "uxtheme.dll" (ByVal hTheme As Long, ByVal hdc As Long, ByVal iPartId As Long, ByVal nStateId As Long, prc As RECT, ByVal eSize As Long, psz As SIZE) As Long
Private Declare Function GetThemeBackgroundContentRect Lib "uxtheme.dll" (ByVal hTheme As Long, ByVal hdc As Long, ByVal iPartId As Long, ByVal nStateId As Long, pBoundingRect As RECT, pContentRect As RECT) As Long
Private Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function SetRect Lib "user32" (lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function PtInRect Lib "user32" (lpRect As RECT, ByVal x As Long, ByVal y As Long) As Long
Private Declare Function DrawFocusRect Lib "user32" (ByVal hdc As Long, lpRect As RECT) As Long
Private Declare Function InflateRect Lib "user32" (lpRect As RECT, ByVal x As Long, ByVal y As Long) As Long

Private Declare Function SetCapture Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseCapture Lib "user32" () As Long
Private Declare Function DrawText Lib "user32" Alias "DrawTextA" (ByVal hdc As Long, ByVal lpStr As String, ByVal nCount As Long, lpRect As RECT, ByVal wFormat As Long) As Long
Private Const DT_LEFT = &H0
Private Const DT_CENTER = &H1
Private Const DT_RIGHT = &H2
Private Const DT_TOP = &H0
Private Const DT_VCENTER = &H4
Private Const DT_BOTTOM = &H8
Private Const DT_SINGLELINE = &H20
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As String) As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
Private Declare Function ScreenToClient Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long

'----------------------------------------------------
'控件事件声明
'----------------------------------------------------
Public Event KeyDown(KeyCode As Integer, Shift As Integer)
Public Event KeyPress(KeyAscii As Integer)
Public Event KeyUp(KeyCode As Integer, Shift As Integer)
Public Event MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
Public Event MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
Public Event MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
Public Event Click()

'----------------------------------------------------
'模块用户变量声明
'----------------------------------------------------
Dim m_nState As Long '按钮控件状态
Dim m_blnMouseEnter As Boolean '鼠标移入控件
Dim m_rcUserControl As RECT '控件矩形
Dim m_blnFocus As Boolean '是否处于焦点

'----------------------------------------------------
'属性变量声明
'----------------------------------------------------
Dim m_mvarValue As String
Dim m_mvarPicture As StdPicture
Dim m_mvarHotPicture As StdPicture
Dim m_mvarTextAlign As AlignConstants
Dim m_mvarHasFocus As Boolean

'----------------------------------------------------
'过程说明:控件初始化
'----------------------------------------------------
Private Sub UserControl_Initialize()
    UserControl.ScaleMode = vbPixels
    m_nState = 1 '设置控件默认状态为PBS_NORMAL
End Sub

'----------------------------------------------------
'过程说明:控件被销毁
'----------------------------------------------------
Private Sub UserControl_Terminate()
    Set m_mvarPicture = Nothing
    Set m_mvarHotPicture = Nothing
End Sub

'----------------------------------------------------
'过程说明:控件按键按下处理
'----------------------------------------------------
Private Sub UserControl_KeyDown(KeyCode As Integer, Shift As Integer)
    If KeyCode = 13 Or KeyCode = 32 Then
        m_nState = 3
        UserControl.Refresh
    End If
    RaiseEvent KeyDown(KeyCode, Shift)
End Sub

'----------------------------------------------------
'过程说明:控件按键处理
'----------------------------------------------------
Private Sub UserControl_KeyPress(KeyAscii As Integer)
    RaiseEvent KeyPress(KeyAscii)
End Sub

'----------------------------------------------------
'过程说明:控件按键抬起处理
'----------------------------------------------------
Private Sub UserControl_KeyUp(KeyCode As Integer, Shift As Integer)
    Dim ptCursor As POINTAPI

If KeyCode = 13 Or KeyCode = 32 Then
        GetCursorPos ptCursor
        ScreenToClient UserControl.hwnd, ptCursor
        If PtInRect(m_rcUserControl, ptCursor.x, ptCursor.y) Then
            m_nState = 2 '控件状态为PBS_HOT
        Else
            m_nState = IIf(m_blnFocus, 5, 1) '控件状态为PBS_NORMAL
        End If
        UserControl.Refresh
        DoEvents
    End If
    RaiseEvent KeyUp(KeyCode, Shift)
End Sub

'----------------------------------------------------
'过程说明:控件缩放处理
'----------------------------------------------------
Private Sub UserControl_Resize()
    GetClientRect UserControl.hwnd, m_rcUserControl
End Sub

'----------------------------------------------------
'过程说明:控件鼠标按下处理
'----------------------------------------------------
Private Sub UserControl_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    If Button = 1 Then '只处理鼠标左键
        m_nState = 3 '控件状态为PBS_PRESSED
        UserControl.Refresh
    End If
    RaiseEvent MouseDown(Button, Shift, x, y)
End Sub

'----------------------------------------------------
'过程说明:控件鼠标移动处理
'----------------------------------------------------
Private Sub UserControl_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    '鼠标移到控件上
    If x > 0 And y > 0 And x < UserControl.ScaleWidth And y < UserControl.ScaleHeight Then
        If Not m_blnMouseEnter Then
            m_nState = 2 '控件状态为PBS_HOT
            m_blnMouseEnter = True
            UserControl.Refresh
        End If
        SetCapture UserControl.hwnd
        '鼠标移出控件外
    Else
        ReleaseCapture
        m_blnMouseEnter = False
        m_nState = IIf(m_blnFocus, 5, 1) '控件状态为PBS_NORMAL
        UserControl.Refresh
    End If
    RaiseEvent MouseMove(Button, Shift, x, y)
End Sub

'----------------------------------------------------
'过程说明:控件鼠标抬起处理
'----------------------------------------------------
Private Sub UserControl_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    Dim ptCursor As POINTAPI
    Dim blnTemp As Boolean

RaiseEvent MouseUp(Button, Shift, x, y)
    If Button = 1 Then '只处理鼠标左键
        blnTemp = m_blnFocus
        m_blnFocus = False
        m_nState = 5
        UserControl.Refresh
        If m_blnMouseEnter Then RaiseEvent Click '激发Click事件
        m_blnFocus = blnTemp
        GetCursorPos ptCursor
        ScreenToClient UserControl.hwnd, ptCursor
        If PtInRect(m_rcUserControl, ptCursor.x, ptCursor.y) Then
            m_nState = 2
        Else
            m_nState = IIf(m_blnFocus, 5, 1)
        End If
        UserControl.Refresh
    End If
End Sub

'----------------------------------------------------
'过程说明:绘制控件
'----------------------------------------------------
Private Sub UserControl_Paint()
    Dim hTheme As Long
    Dim rcDraw As RECT
    Dim objCurrentPic As StdPicture
    Dim bmWidth As Long
    Dim bmHeight As Long
    Dim xpControlSize As SIZE

'绘制XP风格的按钮控件外观
    hTheme = OpenThemeData(0, StrPtr("Button"))
    If hTheme <> 0 Then
        GetThemePartSize hTheme, hdc, 1, m_nState, rcDraw, TS_TRUE, xpControlSize
        SetRect rcDraw, m_rcUserControl.Left, m_rcUserControl.Top, m_rcUserControl.Right, m_rcUserControl.Bottom
        DrawThemeBackground hTheme, hdc, 1, m_nState, rcDraw, rcDraw
        CloseThemeData hTheme
    End If

SetRect rcDraw, m_rcUserControl.Left + 3, m_rcUserControl.Top + 3, m_rcUserControl.Right - 3, m_rcUserControl.Bottom - 3
    '绘制控件焦点框
    If m_mvarHasFocus And m_blnFocus Then
        DrawFocusRect UserControl.hdc, rcDraw
    End If
    InflateRect rcDraw, -3, -3
    '绘制控件图片和文字
    If m_mvarPicture Is Nothing Then
        DrawText UserControl.hdc, m_mvarValue, lstrlen(m_mvarValue), rcDraw, DT_CENTER Or DT_VCENTER Or DT_SINGLELINE
    Else
        If (m_nState = 2 Or m_nState = 3) And (Not m_mvarHotPicture Is Nothing) Then '如果控件状态为PBS_HOT或PBS_PRESSED且HOT图片不为空,则绘制HOT图片
            Set objCurrentPic = m_mvarHotPicture
        Else '否则,绘制普通状态图片
            Set objCurrentPic = m_mvarPicture
        End If
        bmWidth = UserControl.ScaleX(objCurrentPic.Width, vbHimetric, vbPixels)
        bmHeight = UserControl.ScaleY(objCurrentPic.Height, vbHimetric, vbPixels)
        Select Case m_mvarTextAlign
            Case vbAlignNone, vbAlignRight
            objCurrentPic.Render CLng(UserControl.hdc), CLng(rcDraw.Left), CLng(rcDraw.Top + (rcDraw.Bottom - rcDraw.Top - bmHeight) / 2), CLng(bmWidth), CLng(bmHeight), _
                                 0, objCurrentPic.Height, objCurrentPic.Width, -objCurrentPic.Height, ByVal 0&
            DrawText UserControl.hdc, m_mvarValue, lstrlen(m_mvarValue), rcDraw, DT_RIGHT Or DT_VCENTER Or DT_SINGLELINE
            Case vbAlignLeft
            objCurrentPic.Render CLng(UserControl.hdc), CLng(rcDraw.Right - bmWidth), CLng(rcDraw.Top + (rcDraw.Bottom - rcDraw.Top - bmHeight) / 2), CLng(bmWidth), CLng(bmHeight), _
                                 0, objCurrentPic.Height, objCurrentPic.Width, -objCurrentPic.Height, ByVal 0&
            DrawText UserControl.hdc, m_mvarValue, lstrlen(m_mvarValue), rcDraw, DT_LEFT Or DT_VCENTER Or DT_SINGLELINE
            Case vbAlignTop
            objCurrentPic.Render CLng(UserControl.hdc), CLng(rcDraw.Left + (rcDraw.Right - rcDraw.Left - bmWidth) / 2), CLng(rcDraw.Bottom - bmHeight), CLng(bmWidth), CLng(bmHeight), _
                                 0, objCurrentPic.Height, objCurrentPic.Width, -objCurrentPic.Height, ByVal 0&
            DrawText UserControl.hdc, m_mvarValue, lstrlen(m_mvarValue), rcDraw, DT_CENTER Or DT_TOP Or DT_SINGLELINE
            Case vbAlignBottom
            objCurrentPic.Render CLng(UserControl.hdc), CLng(rcDraw.Left + (rcDraw.Right - rcDraw.Left - bmWidth) / 2), CLng(rcDraw.Top), CLng(bmWidth), CLng(bmHeight), _
                                 0, objCurrentPic.Height, objCurrentPic.Width, -objCurrentPic.Height, ByVal 0&
            DrawText UserControl.hdc, m_mvarValue, lstrlen(m_mvarValue), rcDraw, DT_CENTER Or DT_BOTTOM Or DT_SINGLELINE
        End Select
    End If
End Sub

'----------------------------------------------------
'过程说明:读取控件定义的用户属性
'----------------------------------------------------
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
    Me.Enabled = PropBag.ReadProperty("Enabled", True)
    UserControl.ForeColor = PropBag.ReadProperty("ForeColor", Ambient.ForeColor)
    UserControl.BackColor = PropBag.ReadProperty("BackColor", Ambient.BackColor)
    Set UserControl.Font = PropBag.ReadProperty("Font", Ambient.Font)
    Set m_mvarPicture = PropBag.ReadProperty("Picture", Nothing)
    Set m_mvarHotPicture = PropBag.ReadProperty("HotPicture", Nothing)
    m_mvarValue = PropBag.ReadProperty("Value", "")
    m_mvarTextAlign = PropBag.ReadProperty("TextAlign", 0)
    m_mvarHasFocus = PropBag.ReadProperty("HasFocus", False)
End Sub

'----------------------------------------------------
'过程说明:保存控件定义的用户属性
'----------------------------------------------------
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
    Call PropBag.WriteProperty("Enabled", UserControl.Enabled, True)
    Call PropBag.WriteProperty("ForeColor", UserControl.ForeColor, Ambient.ForeColor)
    Call PropBag.WriteProperty("BackColor", UserControl.BackColor, Ambient.BackColor)
    Call PropBag.WriteProperty("Font", UserControl.Font, Ambient.Font)
    Call PropBag.WriteProperty("Picture", m_mvarPicture, Nothing)
    Call PropBag.WriteProperty("HotPicture", m_mvarHotPicture, Nothing)
    Call PropBag.WriteProperty("Value", m_mvarValue, "")
    Call PropBag.WriteProperty("TextAlign", m_mvarTextAlign, 0)
    Call PropBag.WriteProperty("HasFocus", m_mvarHasFocus, False)
End Sub

'----------------------------------------------------
'过程说明:控件焦点处理
Private Sub UserControl_GotFocus()
    m_blnFocus = True
    m_nState = 5
    UserControl.Refresh
End Sub
Private Sub UserControl_LostFocus()
    m_blnFocus = False
    m_nState = 1
    UserControl.Refresh
End Sub

'----------------------------------------------------
'属性说明:获得或设置控件的Enabled属性
'----------------------------------------------------
Public Property Get Enabled() As Boolean
    Enabled = UserControl.Enabled
End Property
Public Property Let Enabled(ByVal New_Value As Boolean)
    UserControl.Enabled = New_Value
    UserControl.PropertyChanged "Enabeld"
    m_nState = IIf(New_Value, 1, 4) '如果Enabled,控件状态则为PBS_NORMAL,否则为PBS_DISABLED
    UserControl.Refresh
End Property

'----------------------------------------------------
'属性说明:获得或设置控件的文字颜色
'----------------------------------------------------
Public Property Get ForeColor() As OLE_COLOR
    ForeColor = UserControl.ForeColor
End Property
Public Property Let ForeColor(ByVal New_Value As OLE_COLOR)
    UserControl.ForeColor = New_Value
    UserControl.PropertyChanged "ForeColor"
    UserControl.Refresh
End Property

'----------------------------------------------------
'属性说明:获得或设置控件的背景颜色(作用于控件的边缘区域)
'----------------------------------------------------
Public Property Get BackColor() As OLE_COLOR
    BackColor = UserControl.BackColor
End Property
Public Property Let BackColor(ByVal New_Value As OLE_COLOR)
    UserControl.BackColor = New_Value
    UserControl.PropertyChanged "BackColor"
    UserControl.Refresh
End Property

'----------------------------------------------------
'属性说明:获得或设置控件的字体
'----------------------------------------------------
Public Property Get Font() As StdFont
    Set Font = UserControl.Font
End Property
Public Property Set Font(ByRef New_Value As StdFont)
    Set UserControl.Font = New_Value
    UserControl.PropertyChanged "Font"
    UserControl.Refresh
End Property

'----------------------------------------------------
'属性说明:获得或设置控件背景图片
'----------------------------------------------------
Public Property Get Picture() As StdPicture
    Set Picture = m_mvarPicture
End Property
Public Property Set Picture(ByRef New_Value As StdPicture)
    Set m_mvarPicture = New_Value
    UserControl.PropertyChanged "Picture"
    UserControl.Refresh
End Property

'----------------------------------------------------
'属性说明:获得或设置控件的热点图片
'----------------------------------------------------
Public Property Get HotPicture() As StdPicture
    Set HotPicture = m_mvarHotPicture
End Property
Public Property Set HotPicture(ByRef New_Value As StdPicture)
    Set m_mvarHotPicture = New_Value
End Property

'----------------------------------------------------
'属性说明:获得或设置控件的值,此属性为控件默认属性
'----------------------------------------------------
Public Property Get Value() As String
    Value = m_mvarValue
End Property
Public Property Let Value(ByVal New_Value As String)
    m_mvarValue = New_Value
    UserControl.PropertyChanged "Value"
    UserControl.Refresh
End Property

'----------------------------------------------------
'属性说明:获得或设置控件文本对齐方式
'----------------------------------------------------
Public Property Get TextAlign() As AlignConstants
    TextAlign = m_mvarTextAlign
End Property
Public Property Let TextAlign(ByVal New_Value As AlignConstants)
    m_mvarTextAlign = New_Value
    UserControl.PropertyChanged "TextAlign"
    UserControl.Refresh
End Property

'----------------------------------------------------
'属性说明:获得或设置控件焦点属性
'----------------------------------------------------
Public Property Get HasFocus() As Boolean
    HasFocus = m_mvarHasFocus
End Property
Public Property Let HasFocus(ByVal New_Value As Boolean)
    m_mvarHasFocus = New_Value
    UserControl.PropertyChanged "HasFocus"
End Property

摘自:用VB实现带图片的XP风格的按钮控件


相关文章参考:

※谈用VB无窗口透明Usercontrol编写透明浮动按钮※

更多精彩>>>

用VB实现带图片的XP风格的按钮控件相关推荐

  1. wpf加载上千张图片部分图片不显示_开源WPF控件库MaterialDesignInXAML推荐

    (给DotNet加星标,提升.Net技能) 转自:沙漠之狐耶dotnet9.com/?p=2180 前言 介绍一个开源的C# WPF开源控件库,非常漂亮,重点是开源哦 WPF做桌面开发是很有优势的,除 ...

  2. qt 关闭窗口的槽函数_勇哥的VC++应用框架学习之QT(1) 信号槽、按钮控件、opencv读取显示图片...

    前言勇哥对于C语言,C++早些年有一些接触,这个系列贴子就记载一下C++应用框架的学习经验. 在写程序时,UI.基础类库.应用程序框架对于vc来讲,只能依靠MFC和QT了. 勇哥对MFC有很强的抵触, ...

  3. java+tableseg,多种功能集成,带Refresh刷新的tableV,Seg分段控件

    支持 IOS7+  详见Demo TestSegmentAndRefreshTableViewDemo 多种功能集成,带Refresh刷新的tableV,Seg分段控件,加载提示toast ##使用到 ...

  4. 图片缩放库 Photoview 和 Gif 控件 GifView 的使用

    课程背景: 在开发中,图片的缩放双击缩放和双击缩小也很重要,可以给用户提供更好的图片浏览体验.有些图片浏览还会涉及到 Gif 动画的播放.通过本课程,你将会学习到图片的缩放处理库和 Gif 播放组件的 ...

  5. VB高效导入Excel2003和Excel2007文件到MSHFlexGrid控件显示

    1.VB高效导入Excel2003和Excel2007文件到MSHFlexGrid控件显示 2.以前也有Excel导入通用功能,但速度有些慢一会把两种实现方式都提供出为参考对比. 一.原通用导入exc ...

  6. 在access窗体中加图片_Access实战:一种不用按钮控件就能控制子窗体联动的方法...

    近来宇哥潜心研究Access的设计,多有心得,在此共享一二.Access窗体若要进行控制,是需要通过按钮控件的,我经过自己探索,发现了一种更加简单的方法,也就是不用控件,通过直接点击窗体已有的表格,就 ...

  7. android富文本图片自适应,Android 图片混排富文本编辑器控件

    一.一个Android 图片混排富文本编辑器控件(仿兴趣部落) 1.1 图片混排富文本控件 是一种图片和文字混合在一起的控件,文本之间可以插入图片,类似于网页的排版样式. 1.2 该控件主要是仿兴趣部 ...

  8. Android 图片混排富文本编辑器控件

    概述 一个Android 图片混排富文本编辑器控件(仿兴趣部落) 详细 代码下载:http://www.demodashi.com/demo/12032.html 一.一个Android 图片混排富文 ...

  9. 做VB的,经常注册和反注册OCX控件和DLL链

    做VB的,经常注册和反注册OCX控件和DLL链 但是,每次都要 "开始"--"运行" --"regsvr32 C:\********\******.o ...

最新文章

  1. 浅谈 nagios监控配置
  2. 冒泡排序 java_Java中的冒泡排序
  3. PDF怎么转换成Word,PDF转Word的方法
  4. 一句SQL随机查询ACCESS中的几条记录
  5. 如何查询一个进程下面的线程数(进程和线程区别)
  6. Android学习按键事件监听与Command模式
  7. 什么是倾斜45度的火山图?
  8. linux gtk python,python-Linux上具有pygtk(gtk.gdk)的桌面/根窗口上的键盘/鼠标事件
  9. 去中心化存储项目Sia计划于2月初启动Sia基金会
  10. Linux下 FFmpeg 编译安装
  11. 一步一步SharePoint 2007之二十二:完美解决实现Form认证后无法再用SharePoint Designer编辑网站的问题...
  12. 阿里云新征程:通往智能之路
  13. 可信开发技术专家---阿里云诚聘
  14. 交换基础之生成树协议
  15. 计算机派位录取,北京幼升小多校划片电脑派位是什么意思
  16. aid learning如何换源
  17. 华南理工网络教育计算机平时作业,2017年华南理工大学网络教育计算机应用基础平时作业...
  18. doe报告模板_DMAIC六西格玛项目报告模板.ppt
  19. 微软OpenPAI平台搭建指南
  20. Java(详解) 1011 A+B 和 C (15 分)

热门文章

  1. AMD 证实停止向中国提供 x86 新技术授权!
  2. 让开发者 so easy 的一站式服务到底存不存在?
  3. iPhone 的黄金时代已结束!
  4. 苹果高通“情变”祸及所有中国 iPhone 用户!
  5. 今天,GitHub 挂了!
  6. java字段描述符_Java 的方法签名与字段类型表示-[Ljava.lang.String;
  7. 【JVM原理探索,Java组件化架构实践
  8. 看完豁然开朗!美团java面试难吗
  9. 第 24 章 状态模式
  10. mysql 实时恢复_MySQL实时在线备份恢复方案:Replication+LVM Snapsho