分类
vb控件性能大扩展:如何用API函数更改VB自带的TooBar的背景颜色和字体颜色???!!!
我现在想为我的一个小软件做一个好看一点的界面,但没有找到好的界面控件(主要是按钮控件或标签控件),我又不想自己写控件,虽然写一个这样的控件很简单,但花时间,而且还不稳定。
我对按钮控件要求如下:
1.能改变字体颜色.
2.能有Picture属性
3. HotPicture属性(HotPicture指MouseMove时的图片)
4. MouseDownPicture属性(HotPicture指MouseDown时的图片)
5. 控件很成熟,稳定,最好是非常流行的,出自大公司的产品。
6. 控件最好是免费的(不是我舍不得出钱,主要是为了几十块钱去写汇款单非常麻烦)
我在网上找了很久,都没有找到合适的。我最后就定用VB自带的TooBar实现以上的功能,以上功能基本上可以达到,但没办法改变TooBar的背景颜色和字体颜色,因为TooBar的背景颜色是灰色的非常难看,不知哪位大侠能用用API函数更改VB自带的TooBar的背景颜色和字体颜色。
请多多指教。万分感谢。
请高手前来指教。
完全可以用VB自带的按钮做一个自己的按钮控件来做.
用ActiveBar吧.
To ansionhuang(毛毛雨-我是外星人,所以我什么都不知道) :
ActiveBar太庞大了,也太复杂了,而且我也不知道哪个版本比较好用。
如果能改变TooBar的背景颜色和字体颜色,则TooBar可作为按钮和标签来使用,也可以作为一款极好的界面控件来使用。
不怕危险可以试试看子类
To kmzs(.:RNPA:.山水岿濛) :
使用子类太危险了, 我只是希望能用APITooBar的背景颜色和字体颜色改变就完全达到我的目的了。
ding ....
是呀!同感!半年前曾为这个问题在网上专门搜索过,无果!
现在,虽没这个需要,但还是想知道,到底有没有成功的先例!
支持。。。。
希望各位高手鼎力相助.如果能改变TooBar的背景颜色和字体颜色,则TooBar可作为按钮和标签来使用,也可以作为一款极好的界面控件来使用,这将极大的扩展TooBar的功能.
http://www.5ivb.net/down/54/5ivb_2071.asp
看看这个VB编控件怎样,有源码的。
To homezj(小吉):
谢谢你的帮助。我现在正在www.google.com上搜索相关的资料,希望能找到突破点。我是按如下方式进行逐步过滤搜索的:Toolbar API VB BackColor。
我找到几条和我的问题相同的国际网页,有空你可以看一看:
http://www.codeguru.com/forum/printthread.php?t=309893
其中有一段代码值得关注:
Below is the area where the I just can't change color and where if I change the back color of the imagelist it won't make any difference to the imagelists color :
' Mark added this in to change the color of the cool bar and menu bar 9/8/04
Private Declare Function ImageList_SetBkColor Lib "COMCTL32" (ByVal hImageList As Long, ByVal clrBk As Long) As Long
For intcount = 0 To TTDocViewer.Annotations.Tools.Count - 1
hdlImageList = imgList.hImageList
lColor = ImageList_SetBkColor(hdlImageList, RGB(9, 3, 2))
ImgList.ListImages.Add intcount + 1, , TTDocViewer.Annotations.Tools.Item(intcount).Picture
lColor = ImageList_SetBkColor(hdlImageList, RGB(9, 3, 2))
' imgList.BackColor = vbYellow
Next
对呀!这个论坛不错!你要的代码,好象也有:
http://www.codeguru.com/forum/attachment.php?attachmentid=7783
无控件改变标准ToolBar的背景色。
你下载看看,我还没细看,你有成果了,别私藏就行啦!
Mark!
哎!今晚总算有空,看一下这个类模块。
这一次接触用SubClass对CommControl进行消息处理,本就有点神秘感,可代码中偏又弄了个内套汇编,更有些头痛,一时摸不清其具体路数了。
忙了半天,好不容易才为该类加上了背景色属性。
下步打算
1、去掉不知所云的汇编,感觉那汇编没太多必要,似乎就是为了给子类过程多加三个参数,便于完全在类中解决,放在标准模块中,应该也不算失败吧!
2、看看为什么作者把按钮文本给注释掉了,没文字,也不太好呀。
不知这两项能否实现,哪位有兴趣,也弄一弄!
下载链接:
http://www.codeguru.com/forum/attachment.php?attachmentid=7783
ToolBar本身支持用户自定义界面——使用Custom Draw
只不过VB封装的太差,没有提供Custom Draw功能
而且在VB中拦截消息只能用子类,非常麻烦
MSDN:
Customizing a Control's Appearance Using Custom Draw
--------------------------------------------------------------------------------
Custom Draw is not a common control; it is a service that many common controls provide. Custom Draw services allow an application greater flexibility in customizing a control's appearance. Your application can harness custom draw notifications to easily change the font used to display items or manually draw an item without having to do a full-blown owner draw.
About Custom Draw
Custom Draw With List-View and Tree-View Controls
Using Custom Draw
Related Topics
About Custom Draw
This section contains general information about custom draw functionality and provides a conceptual overview of how an application can support custom draw.
Currently, the following controls support custom draw functionality:
Header controls
List-view controls
Rebar controls
Toolbar controls
ToolTip controls
Trackbar controls
Tree-view controls
Note Custom draw is implemented in version 4.70 and later of Comctl32.dll for all the controls previously listed. Custom draw is also supported for button controls if you are running Windows XP and have an application manifest to ensure that Comctl32.dll version 6 is available.
About Custom Draw Notification Messages
All common controls that support custom draw send NM_CUSTOMDRAW notification messages at specific points during drawing operations. These notifications describe drawing operations that apply to the entire control as well as drawing operations specific to items within the control. Like many notification messages, NM_CUSTOMDRAW notifications are sent as WM_NOTIFY messages.
The lParam parameter of a custom draw notification message will be the address of an NMCUSTOMDRAW structure or a control-specific structure that contains an NMCUSTOMDRAW structure as its first member. The following table illustrates the relationship between the controls and the structures they use.
Structure Used by
NMCUSTOMDRAW Rebar, trackbar, and header controls
NMLVCUSTOMDRAW List-view controls
NMTBCUSTOMDRAW Toolbar controls
NMTTCUSTOMDRAW ToolTip controls
NMTVCUSTOMDRAW Tree-view controls
Paint Cycles, Drawing Stages, and Notification Messages
Like all Microsoft® Windows® applications, common controls periodically paint and erase themselves based on messages received from the system or other applications. The process of a control painting or erasing itself is called a paint cycle. Controls that support custom draw send NM_CUSTOMDRAW notification messages periodically through each paint cycle. This notification message is accompanied by an NMCUSTOMDRAW structure or another structure that contains an NMCUSTOMDRAW structure as its first member.
One piece of information that the NMCUSTOMDRAW structure contains is the current stage of the paint cycle. This is referred to as the draw stage and is represented by the value in the structure's dwDrawStage member. A control informs its parent about four basic draw stages. These basic, or global, draw stages are represented in the structure by the following flag values (defined in Commctrl.h).
Global draw stage values Description
CDDS_PREPAINT Before the paint cycle begins.
CDDS_POSTPAINT After the paint cycle is complete.
CDDS_PREERASE Before the erase cycle begins.
CDDS_POSTERASE After the erase cycle is complete.
Each of the preceding values can be combined with the CDDS_ITEM flag to specify draw stages specific to items. For convenience, Commctrl.h contains the following item-specific values.
Item-specific draw stage values Description
CDDS_ITEMPREPAINT Before an item is drawn.
CDDS_ITEMPOSTPAINT After an item has been drawn.
CDDS_ITEMPREERASE Before an item is erased.
CDDS_ITEMPOSTERASE After an item has been erased.
CDDS_SUBITEM Shell and Common Controls Versions 4.71. Flag combined with CDDS_ITEMPREPAINT or CDDS_ITEMPOSTPAINT if a subitem is being drawn. This will only be set if CDRF_NOTIFYITEMDRAW is returned from CDDS_PREPAINT.
Your application must process the NM_CUSTOMDRAW notification message and then return a specific value that informs the control what it must do. See the following sections for more information about these return values.
Taking Advantage of Custom Draw Services
The key to harnessing custom draw functionality is in responding to the NM_CUSTOMDRAW notification messages that a control sends. The return values your application sends in response to these notifications determine the control's behavior for that paint cycle.
This section contains information about how your application can use NM_CUSTOMDRAW notification return values to determine the control's behavior.
Details are broken into the following topics:
Responding to the prepaint notification
Requesting item-specific notifications
Drawing the item yourself
Changing fonts and colors
Responding to the prepaint notification
At the beginning of each paint cycle, the control sends the NM_CUSTOMDRAW notification message, specifying the CDDS_PREPAINT value in the dwDrawStage member of the accompanying NMCUSTOMDRAW structure. The value that your application returns to this first notification dictates how and when the control sends subsequent custom draw notifications for the rest of that paint cycle. Your application can return a combination of the following flags in response to the first notification.
Return value Effect
CDRF_DODEFAULT The control will draw itself. It will not send additional NM_CUSTOMDRAW notifications for this paint cycle. This flag cannot be used with any other flag.
CDRF_NOTIFYITEMDRAW The control will notify the parent of any item-specific drawing operations. It will send NM_CUSTOMDRAW notification messages before and after it draws items.
CDRF_NOTIFYPOSTPAINT The control will send an NM_CUSTOMDRAW notification when the painting cycle for the entire control is complete.
CDRF_SKIPDEFAULT The control will not perform any painting at all.
Requesting item-specific notifications
If your application returns CDRF_NOTIFYITEMDRAW to the initial prepaint custom draw notification, the control will send notifications for each item it draws during that paint cycle. These item-specific notifications will have the CDDS_ITEMPREPAINT value in the dwDrawStage member of the accompanying NMCUSTOMDRAW structure. You can request that the control send another notification when it is finished drawing the item by returning CDRF_NOTIFYPOSTPAINT to these item-specific notifications. Otherwise, return CDRF_DODEFAULT and the control will not notify the parent window until it starts to draw the next item.
Drawing the item yourself
If your application draws the entire item, return CDRF_SKIPDEFAULT. This allows the control to skip items that it does not need to draw, thereby decreasing system overhead. Keep in mind that returning this value means the control will not draw any portion of the item.
To homezj(小吉) :
我也在网上找到一些有用的东西,我这几天很忙,等我忙完后我就把这些东西整理出来供大家学习和讨论。
To zyl910(910:分儿,我又来了!) :
谢谢你的指点,现在放寒假了吧,大学里的学习和生活还好吧?
是呀!子类处理真的很烦,不好调试,不能出错,一错就退出。加上要自已定位绘按钮,总觉得自找苦吃。
昨天基本改完了,前面说到的两条也都实现了,效果还不错。就是遇到一个难题:
带菜单的按钮有点生硬,因为我不知道怎么才能获取右边小按钮按下的状态,CSDN中也没说明,Bebug一看,
鼠标移到按钮上收到CDIS_HOT状态;
鼠标点击大按钮得到CDIS_HOT or CDIS_SELECTED状态;
鼠标点击小按钮得到竟然还是CDIS_HOT状态!
困惑中...
还有一处小小不适:
设置类背景色,按钮样式,文本色等属性后,需重绘工具栏,但却不知如何通知让这位老先生重绘!发送WM_Paint消息、InvalidateRect、UpdateWindow统统上阵,都无效。还好在VB中用最简单的Toolbar1.Refresh,是可以办法的,但还没弄清VB是怎么做的。
up
大家新年好,给大家拜个晚年。
经过这一段时间的了解和测试,我还是没有找到好的解决办法,用SubClass非常麻烦,也很复杂,也很危险。我准备参照SmarkMenuXP的形式自己写一个ToolBar.
现在我把最近一段时间收集的一些资料贴出来,供大家学习和参考。另外,要特别感谢小吉的参与和帮助。
http://www.visualbasicforum.com/showthread.php?t=67007
http://planetsourcecode.com/vb/scripts/ShowCode.asp?txtCodeId=5839&lngWId=1
http://vbnet.mvps.org/index.html?code/comctl/toolbarinstatbar.htm
http://www.elitevb.com/content/01,0100,01/
http://www.elitevb.com/content/01,0078,01/
http://www.elitevb.com/search.aspx
http://www.elitevb.com/search.aspx/1
在google中搜索 “How to change Toolbar Backcolor in VB ”
漂亮的toolbar_5ivb_898393.zip
高级ToolBar控件源码_5ivb_775098.rar
HookMenu_116741711202003.zip
vsnetmenu.rar
wh_Menu.rar
xpcontrols.rar
以上压缩文件大家可以在网上搜索即可。
写错了是 SmartMenuXP
ToolBar的SubClass很有趣,节前我就已改好了一个这样的类模块,可定制5种按钮样式,或改变背景、前景、文本的颜色,甚至可以为ToolBar换上背景图。
其实ToolBar提供了一个CustomDraw功能,MS为你已搭好了ToolBar的框架,只是ToolBar的模样交给你自己绘,很简单地,就可以用任意你想要的模样,使用ToolBar的所有功能,这比自己做ToolBar是不是更容易更方便?
这个类代码有些多(我写的功能多了点),可能要4-5贴才能贴完。我就慢慢来,别见怪呀^_^
--------------------------------------------------------
'测试窗体中的代码:需有个ToolBar,最好有ImageList。
Option Explicit
Private Sub Command1_Click()
Dim i As Long
With oTbr
Randomize
'If .BackPicture = "" Then
' .BackPicture = "e:12.jpg"
'Else
' .BackPicture = ""
'End If
.BorderColor = vbBlue '只有BorderStyle大于3时才有效
.BackColor = Rnd * (2 ^ 24)
.TextColor = Rnd * (2 ^ 24)
.TextHiColor = Rnd * (2 ^ 24)
i = .BorderStyle + 1
If i > 4 Then i = 0
.BorderStyle = i '取值范围0-4
End With
End Sub
Private Sub Command2_Click()
If oTbr Is Nothing Then
Set oTbr = New cToolbar
With oTbr
.BindToolBar Toolbar1.hWnd
End With
Command2.Caption = "取消样式"
Command1.Enabled = True
Else
Set oTbr = Nothing
Toolbar1.Refresh
Command2.Caption = "加载样式"
Command1.Enabled = False
End If
End Sub
Private Sub Form_Load()
Command1.Caption = "随机变样"
Command2.Caption = "加载样式"
Command2.Enabled = True
Command1.Enabled = False
End Sub
Private Sub Form_Unload(Cancel As Integer)
Set oTbr = Nothing
End Sub
--------------------------------------------------
--------------------------------------------------
'标准模块中的代码:
Option Explicit
Public oTbr As cToolbar
Public OldWindowProc As Long
Private Const WM_NOTIFY As Long = &H4E
Private Const WM_LBUTTONDOWN = &H201
Private Const WM_LBUTTONUP = &H202
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Function TBSubClass(ByVal hWnd As Long, ByVal Msg As Long, ByVal wp As Long, ByVal lp As Long) As Long
Dim ProcOK As Long
Static MouseDown As Boolean
If Msg = WM_NOTIFY Then
ProcOK = oTbr.MsgProc(lp, MouseDown)
ElseIf Msg = WM_LBUTTONDOWN Then
MouseDown = True
ElseIf Msg = WM_LBUTTONUP Then
MouseDown = False
End If
If ProcOK Then
TBSubClass = ProcOK
Else
TBSubClass = CallWindowProc(OldWindowProc, hWnd, Msg, wp, lp)
End If
End Function
----------------------------------------------------------------
----------------------------------------------------
'类模块中的代码:类名cToolbar
Option Explicit
Private Const CDDS_ITEM As Long = &H10000
Private Const CDDS_PREPAINT As Long = &H1
Private Const CDDS_ITEMPREPAINT As Long = (CDDS_ITEM Or CDDS_PREPAINT)
Private Const CDRF_SKIPDEFAULT As Long = &H4
Private Const CDRF_NOTIFYITEMDRAW As Long = &H20
Private Const CDIS_CHECKED As Long = &H8
Private Const CDIS_DISABLED As Long = &H4
Private Const CDIS_HOT As Long = &H40
Private Const CDIS_SELECTED As Long = &H1
Private Const GWL_WNDPROC = (-4)
Private Const WM_USER As Long = &H400
Private Const TB_GETBUTTONTEXTA As Long = (WM_USER + 45)
Private Const TB_GETIMAGELIST As Long = (WM_USER + 49)
Private Const TB_GETHOTIMAGELIST = (WM_USER + 53)
Private Const TB_GETDISABLEDIMAGELIST = (WM_USER + 55)
Private Const TB_GETBITMAP As Long = (WM_USER + 44)
Private Const TB_COMMANDTOINDEX As Long = (WM_USER + 25)
Private Const TB_GETBUTTON As Long = (WM_USER + 23)
Private Const TBSTYLE_LIST As Long = &H1000
Private Const TBSTYLE_SEP As Long = &H1
Private Const TBSTYLE_DROPDOWN As Long = &H8
Private Const ILD_NORMAL As Long = &H0
Private Const DST_TEXT = &H1&
Private Const DST_ICON As Long = &H3
Private Const DSS_DISABLED = &H20&
Private Const CLR_NONE As Long = &HFFFFFFFF
Private Const GWL_STYLE As Long = -16
Private Const PS_SOLID As Long = 0
Private Const TA_LEFT = 0
Private Const TA_RIGHT = 2
Private Const TA_CENTER = 6
Private Const BF_FLAT = &H4000
Private Const BF_BOTTOM = &H8
Private Const BF_LEFT = &H1
Private Const BF_RIGHT = &H4
Private Const BF_TOP = &H2
Private Const BF_RECT = (BF_LEFT Or BF_TOP Or BF_RIGHT Or BF_BOTTOM)
Private Const BDR_RAISEDOUTER = &H1
Private Const BDR_RAISEDINNER = &H4
Private Const BDR_SUNKENINNER = &H8
Private Const BDR_SUNKENOUTER = &H2
Private Const BDR_OUTER = &H3
Private Const EDGE_ETCHED = (BDR_SUNKENOUTER Or BDR_RAISEDINNER)
Private Const EDGE_RAISED = (BDR_RAISEDOUTER Or BDR_RAISEDINNER)
Private Const EDGE_SUNKEN = (BDR_SUNKENOUTER Or BDR_SUNKENINNER)
Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Type ICONINFO
fIcon As Long
xHotspot As Long
yHotspot As Long
hbmMask As Long
hbmColor As Long
End Type
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type POINTL
X As Long
Y As Long
End Type
Private Type Size
cx As Long
cy As Long
End Type
Private Type LOGFONT
lfHeight As Long
lfWidth As Long
lfEscapement As Long
lfOrientation As Long
lfWeight As Long
lfItalic As Byte
lfUnderline As Byte
lfStrikeOut As Byte
lfCharSet As Byte
lfOutPrecision As Byte
lfClipPrecision As Byte
lfQuality As Byte
lfPitchAndFamily As Byte
lfFaceName As String * 32
End Type
Private Type TBBUTTON
iBitmap As Long
idCommand As Long
fsState As Byte
fsStyle As Byte
bReserved(1) As Byte
dwData As Long
iString As Long
End Type
Private Type MemHdc
hdc As Long
Bmp As Long
obm As Long
End Type
Private Type NMHDR
hwndFrom As Long
idfrom As Long
code As Long
End Type
Private Type NMCUSTOMDRAW
hdr As NMHDR
dwDrawStage As Long
hdc As Long
rc As RECT
dwItemSpec As Long
uItemState As Long
lItemlParam As Long
End Type
Private Type NMTBCUSTOMDRAW
nmcd As NMCUSTOMDRAW
hbrMonoDither As Long
hbrLines As Long
hpenLines As Long
clrText As Long
clrMark As Long
clrTextHighlight As Long
clrBtnFace As Long
clrBtnHighlight As Long
clrHighlightHotTrack As Long
rcText As RECT
nStringBkMode As Long
nHLStringBkMode As Long
End Type
Private m_hWnd As Long
Private m_lngBackColor As Long
Private m_lngBrdStyle As Long
Private m_lngTextColor As Long
Private m_lngTextHiColor As Long
Private m_strBkPicture As String
Private m_lngBrdColor As Long
Private mpicBk As StdPicture
Private mlngImgList As Long
Private mdcWhite As MemHdc
Private mlngHotImgList As Long
Private mlngDsbImgList As Long
Private mlngBtnHiAlpha As Long
Private mlngBtnDownAlpha As Long
Private mlngIconWidth As Long
Private mlngIconHeight As Long
Private Font As LOGFONT
'消息与管理类
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function ShowWindow Lib "user32" Alias "ShowWindowAsync" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
'GDI对象类
Private Declare Function CreateSolidBrush Lib "gdi32.dll" (ByVal crColor As Long) As Long
Private Declare Function CreatePen Lib "gdi32.dll" (ByVal nPenStyle As Long, ByVal nWidth As Long, ByVal crColor As Long) As Long
Private Declare Function CreateFontIndirect Lib "gdi32" Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Private Declare Function DestroyIcon Lib "user32.dll" (ByVal hIcon As Long) As Long
Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
Private Declare Function GetIconInfo Lib "user32" (ByVal hIcon As Long, piconinfo As ICONINFO) As Long
Private Declare Function GetObj Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function CreatePatternBrush Lib "gdi32" (ByVal hBitmap As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hdc As Long) As Long
'区域、绘图、文本类
Private Declare Function GetClientRect Lib "user32.dll" (ByVal hWnd As Long, lpRect As RECT) As Long
Private Declare Function SetRect Lib "user32.dll" (lpRect As RECT, ByVal X1 As Long, ByVal Y1 As Long, ByVal X2 As Long, ByVal Y2 As Long) As Long
Private Declare Function FillRect Lib "user32.dll" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
Private Declare Function Polygon Lib "gdi32" (ByVal hdc As Long, lpPoint As POINTL, ByVal nCount As Long) As Long
Private Declare Function DrawEdge Lib "user32" (ByVal hdc As Long, qrc As RECT, ByVal edge As Long, ByVal grfFlags As Long) As Long
Private Declare Function FrameRect Lib "user32" (ByVal hdc As Long, lpRect As RECT, ByVal hBrush As Long) As Long
Private Declare Function MoveToEx Lib "gdi32.dll" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, lpPoint As Any) As Long
Private Declare Function LineTo Lib "gdi32.dll" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As String) As Long
Private Declare Function GetTextExtentPoint32 Lib "gdi32" Alias "GetTextExtentPoint32A" (ByVal hdc As Long, ByVal lpsz As String, ByVal cbString As Long, lpSize As Size) As Long
Private Declare Function SetTextAlign Lib "gdi32" (ByVal hdc As Long, ByVal wFlags As Long) As Long
Private Declare Function SetBkMode Lib "gdi32" (ByVal hdc As Long, ByVal nBkMode As Long) As Long
Private Declare Function SetTextColor Lib "gdi32.dll" (ByVal hdc As Long, ByVal crColor As Long) As Long
Private Declare Function TextOut Lib "gdi32" Alias "TextOutA" (ByVal hdc As Long, ByVal X As Long, ByVal Y As Long, ByVal lpString As String, ByVal nCount As Long) As Long
Private Declare Function DrawState Lib "user32.dll" Alias "DrawStateA" (ByVal hdc As Long, ByVal hBrush As Long, ByVal lpDrawStateProc As Long, ByVal hIco As Long, ByVal wParam As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal n3 As Long, ByVal n4 As Long, ByVal un As Long) As Long
Private Declare Function AlphaBlend Lib "msimg32.dll" (ByVal hdcDest As Long, ByVal nXOriginDest As Long, ByVal nYOriginDest As Long, ByVal nWidthDest As Long, ByVal hHeightDest As Long, ByVal hdcSrc As Long, ByVal nXOriginSrc As Long, ByVal nYOriginSrc As Long, ByVal nWidthSrc As Long, ByVal nHeightSrc As Long, ByVal blendFunction As Long) As Long
'ImageList类
Private Declare Function ImageList_Draw Lib "comctl32.dll" (ByVal himl As Long, ByVal i As Long, ByVal hdcDst As Long, ByVal X As Long, ByVal Y As Long, ByVal fStyle As Long) As Long
Private Declare Function ImageList_GetBkColor Lib "comctl32.dll" (ByVal himl As Long) As Long
Private Declare Function ImageList_SetBkColor Lib "comctl32.dll" (ByVal himl As Long, ByVal clrBk As Long) As Long
Private Declare Function ImageList_GetIcon Lib "comctl32.dll" (ByVal himl As Long, ByVal i As Long, ByVal flags As Long) As Long
Friend Property Let BorderColor(ByVal vData As Long)
If m_lngBrdColor <> vData Then
m_lngBrdColor = vData
If m_lngBrdStyle > 3 Then Refresh
End If
End Property
Friend Property Get BorderColor() As Long
BorderColor = m_lngBrdColor
End Property
Friend Property Let BackPicture(ByVal vData As String)
If vData <> "" And Dir(vData) <> "" Then
If LCase(m_strBkPicture) <> LCase(vData) Then
m_strBkPicture = vData
Set mpicBk = LoadPicture(m_strBkPicture)
Refresh
End If
Else
Set mpicBk = Nothing
m_strBkPicture = ""
End If
End Property
Friend Property Get BackPicture() As String
BackPicture = m_strBkPicture
End Property
Friend Property Let FontUnderline(ByVal vData As Boolean)
Dim i As Long
i = IIf(vData, 1, 0)
If Font.lfUnderline <> i Then
Font.lfUnderline = i
Refresh
End If
End Property
Friend Property Get FontUnderline() As Boolean
FontUnderline = (Font.lfUnderline = 1)
End Property
Friend Property Let FontItalic(ByVal vData As Boolean)
Dim i As Long
i = IIf(vData, 1, 0)
If Font.lfItalic <> i Then
Font.lfItalic = i
Refresh
End If
End Property
Friend Property Get FontItalic() As Boolean
FontItalic = (Font.lfItalic = 1)
End Property
Friend Property Let FontBold(ByVal vData As Boolean)
Dim i As Long
i = IIf(vData, 700, 400)
If Font.lfWeight <> i Then
Font.lfWeight = i
Refresh
End If
End Property
Friend Property Get FontBold() As Boolean
FontBold = (Font.lfWeight = 700)
End Property
Friend Property Let FontSize(ByVal vData As Long)
If Font.lfHeight <> vData And vData >= 7 And vData <= 16 Then
Font.lfHeight = vData
Font.lfWidth = 0
Refresh
End If
End Property
Friend Property Get FontSize() As Long
FontSize = Font.lfHeight
End Property
Friend Property Let BorderStyle(ByVal vData As Long)
If m_lngBrdStyle <> vData Then
m_lngBrdStyle = vData
Refresh
End If
End Property
Friend Property Get BorderStyle() As Long
BorderStyle = m_lngBrdStyle
End Property
Friend Property Let TextHiColor(ByVal vData As Long)
m_lngTextHiColor = vData
End Property
Friend Property Get TextHiColor() As Long
TextHiColor = m_lngTextHiColor
End Property
Friend Property Let TextColor(ByVal vData As Long)
If m_lngTextColor <> vData Then
m_lngTextColor = vData
Refresh
End If
End Property
Friend Property Get TextColor() As Long
TextColor = m_lngTextColor
End Property
Friend Property Let BackColor(ByVal vData As Long)
If m_lngBackColor <> vData Then
m_lngBackColor = vData
If mpicBk Is Nothing Then Refresh
End If
End Property
Friend Property Get BackColor() As Long
BackColor = m_lngBackColor
End Property
Friend Sub BindToolBar(ByVal hWnd As Long)
If m_hWnd = 0 Then
m_hWnd = hWnd
If m_hWnd Then
OldWindowProc = GetWindowLong(m_hWnd, GWL_WNDPROC)
SetWindowLong m_hWnd, GWL_WNDPROC, AddressOf TBSubClass
End If
Refresh
End If
End Sub
Friend Sub Refresh()
If m_hWnd <> 0 Then
ShowWindow m_hWnd, 0
ShowWindow m_hWnd, 5
End If
End Sub
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 Sub Class_Initialize()
Dim rc As RECT, hBrush As Long, i As Long
m_lngTextColor = vbBlack
m_lngTextHiColor = vbRed
m_lngBackColor = &HD7E9EB
m_lngBrdColor = &H0
mlngBtnHiAlpha = 96
mlngBtnDownAlpha = 192
rc.Bottom = 128
rc.Right = 128
i = GetDC(0)
mdcWhite = NewMyHdc(i, rc.Right, rc.Bottom)
ReleaseDC 0, i
hBrush = CreateSolidBrush(vbWhite)
FillRect mdcWhite.hdc, rc, hBrush
DeleteObject hBrush
With Font
.lfCharSet = 1
.lfHeight = 12
.lfWeight = 400
End With
End Sub
Private Sub Class_Terminate()
SetWindowLong m_hWnd, GWL_WNDPROC, OldWindowProc
mdcWhite = DelMyHdc(mdcWhite)
Set mpicBk = Nothing
End Sub
Private Sub DrawPloy3(hdc As Long, rcDrop As RECT, Up As Boolean)
'画下拉菜单的小三角形
Dim ploy(2) As POINTL
Dim hBrush As Long, hOldBrush As Long
Dim hPen As Long, hOldPen As Long
With rcDrop
If Up Then
.Left = .Left - 1
.Right = .Right - 1
.Top = .Top - 1
.Bottom = .Bottom - 1
hBrush = CreateSolidBrush(m_lngTextHiColor)
hPen = CreatePen(PS_SOLID, 1, m_lngTextHiColor)
Else
hBrush = CreateSolidBrush(m_lngTextColor)
hPen = CreatePen(PS_SOLID, 1, m_lngTextColor)
End If
hOldPen = SelectObject(hdc, hPen)
hOldBrush = SelectObject(hdc, hBrush)
ploy(0).X = (.Left + .Right - 5) 2
ploy(0).Y = (.Top + .Bottom) 2
ploy(1).X = ploy(0).X + 4
ploy(1).Y = ploy(0).Y
ploy(2).X = ploy(0).X + 2
ploy(2).Y = ploy(0).Y + 2
End With
Polygon hdc, ploy(0), 3
SelectObject hdc, hOldPen
SelectObject hdc, hOldBrush
DeleteObject hPen
DeleteObject hBrush
End Sub
Private Sub GetIconSize(hIcon As Long)
'取得图像列表框图标的大小
Dim Bm As BITMAP, bi As ICONINFO
GetIconInfo hIcon, bi
GetObj bi.hbmColor, Len(Bm), Bm
DeleteObject bi.hbmColor
DeleteObject bi.hbmMask
mlngIconWidth = Bm.bmWidth
mlngIconHeight = Bm.bmHeight
End Sub
Private Sub DrawRect(hdc As Long, rc As RECT, State As Long, Optional IsDrop As Boolean)
Dim hPen As Long
If (State > 0 Or IsDrop) And m_lngBrdStyle > 3 Then
hPen = CreatePen(PS_SOLID, 1, m_lngBrdColor)
If IsDrop Then rc.Left = rc.Left - 1
FrameRect hdc, rc, hPen
If IsDrop Then rc.Left = rc.Left + 1
DeleteObject hPen
Exit Sub
End If
Select Case State
Case 0 '普通状态
Select Case m_lngBrdStyle
Case 1
If IsDrop Then DrawEdge hdc, rc, BDR_OUTER, BF_RECT Or BF_FLAT
Case 2
DrawEdge hdc, rc, BDR_RAISEDOUTER, BF_RECT
Case 3
DrawEdge hdc, rc, EDGE_RAISED, BF_RECT
End Select
Case 1 '高亮状态
Select Case m_lngBrdStyle
Case 0
DrawEdge hdc, rc, BDR_RAISEDINNER, BF_RECT
Case 1, 2, 3
DrawEdge hdc, rc, EDGE_RAISED, BF_RECT
End Select
Case 2 '按下状态
Select Case m_lngBrdStyle
Case 0
DrawEdge hdc, rc, BDR_SUNKENOUTER, BF_RECT
Case 1
DrawEdge hdc, rc, BDR_SUNKENINNER, BF_RECT
Case 2, 3
DrawEdge hdc, rc, EDGE_SUNKEN, BF_RECT
End Select
End Select
End Sub
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 Function NewMyHdc(dHdc As Long, w As Long, h As Long, Optional Bm As Long) As MemHdc
With NewMyHdc
.hdc = CreateCompatibleDC(dHdc)
If Bm = 0 Then
.Bmp = CreateCompatibleBitmap(dHdc, w, h)
Else
.Bmp = Bm
End If
.obm = SelectObject(.hdc, .Bmp)
End With
End Function
Private Function DelMyHdc(MyHdc As MemHdc, Optional nobmp As Boolean) As MemHdc
With MyHdc
If .hdc <> 0 Then
SelectObject .hdc, .obm
If nobmp = False Then DeleteObject .Bmp
DeleteDC .hdc
End If
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
总算贴完了,大家可把它看成是一个改变ToolBar样式的示例,希望能起到抛砖引玉的作用。
附:对于带下拉菜单的按钮,我用的方法有点笨,我不知道有没有什么相关消息,还望知情者指点!
我的美工不好,绘图手段很传统,不过根据本类的原理,相信会有朋友可做出更加炫丽的效果来。
To homezj(小吉):
非常感谢,我先下去测试一下你的代码,再上来讨论。
To homezj(小吉):
我已经测试了你的代码,非常棒,正是我所需要的效果,非常感谢,此贴再保留几天就结贴。
另外我从网上收藏了一个XP按钮的源代码,不知你们感不感兴趣,如果需要的话,我就贴上来。
嘿嘿,正是我要的东西!就是看不明白,能不能说说原理呀?
To starofvb(VB之星):
www.vbaccelerator.com上有关于SubClass的例子
我测试了,能有很多种效果,而且不用任何控件,太神奇了,我一直想要这种东西!
我也知道这是用SubClass的,但就是不知道对于ToolBar该怎么拦截消息,都处理哪些消息?
我注意了SubClass中只处理了WM_NOTIFY、WM_LBUTTONDOWN、WM_LBUTTONUP三个消息,这就够了?
为什么呀?怎么处理呀,我看了好困惑!
请高手解释一下呀,小吉说根据本类的原理可以自己改模样,我就是想知道原理!
关注@_@
将ToolBar改成一个功能强大的界面控件是非常有用的,因为它不需要第3方控件,毕竟第3方控件用起来实在是不放心。
To Begin2008(重头再来)
贴出来看看,这个类中按钮效果都是传统风格的,很希望有朋友能把它改成XP风格。
To starofvb(VB之星)
ToolBar、ListView、TreeView等控件都有Custom Draw功能,该功能当然是通过消息机制触发,其核心就是通过WM_NOTIFY消息,这个消息的lParam参数,就是指向一个NMHDR结构的地址,通过NMHDR结构,我们可得知产生消息的hwnd等信息,确定控件类型,并进一步决定整个结构的类型是什么,进而获得NMCUSTOMDRAW和NMTBCUSTOMDRAW结构,NMTBCUSTOMDRAW最前面就是NMCUSTOMDRAW,而NMCUSTOMDRAW最前面就是NMHDR,所以一个NMHDR、NMCUSTOMDRAW,NMCUSTOMDRAW实际上都是同一个地址lParam,只是需根据前面信息,最终确定整个结构的长度而已。
WM_LBUTTONDOWN、WM_LBUTTONUP消息本应与本类无关,只是ToolBar中带菜单的样式的按钮,我一时不知如何获取其Drap消息,所以被迫采用了判断鼠标动作的权宜之计,不知哪位能把这个改改。
DrawToolbarButton过程是改变按钮样式的核心内容,在这部分下下功夫,就可以做出自己理想的ToolBar了
编写这个类,还得感谢楼主,我本来对这种东西并不了解,直到看了楼主提供的http://www.codeguru.com/forum/attachment.php?attachmentid=7783
示例,我才弄明白WM_NOTIFY的机制,受益非浅!
SubClass的危险性,只是在调试时有些麻烦,类中哪怕一个变量未定义,都不会提示,而是直接崩溃。不过调试成功后使用,还是比较安全的,楼主对这个东西不要太担心。
Mark
收藏
用API很困难,VB不支持继承,估计要硬用 子类来解决会很麻烦
up
SubClass的危险性,只是在调试时有些麻烦,类中哪怕一个变量未定义,都不会提示,而是直接崩溃。
==================================================================
这主要是因为在VB IDE下VB程序是解析运行的
当处于调试状态下,VB将不再解析执行你的程序
当你设置了子类
若此时接受到一条Windows消息的时候
由于VB不再解析你的代码
所以CPU将执行未知代码
肯定会触发保护性错误
至于编译成exe后出现“因子类化导致程序崩溃”
那完全是程序员水平、态度问题
没有认真测试代码
看来大家都不知道这一点啊:
Ctrl + F5(全编译执行)的作用是:
检查程序语法错误,将程序编译成P代码,再解析P代码执行程序
与编译成exe时选P代码编译的性能一样
其实“Ctrl + F5”最大的作用还是检查语法错误
这样可以避免出现homezj(小吉)那样的情况:类中哪怕一个变量未定义,都不会提示,而是直接崩溃
如果你嫌每次运行时多按Ctrl麻烦的话
可以关掉VB的“请求时编译”
VB菜单栏:工具->选项
切换到“通用”页
注意“编译”组框
去掉“请求时编译”的勾
这样每次按F5都是全编译执行了
是呀!真的忽略了这一点,全编译执行的确是一个预先检测语法错误的好办法。以前,我的习惯只是启动程序前自动保存。
二者结合可少吃很多后悔药!
不过,关掉VB的“请求时编译”,只能适于小程序,大程序编译是很耗时的,每次启动前都编译,我想大多数人会受不了的。
To homezj(小吉):
我从网上收藏的XP按钮的源代码,现在没有找到,因为是前年收藏的,你可以自己在网上找一找。
另外,我已经从大家的回复中收益非浅,不知大家还要不要继续讨论,如果不需要继续讨论,我就结帖了。
我也是初涉Custom Draw消息处理,ToolBar本来我就很少用,所以我的兴趣是处理过程本身,而不是应用需求,很难静心深入研究它。
前几天看过几个代码,感觉,还有其他消息处理方法,但都没离开SubClass。看来,这一点,大家还是有共识的。
好贴!我代表比尔感谢你们