vbAccelerator - Contents of code file: cToolbar.ctl
VERSION 5.00
Begin VB.UserControl cToolbar
BorderStyle = 1 'Fixed Single
ClientHeight = 540
ClientLeft = 0
ClientTop = 0
ClientWidth = 3855
InvisibleAtRuntime= -1 'True
ScaleHeight = 540
ScaleWidth = 3855
Begin VB.Label lblInfo
Caption = "'Toolbar control'"
Height = 255
Left = 60
TabIndex = 0
Top = 60
Width = 4275
End
End
Attribute VB_Name = "cToolbar"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit
' =========================================================================
' vbAccelerator Toolbar control v3.0
' Copyright 1998-2000 Steve McMahon (steve@vbaccelerator.com)
'
' This is a complete form toolbar implementation designed
' for hosting in a vbAccelerator ReBar control.
'
' -------------------------------------------------------------------------
' Visit vbAccelerator at http://vbaccelerator.com
' =========================================================================
' ==============================================================================
' Declares, constants and types required for toolbar:
' ==============================================================================
Private Type TBADDBITMAP
hInst As Long
nID As Long
End Type
Private Type NMTOOLBAR_SHORT
hdr As NMHDR
iItem As Long
End Type
Private Type NMTOOLBAR
hdr As NMHDR
iItem As Long
tbBtn As TBBUTTON
cchText As Long
lpszString As Long
End Type
Private Type NMTBHOTITEM
hdr As NMHDR
idOld As Long
idNew As Long
dwFlags As Long '// HICF_*
End Type
' Toolbar button states:
Private Enum ectbButtonStates
TBSTATE_CHECKED = &H1
TBSTATE_PRESSED = &H2
TBSTATE_ENABLED = &H4
TBSTATE_WRAP = &H20
TBSTATE_ELLIPSES = &H40
TBSTATE_INDETERMINATE = &H10
TBSTATE_HIDDEN = &H8
End Enum
' Toolbar messages:
Private Const TB_SETSTATE = (WM_USER + 17)
Private Const TB_GETSTATE = (WM_USER + 18)
Private Const TB_ADDBITMAP = (WM_USER + 19)
Private Const TB_ADDBUTTONS = (WM_USER + 20)
Private Const TB_INSERTBUTTON = (WM_USER + 21)
Private Const TB_DELETEBUTTON = (WM_USER + 22)
Private Const TB_GETBUTTON = (WM_USER + 23)
Private Const TB_COMMANDTOINDEX = (WM_USER + 25)
Private Const TB_SAVERESTOREA = (WM_USER + 26)
Private Const TB_SAVERESTOREW = (WM_USER + 76)
Private Const TB_CUSTOMIZE = (WM_USER + 27)
Private Const TB_ADDSTRING = (WM_USER + 28)
Private Const TB_BUTTONSTRUCTSIZE = (WM_USER + 30)
Private Const TB_SETBUTTONSIZE = (WM_USER + 31)
Private Const TB_SETBITMAPSIZE = (WM_USER + 32)
Private Const TB_AUTOSIZE = (WM_USER + 33)
Private Const TB_GETTOOLTIPS = (WM_USER + 35)
Private Const TB_SETTOOLTIPS = (WM_USER + 36)
Private Const TB_SETPARENT = (WM_USER + 37)
Private Const TB_SETROWS = (WM_USER + 39)
Private Const TB_GETROWS = (WM_USER + 40)
Private Const TB_SETCMDID = (WM_USER + 42)
Private Const TB_CHANGEBITMAP = (WM_USER + 43)
Private Const TB_GETBITMAP = (WM_USER + 44)
Private Const TB_GETBUTTONTEXTA = (WM_USER + 45)
Private Const TB_GETBUTTONTEXTW = (WM_USER + 75)
'#if (_WIN32_IE >= 0x0300)
Private Const TB_SETINDENT = (WM_USER + 47)
Private Const TB_SETIMAGELIST = (WM_USER + 48)
Private Const TB_GETIMAGELIST = (WM_USER + 49)
Private Const TB_LOADIMAGES = (WM_USER + 50)
Private Const TB_GETRECT = (WM_USER + 51) '// wParam is the Cmd
instead of index
Private Const TB_SETHOTIMAGELIST = (WM_USER + 52)
Private Const TB_GETHOTIMAGELIST = (WM_USER + 53)
Private Const TB_SETDISABLEDIMAGELIST = (WM_USER + 54)
Private Const TB_GETDISABLEDIMAGELIST = (WM_USER + 55)
Private Const TB_SETSTYLE = (WM_USER + 56)
Private Const TB_GETSTYLE = (WM_USER + 57)
Private Const TB_GETBUTTONSIZE = (WM_USER + 58)
Private Const TB_SETBUTTONWIDTH = (WM_USER + 59)
Private Const TB_SETMAXTEXTROWS = (WM_USER + 60)
Private Const TB_GETTEXTROWS = (WM_USER + 61)
'#endif
'#if (_WIN32_IE >= 0x0400)
Private Const TB_GETOBJECT = (WM_USER + 62) '// wParam == IID,
lParam void **ppv
Private Const TB_SETANCHORHIGHLIGHT = (WM_USER + 73) '// wParam == TRUE/FALSE
Private Const TB_GETANCHORHIGHLIGHT = (WM_USER + 74)
Private Const TB_MAPACCELERATORA = (WM_USER + 78) '// wParam == ch, lParam
int * pidBtn
Private Const TB_MAPACCELERATORW = (WM_USER + 90) '// wParam == ch,
Private Const TB_MAPACCELERATOR = TB_MAPACCELERATORA
Private Type TBINSERTMARK
iButton As Long
dwFlags As Long
End Type
Private Const TBIMHT_AFTER = &H1 '// TRUE = insert After iButton,
otherwise before
Private Const TBIMHT_BACKGROUND = &H2 '// TRUE iff missed buttons completely
Private Const TB_GETINSERTMARK = (WM_USER + 79) '// lParam ==
LPTBINSERTMARK
Private Const TB_SETINSERTMARK = (WM_USER + 80) '// lParam ==
LPTBINSERTMARK
Private Const TB_INSERTMARKHITTEST = (WM_USER + 81) '// wParam == LPPOINT
lParam == LPTBINSERTMARK
Private Const TB_MOVEBUTTON = (WM_USER + 82)
Private Const TB_GETMAXSIZE = (WM_USER + 83) '// lParam == LPSIZE
' Extended style:
Private Const TB_SETEXTENDEDSTYLE = (WM_USER + 84) ' // For TBSTYLE_EX_*
Private Const TB_GETEXTENDEDSTYLE = (WM_USER + 85) '// For TBSTYLE_EX_*
Private Const TB_GETPADDING = (WM_USER + 86)
Private Const TB_SETPADDING = (WM_USER + 87)
Private Const TB_SETINSERTMARKCOLOR = (WM_USER + 88)
Private Const TB_GETINSERTMARKCOLOR = (WM_USER + 89)
Private Const TB_SETCOLORSCHEME = CCM_SETCOLORSCHEME '// lParam is color
scheme
Private Const TB_GETCOLORSCHEME = CCM_GETCOLORSCHEME '// fills in
COLORSCHEME pointed to by lParam
'#endif // _WIN32_IE >= 0x0400
Private Const TBSTYLE_EX_DRAWDDARROWS = &H1
'//Standard image types:
Private Const IDB_STD_SMALL_COLOR = 0
Private Const IDB_STD_LARGE_COLOR = 1
Private Const IDB_VIEW_SMALL_COLOR = 4
Private Const IDB_VIEW_LARGE_COLOR = 5
Private Const IDB_HIST_SMALL_COLOR = 8
Private Const IDB_HIST_LARGE_COLOR = 9
'// icon indexes for standard bitmap
Private Const STD_CUT = 0
Private Const STD_COPY = 1
Private Const STD_PASTE = 2
Private Const STD_UNDO = 3
Private Const STD_REDOW = 4
Private Const STD_DELETE = 5
Private Const STD_FILENEW = 6
Private Const STD_FILEOPEN = 7
Private Const STD_FILESAVE = 8
Private Const STD_PRINTPRE = 9
Private Const STD_PROPERTIES = 10
Private Const STD_HELP = 11
Private Const STD_FIND = 12
Private Const STD_REPLACE = 13
Private Const STD_PRINT = 14
'// icon indexes for standard view bitmap
Private Const VIEW_LARGEICONS = 0
Private Const VIEW_SMALLICONS = 1
Private Const VIEW_LIST = 2
Private Const VIEW_DETAILS = 3
Private Const VIEW_SORTNAME = 4
Private Const VIEW_SORTSIZE = 5
Private Const VIEW_SORTDATE = 6
Private Const VIEW_SORTTYPE = 7
Private Const VIEW_PARENTFOLDER = 8
Private Const VIEW_NETCONNECT = 9
Private Const VIEW_NETDISCONNECT = 10
Private Const VIEW_NEWFOLDER = 11
'#if (_WIN32_IE >= 0x0400)
Private Const VIEW_VIEWMENU = 12
'#End If
'#if (_WIN32_IE >= 0x0300)
Private Const HIST_BACK = 0
Private Const HIST_FORWARD = 1
Private Const HIST_FAVORITES = 2
Private Const HIST_ADDTOFAVORITES = 3
Private Const HIST_VIEWTREE = 4
'#End If
Private Declare Function CreateToolbarEx Lib "COMCTL32" (ByVal hwnd As Long,
ByVal ws As Long, ByVal wID As Long, ByVal nBitmaps As Long, ByVal hBMInst As
Long, ByVal wBMID As Long, ByRef lpButtons As TBBUTTON, ByVal iNumButtons As
Long, ByVal dxButton As Long, ByVal dyButton As Long, ByVal dxBitmap As Long,
ByVal dyBitmap As Long, ByVal uStructSize As Long) As Long
' ==============================================================================
' INTERFACE
' ==============================================================================
' Enumerations:
Public Enum ECTBToolButtonSyle
CTBNormal = TBSTYLE_BUTTON
CTBSeparator = TBSTYLE_SEP
CTBCheck = TBSTYLE_CHECK
CTBCheckGroup = TBSTYLE_CHECKGROUP
CTBDropDown = TBSTYLE_DROPDOWN
CTBAutoSize = TBSTYLE_AUTOSIZE
CTBDropDownArrow = BTNS_WHOLEDROPDOWN
End Enum
Public Enum ECTBImageListTypes
CTBImageListNormal = TB_SETIMAGELIST
CTBImageListHot = TB_SETHOTIMAGELIST
CTBImageListDisabled = TB_SETDISABLEDIMAGELIST
End Enum
Public Enum ECTBToolbarStyle
CTBFlat = TBSTYLE_FLAT
CTBList = TBSTYLE_LIST
CTBTransparent = -1 ' special - here we remove Toolbar from owner window
End Enum
Public Enum ECTBImageSourceTypes
CTBResourceBitmap
CTBLoadFromFile
CTBExternalImageList
CTBPicture
CTBStandardImageSources
End Enum
Public Enum ECTBStandardImageSourceTypes
CTBHistoryLargeColor = IDB_HIST_LARGE_COLOR
CTBHistorySmallColor = IDB_HIST_SMALL_COLOR
CTBStandardLargeColor = IDB_STD_LARGE_COLOR
CTBStandardSmallColor = IDB_STD_SMALL_COLOR
CTBViewLargeColor = IDB_VIEW_LARGE_COLOR
CTBViewSmallColor = IDB_VIEW_SMALL_COLOR
End Enum
Public Enum ECTBStandardImageIndexConstants
' History:
CTBHistAddToFavourites = HIST_ADDTOFAVORITES ' 'Add 'to 'favorites.
CTBHistBack = HIST_BACK ' 'Move 'back.
CTBHistFavourites = HIST_FAVORITES ' 'Open 'favorites 'folder.
CTBHistForward = HIST_FORWARD ' 'Move 'forward.
CTBHistViewTree = HIST_VIEWTREE ' 'View 'tree.
'Standard:
CTBStdCopy = STD_COPY ' 'Copy 'operation.
CTBStdCut = STD_CUT ' 'Cut 'operation.
CTBStdDelete = STD_DELETE ' 'Delete 'operation.
CTBStdFileNew = STD_FILENEW ' 'New 'file 'operation.
CTBStdFileOpen = STD_FILEOPEN ' 'Open 'file 'operation.
CTBStdFIleSave = STD_FILESAVE ' 'Save 'file 'operation.
CTBStdFind = STD_FIND ' 'Find 'operation.
CTBStdHelp = STD_HELP ' 'Help 'operation.
CTBStdPaste = STD_PASTE ' 'Paste 'operation.
CTBStdPrint = STD_PRINT ' 'Print 'operation.
CTBStdPrintPreview = STD_PRINTPRE ' 'Print 'preview 'operation.
CTBStdProperties = STD_PROPERTIES ' 'Properties 'operation.
CTBStdRedo = STD_REDOW ' 'Redo 'operation.
CTBStdReplace = STD_REPLACE ' 'Replace 'operation.
CTBStdUndo = STD_UNDO ' 'Undo 'operation.
'View
CTBViewDetails = VIEW_DETAILS ' 'Details 'view.
CTBViewLargeIcons = VIEW_LARGEICONS ' 'Large 'icons 'view.
CTBViewList = VIEW_LIST ' 'List 'view.
CTBViewNetConnect = VIEW_NETCONNECT ' 'Connect 'to 'network 'drive.
CTBViewNetDisconnect = VIEW_NETDISCONNECT ' 'Disconnect 'from 'network
'drive.
CTBViewNewFolder = VIEW_NEWFOLDER ' 'New 'folder.
CTBViewParentFolder = VIEW_PARENTFOLDER ' 'Go 'to 'parent 'folder.
CTBViewSmallIcons = VIEW_SMALLICONS ' 'Small 'icon 'view.
CTBViewSortDate = VIEW_SORTDATE ' 'Sort 'by 'date.
CTBViewSortName = VIEW_SORTNAME ' 'Sort 'by 'name.
CTBViewSortSize = VIEW_SORTSIZE ' 'Sort 'by 'size.
CTBViewSortType = VIEW_SORTTYPE ' 'Sort 'by 'type.
End Enum
Public Enum ECTBHotItemChangeReasonConstants
HICF_OTHER = 0
HICF_MOUSE = 1 '// Triggered by mouse
HICF_ARROWKEYS = 2 ' // Triggered by arrow keys
HICF_ACCELERATOR = 4 '// Triggered by accelerator
HICF_DUPACCEL = 8 '// This accelerator is not unique
HICF_ENTERING = 10 '// idOld is invalid
HICF_LEAVING = 20 '// idNew is invalid
HICF_RESELECT = 40 '// hot item reselected
End Enum
Public Enum ECTBToolbarFromMenuStyle
CTBMenuStyle
CTBToolbarStyle
End Enum
Public Enum ECTBDropDownAlign
CTBDropDownAlignBottom
CTBDropDownAlignLeft
End Enum
Public Enum ECTBChevronAdditionalButtons
CTBChevronAdditionalAddorRemove
CTBChevronAdditionalCustomise
CTBChevronAdditionalReset
End Enum
' Events:
Public Event ButtonClick(ByVal lButton As Long)
Public Event DropDownPress(ByVal lButton As Long)
Public Event HotItemChange(ByVal iNew As Long, ByVal iOld As Long, ByVal
eReason As ECTBHotItemChangeReasonConstants)
Public Event CustomiseBegin()
Public Event CustomiseCanInsertBefore(ByVal lButton As Long, ByRef bCanInsert
As Boolean)
Public Event CustomiseCanDelete(ByVal lButton As Long, ByRef bCanDelete As
Boolean)
Public Event CustomiseHelpPressed()
Public Event CustomiseResetPressed()
' ==============================================================================
' INTERNAL INFORMATION
' ==============================================================================
' Subclassing
Implements ISubclass
Private m_bInSubClass As Boolean
' Classes to turn toolbar into a menu:
Private m_cMenu As cTbarMenu
Private m_bIsMenu As Boolean
Private m_hMenu As Long
Private m_eCreateFromMenuStyle As ECTBToolbarFromMenuStyle
Private m_bCreateFromMenu2 As Boolean
Private m_lPtrMenu As Long
Private m_eDropDownAlign As ECTBDropDownAlign
' Hwnd of tool bar itself:
Private m_hWndToolBar As Long
Private m_hWndChevronToolbar As Long
Private m_hWndParentForm As Long
' Chevron information:
Private m_bChevronAdditionalButton(0 To 2) As Boolean
Private m_sChevronAdditionalButton(0 To 2) As String
Private m_iChevronIDMap() As Long
Private m_iChevronIDMapCount As Long
' Where the button images are coming from
Private m_eImageSourceType As ECTBImageSourceTypes
Private m_pic As StdPicture
Private m_sFileName As String
Private m_lResourceID As Long
Private m_hInstance As Long
Private m_hIml As Long
Private m_hImlHot As Long
Private m_hImlDis As Long
Private m_eStandardType As ECTBStandardImageSourceTypes
' Button size:
Private m_iButtonWidth As Integer
Private m_iButtonHeight As Integer
Private m_lOrigButtonSize As Long
' Style information:
Private m_bWithText As Boolean
Private m_bWrappable As Boolean
Private m_bVisible As Boolean
' Button information:
' Types:
Private Type ButtonInfoStore
wID As Integer
iImage As Integer
sTipText As String
iTextIndexNum As Integer
sCaption As String
bShowText As Boolean
idString As Long
iLarge As Integer
xWidth As Integer
xHeight As Integer
sKey As String
eStyle As ECTBToolButtonSyle
hSubMenu As Long
hWndCapture As Long
hWndParentOrig As Long
bStretch As Boolean
bControl As Boolean
End Type
Private m_tBInfo() As ButtonInfoStore
' Last return code from toolbar API or sendmessage call
Private m_lR As Long
' Strings in the toolbar:
Private m_lStringIDCount As Long
Private m_sString() As String
Private m_lStringID() As Long
' Common Controls Version:
Private m_lMajorVer As Long
Private m_lMinorVer As Long
Private m_lBuild As Long
' Whether to keep in focus when showing tool wins
Private m_bTitleBarModifier As Boolean
Private m_tRebarBand As RECT
Private m_sCtlName As String
Public Sub chevronPress(ByVal x As Long, ByVal y As Long)
Dim lhWndChevronToolBar As Long
Dim dwStyle As Long
Dim dwExStyle As Long
Dim Button As TBBUTTON
Dim lParam As Long
Dim i As Long
Dim tR As RECT
Dim lW As Long, lH As Long
Dim iNotVisibleIndex As Long
Dim lhWndParent As Long
Dim lExStyle As Long
Dim bMenu As Boolean
Dim hMenu As Long
Dim hSubMenu As Long
Dim tPM As TPMPARAMS
Dim lCmd As Long
Dim lR As Long
Dim cT As Object
Dim tP As POINTAPI
Dim cMenu As Object
Dim iPos As Long
Dim tMII As MENUITEMINFO
Dim tMI() As MENUITEMINFO
Dim iMenuItemCount As Long
Dim bButtonStyle As Boolean
Dim lIndex As Long
Dim bCustomOnly As Boolean
Dim lChevronAddition() As Long
Dim sChevronAddition() As String
Dim lChevronAdditionCount As Long
Dim lChevronTop As Long
Dim lMenu As Long
Dim lTopLevelMenu As Long
Dim bNoAdditionalCustomSeparator As Boolean
Dim sKeyBit As String
bMenu = (Not (m_lPtrMenu = 0))
lhWndParent = UserControl.Parent.hwnd
If Not (GetActiveWindow() = lhWndParent) Then
UserControl.Parent.ZOrder
End If
If Not bMenu Then
' toolbar
' Create a toolbar to show:
dwStyle = WS_CHILD Or WS_VISIBLE Or WS_CLIPCHILDREN
dwStyle = dwStyle Or CCS_NOPARENTALIGN Or CCS_NORESIZE Or CCS_NODIVIDER
dwStyle = dwStyle Or TBSTYLE_TOOLTIPS Or TBSTYLE_FLAT
dwStyle = dwStyle Or TBSTYLE_LIST
dwStyle = dwStyle Or TBSTYLE_WRAPABLE
dwStyle = dwStyle Or TBSTYLE_REGISTERDROP
dwExStyle = WS_EX_TOOLWINDOW
lExStyle = GetWindowLong(lhWndParent, GWL_EXSTYLE)
lExStyle = lExStyle And (WS_EX_RIGHT Or WS_EX_RTLREADING)
dwExStyle = dwExStyle Or lExStyle
lhWndChevronToolBar = CreateWindowEX(dwExStyle, "ToolbarWindow32", "", _
dwStyle, _
0, 0, 0, 0, UserControl.Parent.hwnd, 0&, App.hInstance, 0&)
SendMessageLong lhWndChevronToolBar, TB_SETPARENT, lhWndParent, 0
m_lR = SendMessageLong(lhWndChevronToolBar, TB_BUTTONSTRUCTSIZE,
LenB(Button), 0)
AddBitmapIfRequired lhWndChevronToolBar
If m_eImageSourceType <> -1 Then
lParam = m_lOrigButtonSize + (m_lOrigButtonSize * &H10000)
Else
lParam = 0
End If
m_lR = SendMessageLong(lhWndChevronToolBar, TB_SETBITMAPSIZE, 0, lParam)
' Ok, now we have a toolbar to work with, add copies of the
' buttons that are currently out of view in the toolbar:
Else
' Create a menu to add items to:
'hMenu = CreatePopupMenu()
CopyMemory cT, m_lPtrMenu, 4
Set cMenu = cT
CopyMemory cT, 0&, 4
End If
iNotVisibleIndex = findFirstNonVisibleButton()
m_iChevronIDMapCount = 0
' Is there anything to do?
bCustomOnly = (bMenu And
(m_bChevronAdditionalButton(CTBChevronAdditionalAddorRemove) Or
m_bChevronAdditionalButton(CTBChevronAdditionalCustomise)))
If (iNotVisibleIndex < 0) And Not (bCustomOnly) Then
If lhWndChevronToolBar Then
DestroyWindow lhWndChevronToolBar
End If
Exit Sub
End If
If bMenu Then
' Remove items which can be seen in the toolbar:
If iNotVisibleIndex < 0 Then
iNotVisibleIndex = GetMenuItemCount(m_hMenu)
bNoAdditionalCustomSeparator = True
End If
For i = iNotVisibleIndex - 1 To 0 Step -1
tMII.fMask = MIIM_ID
tMII.cbSize = Len(tMII)
GetMenuItemInfo m_hMenu, i, True, tMII
lIndex = cMenu.ItemForID(tMII.wID)
' Debug.Print lIndex, cMenu.Caption(lIndex)
If cMenu.Visible(lIndex) Then
iMenuItemCount = iMenuItemCount + 1
ReDim Preserve tMI(1 To iMenuItemCount) As MENUITEMINFO
LSet tMI(iMenuItemCount) = tMII
cMenu.Visible(lIndex) = False
End If
Next i
lMenu = 0
For i = 1 To cMenu.Count
If (cMenu.hMenu(i) = m_hMenu) Then
If cMenu.Visible(i) Then
lMenu = i
lTopLevelMenu = cMenu.ItemParentIndex(lMenu)
Exit For
End If
lTopLevelMenu = cMenu.ItemParentIndex(i)
End If
Next i
If m_bChevronAdditionalButton(CTBChevronAdditionalAddorRemove) Or
m_bChevronAdditionalButton(CTBChevronAdditionalCustomise) Or
m_bChevronAdditionalButton(CTBChevronAdditionalReset) Then
If Not bNoAdditionalCustomSeparator Then
lChevronAdditionCount = lChevronAdditionCount + 1
ReDim Preserve lChevronAddition(1 To lChevronAdditionCount) As Long
ReDim Preserve sChevronAddition(1 To lChevronAdditionCount) As
String
sChevronAddition(lChevronAdditionCount) = sKeyBit & ":SEP:1"
lChevronAddition(lChevronAdditionCount) = cMenu.AddItem("-", ,
VBALCHEVRONMENUCONST, lTopLevelMenu, , , ,
sChevronAddition(lChevronAdditionCount))
End If
sKeyBit = "_VBALCC:" & m_hWndToolBar
' add the "Add or Remove Buttons" option:
lChevronAdditionCount = lChevronAdditionCount + 1
ReDim Preserve lChevronAddition(1 To lChevronAdditionCount) As Long
ReDim Preserve sChevronAddition(1 To lChevronAdditionCount) As String
sChevronAddition(lChevronAdditionCount) = sKeyBit & ":AOR"
lChevronAddition(lChevronAdditionCount) =
cMenu.AddItem(m_sChevronAdditionalButton(CTBChevronAdditionalAddorRemo
ve), , VBALCHEVRONMENUCONST, lTopLevelMenu, , , ,
sChevronAddition(lChevronAdditionCount))
lChevronTop = lChevronAddition(lChevronAdditionCount)
If lMenu <= 0 Then
lMenu = lChevronAddition(lChevronAdditionCount)
End If
i = -1
If (m_bChevronAdditionalButton(CTBChevronAdditionalAddorRemove)) Then
' add the add/remove details:
For i = 0 To ButtonCount - 1
lChevronAdditionCount = lChevronAdditionCount + 1
ReDim Preserve lChevronAddition(1 To lChevronAdditionCount) As
Long
ReDim Preserve sChevronAddition(1 To lChevronAdditionCount) As
String
sChevronAddition(lChevronAdditionCount) = sKeyBit & ":BTN:" & i
& ":" & ButtonKey(i)
lChevronAddition(lChevronAdditionCount) = cMenu.AddItem( _
ButtonCaption(i), , _
VBALCHEVRONMENUCONST, _
lChevronTop, _
m_tBInfo(i).iImage, ButtonVisible(i), , _
sChevronAddition(lChevronAdditionCount))
cMenu.RedisplayMenuOnClick(lChevronAddition(lChevronAdditionCount
)) = True
cMenu.ShowCheckAndIcon(lChevronAddition(lChevronAdditionCount))
= True
Next i
End If
If m_bChevronAdditionalButton(CTBChevronAdditionalReset) Then
' add the reset toolbar button:
If i > -1 Then
i = -1
lChevronAdditionCount = lChevronAdditionCount + 1
ReDim Preserve lChevronAddition(1 To lChevronAdditionCount) As
Long
ReDim Preserve sChevronAddition(1 To lChevronAdditionCount) As
String
sChevronAddition(lChevronAdditionCount) = sKeyBit & ":SEP:2"
lChevronAddition(lChevronAdditionCount) = cMenu.AddItem("-", ,
VBALCHEVRONMENUCONST, lChevronTop, , , ,
sChevronAddition(lChevronAdditionCount))
End If
lChevronAdditionCount = lChevronAdditionCount + 1
ReDim Preserve lChevronAddition(1 To lChevronAdditionCount) As Long
ReDim Preserve sChevronAddition(1 To lChevronAdditionCount) As
String
sChevronAddition(lChevronAdditionCount) = sKeyBit & ":RST"
lChevronAddition(lChevronAdditionCount) =
cMenu.AddItem(m_sChevronAdditionalButton(CTBChevronAdditionalReset)
, , VBALCHEVRONMENUCONST, lChevronTop, , , ,
sChevronAddition(lChevronAdditionCount))
End If
If m_bChevronAdditionalButton(CTBChevronAdditionalCustomise) Then
' add the customise button:
If i > -1 Then
i = -1
lChevronAdditionCount = lChevronAdditionCount + 1
ReDim Preserve lChevronAddition(1 To lChevronAdditionCount) As
Long
ReDim Preserve sChevronAddition(1 To lChevronAdditionCount) As
String
sChevronAddition(lChevronAdditionCount) = sKeyBit & ":SEP:3"
lChevronAddition(lChevronAdditionCount) = cMenu.AddItem("-", ,
VBALCHEVRONMENUCONST, lChevronTop, , , ,
sChevronAddition(lChevronAdditionCount))
End If
lChevronAdditionCount = lChevronAdditionCount + 1
ReDim Preserve lChevronAddition(1 To lChevronAdditionCount) As Long
ReDim Preserve sChevronAddition(1 To lChevronAdditionCount) As
String
sChevronAddition(lChevronAdditionCount) = sKeyBit & ":CST"
lChevronAddition(lChevronAdditionCount) =
cMenu.AddItem(m_sChevronAdditionalButton(CTBChevronAdditionalCustom
ise), , VBALCHEVRONMENUCONST, lChevronTop, , , ,
sChevronAddition(lChevronAdditionCount))
End If
End If
Else
For i = iNotVisibleIndex To ButtonCount - 1
If Not m_tBInfo(i).eStyle = CTBSeparator Then
m_iChevronIDMapCount = m_iChevronIDMapCount + 1
plAddButton lhWndChevronToolBar, m_tBInfo(i).wID,
m_tBInfo(i).sTipText, m_tBInfo(i).iImage, , m_tBInfo(i).iLarge,
m_tBInfo(i).sCaption, m_tBInfo(i).eStyle And Not CTBAutoSize
SendMessageLong lhWndChevronToolBar, TB_ENABLEBUTTON,
m_tBInfo(i).wID, Abs(ButtonEnabled(i))
SendMessageLong lhWndChevronToolBar, TB_CHECKBUTTON,
m_tBInfo(i).wID, Abs(ButtonChecked(i))
ReDim Preserve m_iChevronIDMap(1 To m_iChevronIDMapCount) As Long
m_iChevronIDMap(m_iChevronIDMapCount) = i
End If
Next i
End If
If bMenu Then
tP.x = x: tP.y = y
ScreenToClient cMenu.hWndOwner, tP
lIndex = cMenu.ShowPopupMenuAtIndex(tP.x * Screen.TwipsPerPixelX, tP.y *
Screen.TwipsPerPixelY, , , , , , lMenu)
' add menu items back in again:
For i = iMenuItemCount To 1 Step -1
lIndex = cMenu.ItemForID(tMI(i).wID)
cMenu.Visible(lIndex) = True
Next i
' remove the chevron items:
For i = lChevronAdditionCount To 1 Step -1
cMenu.RemoveItem sChevronAddition(i) 'lChevronAddition(i)
Next i
Else
' Evaluate the size of the chevron bar:
lW = 0: lH = 0
For i = 0 To plButtonCount(lhWndChevronToolBar) - 1
SendMessage lhWndChevronToolBar, TB_GETITEMRECT, i, tR
If tR.Right - tR.Left > lW Then
lW = tR.Right - tR.Left
End If
lH = lH + tR.Bottom - tR.Top
Next i
' account for borders:
lW = lW + 6
lH = lH + 6
If y + lH > Screen.Height \ Screen.TwipsPerPixelY - 2 Then
y = Screen.Height \ Screen.TwipsPerPixelY - lH - 2
End If
If x + lW > Screen.Width \ Screen.TwipsPerPixelX - 2 Then
x = Screen.Width \ Screen.TwipsPerPixelX - lW - 2
End If
' Show the chevron window at the appropriate position:
'Dim cCW As cChevronWindow
'Set cCW = New cChevronWindow
'm_hWndChevronToolbar = lhWndChevronToolBar
'cCW.Create m_hWndParentForm
'cCW.Capture m_hWndChevronToolbar
'cCW.Show x, y, lW, lH
'cCW.Destroy
'm_hWndChevronToolbar = 0
End If
End Sub
Public Property Get ChevronButton(ByVal eButton As
ECTBChevronAdditionalButtons) As Boolean
ChevronButton = m_bChevronAdditionalButton(eButton)
End Property
Public Property Let ChevronButton(ByVal eButton As
ECTBChevronAdditionalButtons, ByVal bState As Boolean)
m_bChevronAdditionalButton(eButton) = bState
End Property
Public Property Get ChevronButtonCaption(ByVal eButton As
ECTBChevronAdditionalButtons) As String
ChevronButtonCaption = m_sChevronAdditionalButton(eButton)
End Property
Public Property Let ChevronButtonCaption(ByVal eButton As
ECTBChevronAdditionalButtons, ByVal sCaption As String)
m_sChevronAdditionalButton(eButton) = sCaption
End Property
Friend Function AltKeyPress(ByVal eKeyCode As KeyCodeConstants) As Boolean
Dim wID As Long
Dim iKey As Long
Dim iB As Long
Dim i As Long
Dim sAccel As String
If m_hWndToolBar <> 0 Then
' Am i a member of an active form?
If getTheActiveWindow() Then
iB = -1
sAccel = UCase$(Chr$(eKeyCode))
For i = 0 To ButtonCount - 1
If psGetAccelerator(m_tBInfo(i).sCaption) = sAccel Then
iB = i
wID = m_tBInfo(i).wID
Exit For
End If
Next i
If iB > -1 Then
ButtonPressed(iB) = True
SendMessageLong m_hWndToolBar, WM_COMMAND, wID, m_hWndToolBar
ButtonPressed(iB) = False
AltKeyPress = True
Else
'Debug.Assert iB > -1
End If
End If
End If
End Function
Private Function getTheActiveWindow() As Boolean
Dim lhWnd As Long
lhWnd = GetActiveWindow()
If lhWnd = m_hWndParentForm Then
' is active
getTheActiveWindow = True
Else
lhWnd = GetProp(lhWnd, TOOLWINDOWPARENTWINDOWHWND)
If lhWnd = m_hWndParentForm Then
' is active
getTheActiveWindow = True
End If
End If
End Function
Friend Sub pMenuClick(ByVal hWndToolbar As Long, ByVal iButton As Long)
Dim lR As Long
'Debug.Print iButton
If Not m_lPtrMenu = 0 Then
PopupObject.CreateSubClass m_hWndParentForm
End If
If Not m_cMenu Is Nothing Then
m_cMenu.MenuAlignLeft = (m_eDropDownAlign = CTBDropDownAlignLeft)
m_cMenu.CoolMenuAttach m_hWndParentForm, hWndToolbar, m_hMenu, m_lPtrMenu
lR = m_cMenu.TrackPopup(iButton)
m_cMenu.CoolMenuDetach
End If
If Not m_lPtrMenu = 0 Then
If lR <> 0 Then
' Debug.Print "THAT WAS MENU ITEM: ", lR
PopupObject.EmulateMenuClick lR
End If
PopupObject.DestroySubClass
End If
End Sub
Private Property Get PopupObject() As Object
Dim oTemp As Object
CopyMemory oTemp, m_lPtrMenu, 4
Set PopupObject = oTemp
CopyMemory oTemp, 0&, 4
End Property
Public Property Get AutosizeButtonPadding() As Long
' NB Only applies to autosize buttons
If m_hWndToolBar <> 0 Then
AutosizeButtonPadding = (SendMessageLong(m_hWndToolBar, TB_GETPADDING, 0,
0) And &H7FFF&)
End If
End Property
Public Property Let AutosizeButtonPadding(ByVal lPadding As Long)
Dim lxy As Long
If m_hWndToolBar <> 0 Then
lxy = (lPadding And &H7FFF&) Or (lPadding And &H7FFF& * &H10000)
SendMessageLong m_hWndToolBar, TB_SETPADDING, 0, lxy
End If
End Property
Public Sub GetComCtrlVersionInfo( _
ByRef lMajor As Long, _
ByRef lMinor As Long, _
Optional ByRef lBuild As Long _
)
lMajor = m_lMajorVer
lMinor = m_lMinorVer
lBuild = m_lBuild
End Sub
Public Property Get ButtonCount() As Long
If m_hWndToolBar <> 0 Then
ButtonCount = plButtonCount(m_hWndToolBar)
End If
End Property
Private Property Get plButtonCount(ByVal hWndToolbar As Long) As Long
plButtonCount = SendMessageLong(hWndToolbar, TB_BUTTONCOUNT, 0, 0)
End Property
Public Property Get ButtonToolTip(ByVal vButton As Variant) As String
Dim iB As Long
iB = ButtonIndex(vButton)
If (iB > -1) Then
ButtonToolTip = m_tBInfo(iB).sTipText
End If
End Property
Public Property Let ButtonToolTip(ByVal vButton As Variant, ByVal sToolTip As
String)
Dim iB As Long
iB = ButtonIndex(vButton)
If (iB > -1) Then
m_tBInfo(iB).sTipText = sToolTip
End If
End Property
Private Function pbGetIndexForID(ByVal iBtnId As Long) As Long
Dim iB As Long
pbGetIndexForID = -1
For iB = 0 To UBound(m_tBInfo)
If (m_tBInfo(iB).wID = iBtnId) Then
pbGetIndexForID = iB
Exit For
End If
Next iB
End Function
Public Property Get ButtonImage(ByVal vButton As Variant) As Long
Dim iB As Long
iB = ButtonIndex(vButton)
If (iB <> -1) Then
ButtonImage = m_tBInfo(iB).iImage
End If
End Property
Public Property Let ButtonImage(ByVal vButton As Variant, ByVal iImage As Long)
Dim iB As Long
' If we are running pre 4.71 we must remove the button and add it again.
' 4.71+ we can use the TB_SETBUTTONINFO method to change it on the fly:
If (m_lMajorVer > 4) Or ((m_lMajorVer = 4) And (m_lMinorVer > 70)) Then
Dim tBI As TBBUTTONINFO
Dim iID As Long
iB = ButtonIndex(vButton)
If (iB <> -1) Then
iID = m_tBInfo(iB).wID
tBI.cbSize = Len(tBI)
tBI.dwMask = TBIF_IMAGE
tBI.iImage = iImage
If (SendMessage(m_hWndToolBar, TB_SETBUTTONINFO, iID, tBI) <> 0) Then
m_tBInfo(iB).iImage = iImage
End If
End If
Else
iB = ButtonIndex(vButton)
If (iB <> -1) Then
' Delete this button...
'RemoveButton iB
'
End If
End If
End Property
Public Property Get ButtonCaption(ByVal vButton As Variant) As String
Dim iB As Long
iB = ButtonIndex(vButton)
If (iB <> -1) Then
ButtonCaption = m_tBInfo(iB).sCaption
End If
End Property
Public Property Let ButtonCaption(ByVal vButton As Variant, ByVal sCaption As
String)
Dim iB As Integer
Dim bEnd As Boolean
iB = ButtonIndex(vButton)
If (iB > -1) Then
If ((m_lMajorVer > 4) Or ((m_lMajorVer = 4) And (m_lMinorVer > 70))) And
sCaption <> "" Then
Dim tBI As TBBUTTONINFO
Dim sBuf As String
Dim iID As Long
If iB <> -1 Then
' Remove any existing accelerator associated with caption:
plRemoveString m_tBInfo(iB).sCaption
' don't add too many strings...
plAddStringIfRequired m_hWndToolBar, sCaption
If m_tBInfo(iB).bShowText Then
sBuf = sCaption
sBuf = sBuf & String$(80 - Len(sBuf), 0)
Else
sBuf = String$(80, 0)
End If
sBuf = StrConv(sBuf, vbFromUnicode)
iID = m_tBInfo(iB).wID
tBI.cbSize = Len(tBI)
tBI.pszText = StrPtr(sBuf)
tBI.dwMask = TBIF_TEXT
If (SendMessage(m_hWndToolBar, TB_SETBUTTONINFO, iID, tBI) <> 0)
Then
m_tBInfo(iB).sCaption = sCaption
End If
End If
Else
' Hmmm. YOu can't remove any of the captions that have
' been added to the toolbar control, so if we keep on
' adding the damn things... Don't change button captions
' to too many different things!
Dim tBInfo As ButtonInfoStore
LSet tBInfo = m_tBInfo(iB)
If iB = ButtonCount - 1 Then
bEnd = True
End If
RemoveButton iB
If bEnd Then
AddButton tBInfo.sTipText, tBInfo.iImage, , tBInfo.iLarge,
sCaption, tBInfo.eStyle, tBInfo.sKey
Else
AddButton tBInfo.sTipText, tBInfo.iImage, iB, tBInfo.iLarge,
sCaption, tBInfo.eStyle, tBInfo.sKey
End If
End If
End If
End Property
Public Property Get ButtonTextVisible(ByVal vButton As Variant) As Boolean
Dim iB As Integer
iB = ButtonIndex(vButton)
If iB > -1 Then
ButtonTextVisible = m_tBInfo(iB).bShowText
End If
End Property
Public Property Let ButtonTextVisible(ByVal vButton As Variant, ByVal bState As
Boolean)
Dim iB As Integer
Dim tBI As ButtonInfoStore
Dim bEnd As Boolean
Dim bChecked As Boolean
Dim bEnabled As Boolean
Dim bVisible As Boolean, bSet As Boolean
Dim lStyle As Long, lR As Long
lStyle = GetWindowLong(m_hWndToolBar, GWL_STYLE)
If (lStyle And TBSTYLE_LIST) <> TBSTYLE_LIST Then
lR = SendMessageLong(m_hWndToolBar, TB_GETTEXTROWS, 0, 0)
If bState Then
If lR < 1 Then
SendMessageLong m_hWndToolBar, TB_SETMAXTEXTROWS, 1, 0
bSet = True
End If
Else
If lR > 0 Then
SendMessageLong m_hWndToolBar, TB_SETMAXTEXTROWS, 0, 0
bSet = True
End If
End If
If bSet Then
For iB = 0 To ButtonCount - 1
m_tBInfo(iB).bShowText = bState
Next iB
End If
Else
iB = ButtonIndex(vButton)
If iB > -1 Then
If Not (m_tBInfo(iB).bControl) Then
If bState <> m_tBInfo(iB).bShowText Then
' Hide/show text for this button:
bChecked = ButtonChecked(iB)
bEnabled = ButtonEnabled(iB)
bVisible = ButtonVisible(iB)
LSet tBI = m_tBInfo(iB)
bEnd = (iB = (ButtonCount - 1))
RemoveButton iB
If bEnd Then
If bState Then
iB = plAddButton(m_hWndToolBar, NewButtonID, tBI.sTipText,
tBI.iImage, , tBI.iLarge, tBI.sCaption, tBI.eStyle,
tBI.sKey)
Else
iB = plAddButton(m_hWndToolBar, NewButtonID, tBI.sTipText,
tBI.iImage, , tBI.iLarge, , tBI.eStyle, tBI.sKey)
End If
Else
If bState Then
iB = plAddButton(m_hWndToolBar, NewButtonID, tBI.sTipText,
tBI.iImage, iB, tBI.iLarge, tBI.sCaption, tBI.eStyle,
tBI.sKey)
Else
iB = plAddButton(m_hWndToolBar, NewButtonID, tBI.sTipText,
tBI.iImage, iB, tBI.iLarge, , tBI.eStyle, tBI.sKey)
End If
End If
m_tBInfo(iB).sCaption = tBI.sCaption
ButtonEnabled(iB) = bEnabled
ButtonChecked(iB) = bChecked
ButtonVisible(iB) = bVisible
m_tBInfo(iB).bShowText = bState
m_tBInfo(iB).hSubMenu = tBI.hSubMenu
End If
End If
End If
End If
End Property
Public Property Get ButtonIndex(ByVal vButton As Variant) As Integer
Dim iB As Integer
Dim iIndex As Integer
iIndex = -1
If (IsNumeric(vButton)) Then
iIndex = CInt(vButton)
Else
For iB = 0 To UBound(m_tBInfo)
If (m_tBInfo(iB).sKey = vButton) Then
iIndex = iB
Exit For
End If
Next iB
End If
If (iIndex > -1) And (iIndex <= UBound(m_tBInfo)) Then
ButtonIndex = iIndex
Else
' error
debugmsg m_sCtlName & ",Button index failed"
ButtonIndex = -1
End If
End Property
Public Property Get ButtonKey(ByVal iButton As Long) As String
If (iButton > -1) And (iButton < ButtonCount) Then
ButtonKey = m_tBInfo(iButton).sKey
End If
End Property
Public Property Get ButtonEnabled(ByVal vButton As Variant) As Boolean
Dim iButton As Long
Dim iID As Long
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
iID = m_tBInfo(iButton).wID
ButtonEnabled = pbGetState(iID, TBSTATE_ENABLED)
End If
End Property
Public Property Let ButtonEnabled(ByVal vButton As Variant, ByVal bState As
Boolean)
Dim iButton As Long
Dim iID As Long
Dim lEnable As Long
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
iID = m_tBInfo(iButton).wID
pbSetState iID, TBSTATE_ENABLED, bState
End If
End Property
Public Property Get ButtonVisible(ByVal vButton As Variant) As Boolean
Dim iButton As Long
Dim iID As Long
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
iID = m_tBInfo(iButton).wID
ButtonVisible = Not (pbGetState(iID, TBSTATE_HIDDEN))
End If
End Property
Public Property Let ButtonVisible(ByVal vButton As Variant, ByVal bState As
Boolean)
Dim iButton As Long
Dim iID As Long
Dim i As Long
Dim j As Long
Dim bPriorSeparator As Boolean
Dim bNextSeparator As Boolean
Dim bHiddenSeparator As Boolean
Dim iNextSeparator As Long
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
iID = m_tBInfo(iButton).wID
pbSetState iID, TBSTATE_HIDDEN, Not (bState)
If (m_tBInfo(iButton).eStyle <> CTBSeparator) Then
If Not (bState) Then
' if the prior visible button is a separator, and the next one
is also,
' then we hide the next separator:
bPriorSeparator = True
For i = iButton - 1 To 0 Step -1
If (ButtonVisible(i)) Then
If (m_tBInfo(i).eStyle = CTBSeparator) Then
bPriorSeparator = True
Else
bPriorSeparator = False
End If
Exit For
End If
Next i
bNextSeparator = False
For i = iButton + 1 To ButtonCount - 1
If (ButtonVisible(i)) Then
If (m_tBInfo(i).eStyle = CTBSeparator) Then
bNextSeparator = True
iNextSeparator = i
End If
Exit For
End If
Next i
If (bPriorSeparator And bNextSeparator) Then
pbSetState m_tBInfo(iNextSeparator).wID, TBSTATE_HIDDEN, True
End If
Else
' check for a hidden separator followed by a visible button:
For i = iButton + 1 To ButtonCount - 1
If (ButtonVisible(i)) Then
Exit For
Else
If (m_tBInfo(i).eStyle = CTBSeparator) Then
bHiddenSeparator = True
iNextSeparator = i
Exit For
End If
End If
Next i
If (bHiddenSeparator) Then
' check that the next visible button is not also a separator
For i = iNextSeparator + 1 To ButtonCount - 1
If (ButtonVisible(i)) Then
If (m_tBInfo(i).eStyle = CTBSeparator) Then
bHiddenSeparator = False
End If
End If
Exit For
Next i
If (bHiddenSeparator) Then
pbSetState m_tBInfo(iNextSeparator).wID, TBSTATE_HIDDEN,
False
End If
End If
End If
End If
ResizeToolbar
End If
End Property
Private Property Get plButtonVisible(ByVal hWndToolbar As Long, ByVal lBtnIndex
As Long) As Boolean
Dim tBB As TBBUTTON
SendMessage m_hWndToolBar, TB_GETBUTTON, lBtnIndex, tBB
plButtonVisible = (SendMessageLong(hWndToolbar, TB_ISBUTTONHIDDEN,
tBB.idCommand, 0) = 0)
End Property
Public Property Get ButtonWidth(ByVal vButton As Variant)
Dim iButton As Long
Dim tR As RECT
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
SendMessage m_hWndToolBar, TB_GETRECT, m_tBInfo(iButton).wID, tR
ButtonWidth = tR.Right - tR.Left
moveChildWindow iButton
End If
End Property
Public Property Let ButtonWidth(ByVal vButton As Variant, ByVal lWidth As
Variant)
' the width parameter should be a long for pixels, but the original was
' compiled with the property Get as a variant... forgot to type the
' vartype - doh!
Dim iButton As Long
Dim tR As RECT
Dim tWR As RECT
Dim lhWnd As Long
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
Dim tBB As TBBUTTONINFO
tBB.cbSize = LenB(tBB)
tBB.dwMask = TBIF_SIZE
SendMessage m_hWndToolBar, TB_GETBUTTONINFO, m_tBInfo(iButton).wID, tBB
If Not (tBB.cx = lWidth) Then
tBB.cx = lWidth
SendMessage m_hWndToolBar, TB_SETBUTTONINFO, m_tBInfo(iButton).wID, tBB
If Not (m_tBInfo(iButton).hWndCapture = 0) Then
moveChildWindow iButton
End If
End If
End If
End Property
Public Property Get ButtonHeight(ByVal vButton As Variant) As Long
Dim iButton As Long
Dim tR As RECT
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
SendMessage m_hWndToolBar, TB_GETRECT, m_tBInfo(iButton).wID, tR
ButtonHeight = tR.Bottom - tR.Top
End If
End Property
Public Property Get ButtonLeft(ByVal vButton As Variant) As Long
Dim iButton As Long
Dim tR As RECT
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
SendMessage m_hWndToolBar, TB_GETRECT, m_tBInfo(iButton).wID, tR
ButtonLeft = tR.Left
End If
End Property
Public Property Get ButtonTop(ByVal vButton As Variant) As Long
Dim iButton As Long
Dim tR As RECT
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
SendMessage m_hWndToolBar, TB_GETRECT, m_tBInfo(iButton).wID, tR
ButtonTop = tR.Top
End If
End Property
Public Property Get ButtonHot(ByVal vButton As Variant) As Boolean
Dim iB As Integer
iB = ButtonIndex(vButton)
If iB > -1 Then
ButtonHot = (SendMessageLong(m_hWndToolBar, TB_GETHOTITEM, 0, 0) = iB)
End If
End Property
Public Property Let ButtonHot(ByVal vButton As Variant, ByVal bHot As Boolean)
Dim iB As Integer
iB = ButtonIndex(vButton)
If iB > -1 Then
If ButtonHot(iB) Then
If Not bHot Then
SendMessageLong m_hWndToolBar, TB_SETHOTITEM, -1, 0
End If
Else
If bHot Then
SendMessageLong m_hWndToolBar, TB_SETHOTITEM, iB, 0
End If
End If
End If
End Property
Public Property Get MaxButtonWidth() As Long
Dim i As Long
Dim lW As Long
Dim lMaxW As Long
For i = 0 To ButtonCount - 1
lW = ButtonWidth(i)
If lW > lMaxW Then
lMaxW = lW
End If
Next i
MaxButtonWidth = lMaxW
End Property
Public Property Get MaxButtonHeight() As Long
Dim i As Long
Dim lH As Long
Dim lMaxH As Long
For i = 0 To ButtonCount - 1
lH = ButtonHeight(i)
If lH > lMaxH Then
lMaxH = lH
End If
Next i
MaxButtonHeight = lMaxH
End Property
Public Property Get ButtonChecked(ByVal vButton As Variant) As Boolean
ButtonChecked = plButtonChecked(m_hWndToolBar, vButton)
End Property
Private Property Get plButtonChecked(ByVal hWndToolbar As Long, ByVal vButton
As Variant) As Boolean
Dim iButton As Long
Dim iID As Long
Dim tBB As TBBUTTON
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
SendMessage hWndToolbar, TB_GETBUTTON, iButton, tBB
iID = tBB.idCommand 'm_tBInfo(iButton).wID
plButtonChecked = pbGetState2(hWndToolbar, iID, TBSTATE_CHECKED)
End If
End Property
Public Property Let ButtonChecked(ByVal vButton As Variant, ByVal bState As
Boolean)
plButtonChecked(m_hWndToolBar, vButton) = bState
End Property
Private Property Let plButtonChecked(ByVal hWndToolbar As Long, ByVal vButton
As Variant, ByVal bState As Boolean)
Dim iButton As Long
Dim iID As Long
Dim tBB As TBBUTTON
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
SendMessage hWndToolbar, TB_GETBUTTON, iButton, tBB
iID = tBB.idCommand
'Check the button
SendMessageLong hWndToolbar, TB_CHECKBUTTON, iID, Abs(bState)
If (ButtonPressed(iButton) <> bState) Then
SendMessageLong hWndToolbar, TB_CHECKBUTTON, iID, Abs(bState)
End If
End If
End Property
Public Property Get ButtonPressed(ByVal vButton As Variant) As Boolean
ButtonPressed = plButtonPressed(m_hWndToolBar, vButton)
End Property
Private Property Get plButtonPressed(ByVal hWndToolbar As Long, ByVal vButton
As Variant) As Boolean
Dim iButton As Long
Dim iID As Long
Dim tBB As TBBUTTON
If (hWndToolbar = m_hWndToolBar) Then
iButton = ButtonIndex(vButton)
Else
iButton = vButton
End If
If (iButton <> -1) Then
SendMessage hWndToolbar, TB_GETBUTTON, iButton, tBB
iID = tBB.idCommand
plButtonPressed = pbGetState2(hWndToolbar, iID, TBSTATE_PRESSED)
End If
End Property
Public Property Let ButtonPressed(ByVal vButton As Variant, ByVal bState As
Boolean)
plButtonPressed(m_hWndToolBar, vButton) = bState
End Property
Private Property Let plButtonPressed(ByVal hWndToolbar As Long, ByVal vButton
As Variant, ByVal bState As Boolean)
Dim iButton As Long
Dim iID As Long
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
iID = m_tBInfo(iButton).wID
pbSetState2 hWndToolbar, iID, TBSTATE_PRESSED, bState
End If
End Property
Public Property Get ButtonStyle(ByVal vButton As Variant) As ECTBToolButtonSyle
Dim iButton As Long
Dim iID As Long
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
Dim tBI As TBBUTTONINFO
iID = m_tBInfo(iButton).wID
tBI.cbSize = LenB(tBI)
tBI.dwMask = TBIF_STYLE
If (SendMessage(m_hWndToolBar, TB_GETBUTTONINFO, iID, tBI) = iButton) Then
ButtonStyle = tBI.fsStyle
End If
End If
End Property
Public Property Let ButtonStyle(ByVal vButton As Variant, ByVal eStyle As
ECTBToolButtonSyle)
Dim iButton As Long
Dim iID As Long
Dim tR As RECT
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
Dim tBI As TBBUTTONINFO
iID = m_tBInfo(iButton).wID
tBI.cbSize = LenB(tBI)
tBI.dwMask = TBIF_STYLE
tBI.fsStyle = eStyle
If m_tBInfo(iButton).bShowText = False And (GetWindowLong(m_hWndToolBar,
GWL_STYLE) And TBSTYLE_LIST) = TBSTYLE_LIST Then
tBI.dwMask = tBI.dwMask Or TBIF_SIZE
SendMessage m_hWndToolBar, TB_GETITEMRECT, iButton, tR
tBI.cx = tR.Right - tR.Left
End If
SendMessage m_hWndToolBar, TB_SETBUTTONINFO, iID, tBI
m_tBInfo(iButton).eStyle = tBI.fsStyle
End If
End Property
Public Property Get ButtonTextWrap(ByVal vButton As Variant) As Boolean
Dim iButton As Long
Dim iID As Long
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
iID = m_tBInfo(iButton).wID
ButtonTextWrap = pbGetState(iID, TBSTATE_WRAP)
End If
End Property
Public Property Let ButtonTextWrap(ByVal vButton As Variant, ByVal bState As
Boolean)
Dim iButton As Long
Dim iID As Long
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
iID = m_tBInfo(iButton).wID
pbSetState iID, TBSTATE_WRAP, bState
End If
End Property
Public Property Get ButtonTextEllipses(ByVal vButton As Variant) As Boolean
Dim iButton As Long
Dim iID As Long
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
iID = m_tBInfo(iButton).wID
ButtonTextEllipses = pbGetState(iID, TBSTATE_ELLIPSES)
End If
End Property
Public Property Let ButtonTextEllipses(ByVal vButton As Variant, ByVal bState
As Boolean)
Dim iButton As Long
Dim iID As Long
iButton = ButtonIndex(vButton)
If (iButton <> -1) Then
iID = m_tBInfo(iButton).wID
pbSetState iID, TBSTATE_ELLIPSES, bState
End If
End Property
Private Function pbGetState(ByVal iIDBtn As Long, ByVal fStateFlag As
ectbButtonStates) As Boolean
Dim fState As Long
fState = SendMessageLong(m_hWndToolBar, TB_GETSTATE, iIDBtn, 0)
pbGetState = ((fState And fStateFlag) = fStateFlag)
End Function
Private Function pbGetState2(ByVal hWndToolbar As Long, ByVal iIDBtn As Long,
ByVal fStateFlag As ectbButtonStates) As Boolean
Dim fState As Long
fState = SendMessageLong(hWndToolbar, TB_GETSTATE, iIDBtn, 0)
pbGetState2 = ((fState And fStateFlag) = fStateFlag)
End Function
Private Function pbSetState(ByVal iIDBtn As Long, ByVal fStateFlag As
ectbButtonStates, ByVal bState As Boolean)
Dim fState As Long
fState = SendMessageLong(m_hWndToolBar, TB_GETSTATE, iIDBtn, 0)
If (bState) Then
fState = fState Or fStateFlag
Else
fState = fState And Not fStateFlag
End If
If (SendMessageLong(m_hWndToolBar, TB_SETSTATE, iIDBtn, fState) = 0) Then
debugmsg m_sCtlName & ",Button state failed"
Else
pbSetState = True
End If
End Function
Private Function pbSetState2(ByVal hWndToolbar As Long, ByVal iIDBtn As Long,
ByVal fStateFlag As ectbButtonStates, ByVal bState As Boolean)
Dim fState As Long
fState = SendMessageLong(hWndToolbar, TB_GETSTATE, iIDBtn, 0)
If (bState) Then
fState = fState Or fStateFlag
Else
fState = fState And Not fStateFlag
End If
If (SendMessageLong(hWndToolbar, TB_SETSTATE, iIDBtn, fState) = 0) Then
debugmsg m_sCtlName & ",Button state failed"
Else
pbSetState2 = True
End If
End Function
Public Property Get hwnd() As Long
hwnd = m_hWndToolBar
End Property
Public Property Get TitleBarModifier() As Boolean
TitleBarModifier = g_bTitleBarModifier
End Property
Public Property Let TitleBarModifier(ByVal bState As Boolean)
g_bTitleBarModifier = bState
If bState Then
'AttachTitleBarMod m_hWndParentForm
Else
'DetachTitleBarMod m_hWndParentForm
End If
End Property
Public Sub DestroyToolBar()
Dim i As Long
Dim iU As Long
'On Error Resume Next
'We need to clean up our windows
debugmsg m_sCtlName & ",DestroyToolBar"
pSubClass False
If (m_hWndToolBar <> 0) Then
' Remove from tooltip:
RemoveFromToolTip m_hWndToolBar
' Clear me from keyboard hook:
mToolbar.DetachKeyboardHook Me
If Not (m_lPtrMenu = 0) Then
RemoveProp m_hWndToolBar, "vbalTbar:OwnsMenu:" & m_lPtrMenu
m_lPtrMenu = 0
End If
' Can't use button count - the buttons can all be removed before
' we get here!
iU = UBound(m_tBInfo)
For i = 0 To iU
If Not (m_tBInfo(i).hWndCapture = 0) Then
debugmsg m_sCtlName & ",Resetting parent:" & m_tBInfo(i).hWndCapture
'SetParent m_tBInfo(i).hWndCapture, m_tBInfo(i).hWndParentOrig
End If
Next i
ShowWindow m_hWndToolBar, SW_HIDE
SetParent m_hWndToolBar, 0
DestroyWindow m_hWndToolBar
RemoveProp m_hWndToolBar, "vbalTbar:ControlPtr"
m_hWndToolBar = 0
End If
If Not (m_hWndParentForm = 0) Then
RemoveProp m_hWndParentForm, "vbalTbar:MDIClient"
m_hWndParentForm = 0
End If
Set m_cMenu = Nothing
Err.Clear
On Error GoTo 0
End Sub
Public Sub CreateFromMenu( _
ByRef cMenu As Object _
)
CreateFromMenu2 cMenu, CTBMenuStyle
m_bCreateFromMenu2 = False
End Sub
Public Sub CreateFromMenu2( _
ByRef cMenu As Object, _
Optional ByVal eStyle As ECTBToolbarFromMenuStyle, _
Optional ByVal sMenuParentKey As String _
)
Dim i As Long
Dim lIndexSearch As Long
Dim hSubMenu As Long
Dim sCaption As String
Dim iPos As Long
Dim bEnabled As Boolean
Dim bVisible As Boolean
Dim sKey As String
Dim iIcon As Long
Dim tMII As MENUITEMINFO
Dim lR As Long
Dim lID As Long
Dim iB As Long
Dim eBtnStyle As ECTBToolButtonSyle
Dim lThisGroupCount As Long
Dim lThisGroup() As Long
Dim iThisGroupCheckIndex As Long
Dim iThis As Long
Dim sHelptext As String
Dim lhWndLock As Long
If Not (m_lPtrMenu = 0) Then
RemoveProp m_hWndParentForm, "vbalTbar:OwnsMenu:" & m_lPtrMenu
m_lPtrMenu = 0
End If
If m_hWndToolBar = 0 Then
If eStyle = CTBMenuStyle Then
CreateToolbar , True, True, True, 0
Else
CreateToolbar , False, False, False, 0
End If
Else
If IsWindowVisible(m_hWndToolBar) Then
LockWindowUpdate m_hWndToolBar
lhWndLock = m_hWndToolBar
End If
' remove all buttons:
For i = ButtonCount - 1 To 0 Step -1
RemoveButton i
Next i
End If
iThisGroupCheckIndex = -1
' Now add buttons according to menu:
With cMenu
If .Count > 0 Then
If sMenuParentKey <> "" Then
lIndexSearch = .IndexForKey(sMenuParentKey)
For i = 1 To .Count
If (.ItemParentIndex(i) = lIndexSearch) Then
m_hMenu = .hMenu(i)
Exit For
End If
Next i
Else
m_hMenu = .hMenu(1)
End If
m_eCreateFromMenuStyle = eStyle
m_bCreateFromMenu2 = True
For i = 1 To .Count
' Is top level menu?
If .hMenu(i) = m_hMenu Then
' Get info about menu item:
iB = -1
sCaption = .Caption(i)
sKey = .ItemKey(i)
sHelptext = .HelpText(i)
lID = .IDForItem(i)
bVisible = .Visible(i)
' Find if this menu has submenus:
tMII.fMask = MIIM_SUBMENU Or MIIM_STATE
tMII.cbSize = LenB(tMII)
lR = GetMenuItemInfo(.hMenu(i), lID, False, tMII)
hSubMenu = tMII.hSubMenu
bEnabled = ((tMII.fState And &H1) = &H0)
If (sCaption = "-") Then
eBtnStyle = CTBSeparator
Else
eBtnStyle = CTBAutoSize
If eStyle = CTBToolbarStyle Then
If Not (hSubMenu = 0) Then
eBtnStyle = eBtnStyle Or CTBDropDown
End If
End If
End If
' Add the button:
If eStyle = CTBMenuStyle Then
iB = plAddButton(m_hWndToolBar, NewButtonID, , , , ,
sCaption, CTBAutoSize, sKey)
Else
iIcon = .ItemIcon(i)
iB = plAddButton(m_hWndToolBar, NewButtonID, sHelptext,
iIcon, , , sCaption, eBtnStyle, sKey)
If eBtnStyle = CTBSeparator Then
If iThisGroupCheckIndex > -1 Then
For iThis = 1 To lThisGroupCount
ButtonStyle(lThisGroup(iThis)) = CTBCheckGroup Or
CTBAutoSize 'ButtonStyle(lThisGroup(iThis) Or
CTBCheckGroup)
Next iThis
ButtonChecked(iThisGroupCheckIndex) = True
End If
lThisGroupCount = 0
iThisGroupCheckIndex = -1
Else
lThisGroupCount = lThisGroupCount + 1
ReDim Preserve lThisGroup(1 To lThisGroupCount) As Long
lThisGroup(lThisGroupCount) = iB
If .RadioCheck(i) Then
iThisGroupCheckIndex = iB
ElseIf .Checked(i) Then
ButtonChecked(iB) = True
End If
End If
End If
ButtonVisible(iB) = bVisible
'Debug.Print "Added " & sCaption, iB, bEnabled
If iB > -1 Then
m_tBInfo(iB).hSubMenu = hSubMenu
ButtonEnabled(iB) = bEnabled
If eStyle = CTBToolbarStyle Then
If (GetWindowLong(m_hWndToolBar, GWL_STYLE) And
TBSTYLE_LIST) = TBSTYLE_LIST Then
ButtonTextVisible(iB) = False
End If
End If
End If
End If
Next i
End If
End With
If lhWndLock <> 0 Then
LockWindowUpdate 0
End If
' Store a reference to the item:
m_lPtrMenu = ObjPtr(cMenu)
SetProp m_hWndParentForm, "vbalTbar:OwnsMenu:" & m_lPtrMenu, ObjPtr(Me)
End Sub
Public Property Get DropDownAlign() As ECTBDropDownAlign
'
DropDownAlign = m_eDropDownAlign
'
End Property
Public Property Let DropDownAlign(ByVal eAlign As ECTBDropDownAlign)
m_eDropDownAlign = eAlign
End Property
Public Sub CreateToolbar( _
Optional ButtonSize As Integer = 16, _
Optional StyleList As Boolean, _
Optional WithText As Boolean, _
Optional Wrappable As Boolean, _
Optional PicSize As Integer)
On Error Resume Next
Dim Button As TBBUTTON
Dim lParam As Long
Dim ListButtons As Boolean
Dim dwStyle As Long
Dim dwExStyle As Long
Dim lExStyle As Long
Dim lhWndClient As Long
Dim hWndParent As Long
DestroyToolBar
m_bWrappable = Wrappable
m_bWithText = WithText
hWndParent = UserControl.Parent.hwnd
dwStyle = WS_CHILD Or WS_VISIBLE Or WS_CLIPCHILDREN
dwStyle = dwStyle Or CCS_NOPARENTALIGN Or CCS_NORESIZE Or CCS_NODIVIDER
dwStyle = dwStyle Or TBSTYLE_TOOLTIPS Or TBSTYLE_FLAT
'dwStyle = dwStyle Or CCS_ADJUSTABLE
If (StyleList) Then
dwStyle = dwStyle Or TBSTYLE_LIST
End If
If (Wrappable) Then
dwStyle = dwStyle Or TBSTYLE_WRAPABLE
End If
dwExStyle = WS_EX_TOOLWINDOW
lExStyle = GetWindowLong(hWndParent, GWL_EXSTYLE)
lExStyle = lExStyle And (WS_EX_RIGHT Or WS_EX_RTLREADING)
dwExStyle = dwExStyle Or lExStyle
m_hWndToolBar = CreateWindowEX(dwExStyle, "ToolbarWindow32", "", _
dwStyle, _
0, 0, 0, 0, UserControl.Parent.hwnd, 0&, App.hInstance, 0&)
If m_hWndToolBar <> 0 Then
SendMessageLong m_hWndToolBar, TB_SETPARENT, hWndParent, 0
m_lR = SendMessageLong(m_hWndToolBar, TB_BUTTONSTRUCTSIZE, LenB(Button),
0)
AddBitmapIfRequired m_hWndToolBar
m_lOrigButtonSize = ButtonSize
If m_eImageSourceType <> -1 Then
lParam = ButtonSize + (ButtonSize * &H10000)
Else
lParam = 0
End If
m_lR = SendMessageLong(m_hWndToolBar, TB_SETBITMAPSIZE, 0, lParam)
SetProp m_hWndToolBar, "vbalTbar:ControlPtr", ObjPtr(Me)
m_hWndParentForm = UserControl.Parent.hwnd
lhWndClient = FindWindowEx(m_hWndParentForm, 0, "MDIClient", ByVal 0&)
SetProp m_hWndToolBar, "vbalTbar:MDIClient", lhWndClient
pSubClass True, m_hWndParentForm
AddToToolTip m_hWndToolBar
' Start checking for accelerator key presses here:
mToolbar.AttachKeyboardHook Me
Set m_cMenu = New cTbarMenu
End If
End Sub
Public Property Get ListStyle() As Boolean
ListStyle = pbIsStyle(TBSTYLE_LIST)
End Property
Public Property Let ListStyle(ByVal bState As Boolean)
pbSetStyle TBSTYLE_LIST, bState
End Property
Public Property Get Wrappable() As Boolean
Wrappable = pbIsStyle(TBSTYLE_WRAPABLE)
End Property
Public Property Let Wrappable(ByVal bState As Boolean)
pbSetStyle TBSTYLE_WRAPABLE, bState
End Property
Private Function pbSetStyle(ByVal lStyleBit As Long, ByVal bState As Boolean)
As Boolean
Dim lS As Long
Dim iB As Long
If Not pbIsStyle(lStyleBit) = bState Then
lS = GetWindowLong(m_hWndToolBar, GWL_STYLE)
If bState Then
lS = lS Or lStyleBit
Else
lS = lS And Not lStyleBit
End If
SetWindowLong m_hWndToolBar, GWL_STYLE, lS
Dim i As Long
For iB = 0 To ButtonCount - 1
ButtonTextVisible(iB) = Not (ButtonTextVisible(iB))
ButtonTextVisible(iB) = Not (ButtonTextVisible(iB))
Next iB
ResizeToolbar
End If
End Function
Private Function pbIsStyle(ByVal lStyleBit As Long) As Boolean
Dim lS As Long
If m_hWndToolBar <> 0 Then
lS = GetWindowLong(m_hWndToolBar, GWL_STYLE)
If (lS And lStyleBit) = lStyleBit Then
pbIsStyle = True
End If
End If
End Function
Public Property Let ImageSource( _
ByVal eType As ECTBImageSourceTypes _
)
m_eImageSourceType = eType
End Property
Public Property Let ImageResourceID(ByVal lResourceId As Long)
m_lResourceID = lResourceId
End Property
Public Property Let ImageResourcehInstance(ByVal hInstance As Long)
m_hInstance = hInstance
End Property
Public Property Let ImageFile(ByVal sFIle As String)
m_sFileName = sFIle
End Property
Public Sub SetImageList( _
ByVal vThis As Variant, _
Optional ByVal eType As ECTBImageListTypes = CTBImageListNormal _
)
Dim hIml As Long
' Set the ImageList handle property either from a VB
' image list or directly:
If VarType(vThis) = vbObject Then
' Assume VB ImageList control. Note that unless
' some call has been made to an object within a
' VB ImageList the image list itself is not
' created. Therefore hImageList returns error. So
' ensure that the ImageList has been initialised by
' drawing into nowhere:
On Error Resume Next
' Get the image list initialised..
vThis.ListImages(1).Draw 0, 0, 0, 1
hIml = vThis.hImageList
If (Err.Number <> 0) Then
Err.Clear
hIml = vThis.hIml
If Err.Number <> 0 Then
hIml = 0
End If
End If
On Error GoTo 0
ElseIf VarType(vThis) = vbLong Then
' Assume ImageList handle:
hIml = vThis
Else
Err.Raise vbObjectError + 1049, "cToolbar." & App.EXEName, "ImageList
property expects ImageList object or long hImageList handle."
End If
' If we have a valid image list, then associate it with the control:
Select Case eType
Case CTBImageListDisabled
m_hImlDis = hIml
Case CTBImageListHot
m_hImlHot = hIml
Case CTBImageListNormal
m_hIml = hIml
End Select
If m_hWndToolBar <> 0 Then
If (hIml <> 0) Then
m_lR = SendMessageLong(m_hWndToolBar, eType, 0, hIml)
End If
End If
End Sub
Public Property Let ImagePicture(ByVal picThis As StdPicture)
Set m_pic = picThis
End Property
Public Property Let ImageStandardBitmapType(ByVal eType As
ECTBStandardImageSourceTypes)
m_eStandardType = eType
End Property
Private Sub AddBitmapIfRequired(ByVal lhWndToolbar As Long)
Dim tbab As TBADDBITMAP
Select Case m_eImageSourceType
Case CTBStandardImageSources
SendMessageLong lhWndToolbar, TB_LOADIMAGES, m_eStandardType,
HINST_COMMCTRL
Case CTBPicture
tbab.hInst = 0
tbab.nID = hBmpFromPicture(m_pic)
' Add the bitmap containing button images to the toolbar.
m_lR = SendMessage(lhWndToolbar, TB_ADDBITMAP, 54, tbab)
Case CTBLoadFromFile
tbab.hInst = 0
tbab.nID = LoadImage(0, m_sFileName, IMAGE_BITMAP, 0, 0, _
LR_LOADFROMFILE Or LR_LOADMAP3DCOLORS Or LR_LOADTRANSPARENT)
m_lR = SendMessage(lhWndToolbar, TB_ADDBITMAP, 54, tbab)
Case CTBResourceBitmap
tbab.hInst = 0
tbab.nID = LoadImageLong(m_hInstance, m_lResourceID, IMAGE_BITMAP, 0, 0, _
LR_LOADMAP3DCOLORS Or LR_LOADTRANSPARENT)
m_lR = SendMessage(lhWndToolbar, TB_ADDBITMAP, 54, tbab)
Case CTBExternalImageList
If m_hIml <> 0 Then
SendMessageLong lhWndToolbar, CTBImageListNormal, 0, m_hIml
End If
If m_hImlHot <> 0 Then
SendMessageLong lhWndToolbar, CTBImageListHot, 0, m_hImlHot
End If
If m_hImlDis <> 0 Then
SendMessageLong lhWndToolbar, CTBImageListDisabled, 0, m_hImlDis
End If
End Select
End Sub
Public Sub RemoveButton(ByVal vButton As Variant)
Dim iB As Integer
Dim iCount As Long
Dim iNewCount As Long
Dim i As Long
Dim iT As Long
Dim sCaption As String
iB = ButtonIndex(vButton)
If (iB > -1) Then
iCount = ButtonCount
If iCount <= 0 Then
Debug.Assert iCount > 0
Else
If Not (m_tBInfo(iB).hWndCapture = 0) Then
'SetParent m_tBInfo(iB).hWndCapture, m_tBInfo(iB).hWndParentOrig
End If
sCaption = m_tBInfo(iB).sCaption
m_lR = SendMessageLong(m_hWndToolBar, TB_DELETEBUTTON, iB, 0)
If m_lMajorVer < 4 Or (m_lMajorVer = 4 And m_lMinorVer < 71) Then
iNewCount = ButtonCount
If iNewCount = 0 Then
Erase m_tBInfo
Else
For i = iB To iNewCount - 1
LSet m_tBInfo(i) = m_tBInfo(i + 1)
Next i
ReDim Preserve m_tBInfo(0 To iNewCount - 1) As ButtonInfoStore
End If
plRemoveString sCaption
End If
End If
End If
End Sub
Public Sub AddControl( _
ByVal lhWnd As Long, _
Optional ByVal vButtonBefore As Variant, _
Optional ByVal sKey As String = "" _
)
Dim lButton As Long
lButton = plAddButton(m_hWndToolBar, NewButtonID, , , vButtonBefore, , ,
CTBNormal, sKey)
If lButton > -1 Then
SetControlSub lhWnd, lButton
End If
End Sub
Public Sub SetControl( _
ByVal lhWnd As Long, _
ByVal vButton As Variant _
)
Dim iB As Long
iB = ButtonIndex(vButton)
If (iB <> -1) Then
SetControlSub lhWnd, iB
End If
End Sub
Private Sub SetControlSub(ByVal lhWnd As Long, ByVal lButton As Long)
Dim tR As RECT
Dim lhWndParent As Long
ButtonEnabled(lButton) = False
GetWindowRect lhWnd, tR
ButtonWidth(lButton) = tR.Right - tR.Left
If Not (lhWnd = 0) Then
lhWndParent = GetParent(lhWnd)
'SetParent lhWnd, m_hWndToolBar
End If
With m_tBInfo(lButton)
.bControl = True
.hWndCapture = lhWnd
.hWndParentOrig = lhWndParent
.xWidth = tR.Right - tR.Left
End With
If Not (lhWnd = 0) Then
moveChildWindow lButton
End If
End Sub
Public Property Get ControlStretch(ByVal vButton As Variant) As Boolean
Dim iB As Long
iB = ButtonIndex(vButton)
If (iB <> -1) Then
ControlStretch = m_tBInfo(iB).bStretch
End If
End Property
Public Property Let ControlStretch(ByVal vButton As Variant, ByVal bState As
Boolean)
Dim iB As Long
iB = ButtonIndex(vButton)
If (iB <> -1) Then
m_tBInfo(iB).bStretch = bState
End If
End Property
Private Function plAddButton( _
ByVal hWndToolbar As Long, _
ByVal lIDCommand As Long, _
Optional ByVal sTip As String = "", _
Optional ByVal iImage As Integer = -1, _
Optional ByVal vButtonBefore As Variant, _
Optional ByVal xLarge As Integer = 0, _
Optional ByVal sButtonText As String, _
Optional ByVal eButtonStyle As ECTBToolButtonSyle, _
Optional ByVal sKey As String = "" _
) As Long
Dim tB As TBBUTTON
Dim lParam As Long
Dim iB As Integer, i As Integer
Dim bInsert As Boolean
Dim iCount As Long
Dim idString As Long
plAddButton = -1
iCount = plButtonCount(hWndToolbar)
If iCount = 0 Then
' Make sure we can have drop-down buttons:
SendMessageLong hWndToolbar, TB_SETEXTENDEDSTYLE, 0,
TBSTYLE_EX_DRAWDDARROWS
End If
' Are we adding or inserting?
If Not (IsMissing(vButtonBefore)) Then
iB = ButtonIndex(vButtonBefore)
If (iB > -1) Then
bInsert = True
End If
End If
' Do we need to add a new string for this button?
idString = -1
If Len(sButtonText) > 0 Then
idString = plAddStringIfRequired(hWndToolbar, sButtonText)
End If
With tB
.iBitmap = iImage
.idCommand = lIDCommand
.fsState = TBSTATE_ENABLED
.fsStyle = eButtonStyle
.dwData = 0
.iString = idString
End With
If (bInsert) Then
m_lR = SendMessage(hWndToolbar, TB_INSERTBUTTON, iB, tB)
If (m_lR <> 0) Then
If hWndToolbar = m_hWndToolBar Then
' We need to insert into the structure:
ReDim Preserve m_tBInfo(0 To iCount) As ButtonInfoStore
For i = iCount To iB + 1 Step -1
LSet m_tBInfo(i) = m_tBInfo(i - 1)
Next i
With m_tBInfo(iB)
.wID = tB.idCommand
.iImage = iImage
.sTipText = sTip
.iLarge = xLarge
.sKey = sKey
.bShowText = m_bWithText
.sCaption = sButtonText
.eStyle = eButtonStyle
.hWndCapture = 0
.hWndParentOrig = 0
.bControl = False
.bStretch = False
.hSubMenu = 0
End With
plAddButton = iB
End If
End If
Else
m_lR = SendMessage(hWndToolbar, TB_ADDBUTTONS, 1, tB)
If (m_lR <> 0) Then
' Add this button to the list:
If hWndToolbar = m_hWndToolBar Then
ReDim Preserve m_tBInfo(0 To iCount) As ButtonInfoStore
With m_tBInfo(iCount)
.wID = tB.idCommand
.iImage = iImage
.sTipText = sTip
.iLarge = xLarge
.sKey = sKey
.bShowText = m_bWithText
.sCaption = sButtonText
.eStyle = eButtonStyle
.hWndCapture = 0
.hWndParentOrig = 0
.bControl = False
.bStretch = False
.hSubMenu = 0
End With
plAddButton = iCount
End If
End If
End If
' Size window:
pResizeToolbar hWndToolbar
End Function
Public Sub AddButton( _
Optional ByVal sTip As String = "", _
Optional ByVal iImage As Integer = -1, _
Optional ByVal vButtonBefore As Variant, _
Optional ByVal xLarge As Integer = 0, _
Optional ByVal sButtonText As String, _
Optional ByVal eButtonStyle As ECTBToolButtonSyle, _
Optional ByVal sKey As String = "" _
)
plAddButton m_hWndToolBar, NewButtonID, sTip, iImage, vButtonBefore, xLarge,
sButtonText, eButtonStyle, sKey
End Sub
Private Function plAddStringIfRequired(ByVal hWndToolbar As Long, ByVal sString
As String) As Long
Dim ID As Long
Dim i As Long
Dim b() As Byte
Dim sAccel As String
' Signal default:
ID = -1
If hWndToolbar = m_hWndToolBar Then
' Check if we already have the string - if we do, then use that
For i = 1 To m_lStringIDCount
If (m_sString(i) = sString) Then
ID = m_lStringID(i)
Exit For
End If
Next i
End If
' If string not found, then add one:
If (ID = -1) Then
b = StrConv(sString, vbFromUnicode)
i = UBound(b) + 2
ReDim Preserve b(0 To i) As Byte
b(i - 1) = 0
b(i) = 0
ID = SendMessage(hWndToolbar, TB_ADDSTRING, 0, b(0))
If m_hWndToolBar = hWndToolbar Then
m_lStringIDCount = m_lStringIDCount + 1
ReDim Preserve m_sString(1 To m_lStringIDCount) As String
ReDim Preserve m_lStringID(1 To m_lStringIDCount) As Long
m_sString(m_lStringIDCount) = sString
m_lStringID(m_lStringIDCount) = ID
End If
End If
' Return the Id:
plAddStringIfRequired = ID
End Function
Private Function psGetAccelerator(ByVal sString As String) As String
Dim iPos As Long
iPos = InStr(sString, "&")
If iPos <> 0 And iPos <> InStr(sString, "&&") Then
If iPos < Len(sString) Then
psGetAccelerator = UCase$(Mid$(sString, iPos + 1, 1))
End If
End If
End Function
Private Function plRemoveString(ByVal sCaption As String)
' unfortunately you cannot remove a string
' from the toolbar itself (because, as MSJ puts it,
' ".. the toolbar is braindead ..")
End Function
Public Sub ResizeToolbar()
pResizeToolbar m_hWndToolBar
End Sub
Private Sub pResizeToolbar(ByVal hWndToolbar As Long)
Dim tR As RECT, tPR As RECT, tCR As RECT
Dim tP As POINTAPI
Dim lCount As Long
Dim i As Long
Dim Button As TBBUTTON
Dim lW As Long, lH As Long
Dim bInRebar As Boolean
Dim lhWnd As Long
' Get number of buttons:
lCount = SendMessageLong(hWndToolbar, TB_BUTTONCOUNT, 0, 0)
If (lCount > 0) Then
' Get the total length:
lW = plToolbarWidth(hWndToolbar)
lH = plToolbarHeight(hWndToolbar)
' Get rectangle for toolbar. Unfortunately the rebar doesn't
' seem to like ClientToScreen and gives the wrong answer! So
' do it manually:
GetWindowRect hWndToolbar, tR
GetWindowRect GetParent(hWndToolbar), tPR
GetClientRect GetParent(hWndToolbar), tCR
'Debug.Print tR.Top, tPR.Top, tCR.Top
tP.x = tR.Left - tPR.Left - 2
tP.y = tR.Top - tPR.Top - 2
' Make window correct size:
If (m_bWrappable) Then
SetWindowPos hWndToolbar, 0, tP.x, tP.y, lW, lH, SWP_FRAMECHANGED Or
SWP_NOMOVE Or SWP_NOOWNERZORDER
Else
SetWindowPos hWndToolbar, 0, tP.x, tP.y, lW, lH, SWP_FRAMECHANGED Or
SWP_NOMOVE Or SWP_NOOWNERZORDER
End If
If hWndToolbar = m_hWndToolBar Then
For i = 0 To lCount - 1
If Not (m_tBInfo(i).hWndCapture = 0) Then
moveChildWindow i
End If
Next i
correctRebarIfExists
End If
End If
End Sub
Private Sub correctRebarIfExists()
Dim lhWnd As Long
Dim sBuf As String
Dim iPos As Long
If IsWindowVisible(m_hWndToolBar) Then
lhWnd = GetParent(m_hWndToolBar)
sBuf = String$(256, 0)
GetClassName lhWnd, sBuf, 255
iPos = InStr(sBuf, vbNullChar)
If iPos > 1 Then sBuf = Left$(sBuf, iPos - 1)
'Debug.Print lhWnd, sBuf
If sBuf = REBARCLASSNAME Then
SendMessageLong lhWnd, WM_SIZE, 0, 0
Exit Sub
End If
lhWnd = GetParent(lhWnd)
sBuf = String$(256, 0)
GetClassName lhWnd, sBuf, 255
iPos = InStr(sBuf, vbNullChar)
If iPos > 1 Then sBuf = Left$(sBuf, iPos - 1)
'Debug.Print lhWnd, sBuf
'If sBuf = REBARCLASSNAME Then
SendMessageLong lhWnd, WM_SIZE, 0, 0
Exit Sub
'End If
End If
End Sub
Public Property Get ToolbarWidth() As Long
ToolbarWidth = plToolbarWidth(m_hWndToolBar)
End Property
Private Property Get plToolbarWidth(ByVal hWndToolbar As Long) As Long
Dim lSize As Long
Dim lCount As Long
Dim lWidth As Long
Dim i As Long
Dim rc As RECT
' Get number of buttons:
lCount = SendMessageLong(hWndToolbar, TB_BUTTONCOUNT, 0, 0)
If (lCount > 0) Then
' Get the total length:
For i = 0 To lCount - 1
If (plButtonVisible(hWndToolbar, i)) Then
If (m_tBInfo(i).bControl) Then
ButtonWidth(i) = m_tBInfo(i).xWidth
moveChildWindow i
Else
SendMessage hWndToolbar, TB_GETITEMRECT, i, rc
lSize = lSize + rc.Right - rc.Left
End If
End If
Next i
plToolbarWidth = lSize
End If
End Property
Public Property Get ToolbarHeight() As Long
ToolbarHeight = plToolbarHeight(m_hWndToolBar)
End Property
Private Property Get plToolbarHeight(ByVal hWndToolbar As Long) As Long
Dim lSize As Long
Dim lCount As Long
Dim i As Long
Dim rc As RECT
' Get number of buttons:
lCount = SendMessageLong(hWndToolbar, TB_BUTTONCOUNT, 0, 0)
If (lCount > 0) Then
' Get the height:
i = 0
Do While plButtonVisible(hWndToolbar, i) = False
i = i + 1
If i >= lCount Then
Exit Do
End If
Loop
SendMessage hWndToolbar, TB_GETITEMRECT, i, rc
plToolbarHeight = rc.Bottom
End If
End Property
Public Sub ButtonSize(xWidth As Integer, xHeight As Integer)
m_iButtonWidth = xWidth
m_iButtonHeight = xHeight
SendMessageLong m_hWndToolBar, TB_AUTOSIZE, 0, 0
ResizeToolbar
End Sub
Public Sub GetDropDownPosition( _
ByVal ID As Integer, _
ByRef x As Long, _
ByRef y As Long _
)
Dim rc As RECT
Dim tP As POINTAPI
Dim i As Long
Dim lMappedID As Long
If Not m_hWndChevronToolbar = 0 Then
' need to modify ID so it is relative to the chevron toolbar,
' rather than the
For i = 1 To m_iChevronIDMapCount
If ID = m_iChevronIDMap(i) Then
lMappedID = i - 1
Exit For
End If
Next i
SendMessage m_hWndChevronToolbar, TB_GETITEMRECT, lMappedID, rc
tP.x = rc.Left
tP.y = rc.Bottom
MapWindowPoints m_hWndChevronToolbar, m_hWndParentForm, tP, 1
Else
SendMessage m_hWndToolBar, TB_GETITEMRECT, ID, rc
tP.x = rc.Left
tP.y = rc.Bottom
MapWindowPoints m_hWndToolBar, m_hWndParentForm, tP, 1
End If
x = tP.x * Screen.TwipsPerPixelX
y = tP.y * Screen.TwipsPerPixelY
End Sub
Private Sub pInitialise()
Dim tIccex As CommonControlsEx
If Not (UserControl.Ambient.UserMode) Then
' We are in design mode:
lblInfo.Caption = "Toolbar Control: " & UserControl.Extender.Name
Else
UserControl.BorderStyle() = 0
lblInfo.Visible = False
UserControl.Extender.Left = -UserControl.Width * 2
' We are in run
With tIccex
.dwSize = LenB(tIccex)
.dwICC = ICC_BAR_CLASSES
End With
'We need to make this call to make sure the common controls are loaded
InitCommonControlsEx tIccex
m_hWndToolBar = 0
End If
End Sub
Private Sub pSubClass(ByVal bState As Boolean, Optional ByVal lhWnd As Long = 0)
Static s_lhWndSave As Long
If (m_bInSubClass <> bState) Then
If (bState) Then
'Debug.Print "Subclassing:Start"
Debug.Assert (lhWnd <> 0)
If (s_lhWndSave <> 0) Then
pSubClass False
End If
s_lhWndSave = lhWnd
pAttMsg lhWnd, WM_COMMAND
pAttMsg lhWnd, WM_MOUSEMOVE
pAttMsg lhWnd, WM_LBUTTONDOWN
pAttMsg lhWnd, WM_LBUTTONUP
pAttMsg lhWnd, WM_RBUTTONDOWN
pAttMsg lhWnd, WM_RBUTTONUP
pAttMsg lhWnd, WM_MBUTTONDOWN
pAttMsg lhWnd, WM_MBUTTONUP
pAttMsg lhWnd, WM_NOTIFY
pAttMsg m_hWndToolBar, WM_SIZE
pAttMsg m_hWndToolBar, WM_WINDOWPOSCHANGING
pAttMsg m_hWndToolBar, WM_WINDOWPOSCHANGED
pAttMsg m_hWndToolBar, WM_SHOWWINDOW
pAttMsg m_hWndToolBar, WM_DESTROY
pAttMsg lhWnd, WM_PARENTNOTIFY
pAttMsg lhWnd, WM_DESTROY
s_lhWndSave = lhWnd
m_bInSubClass = True
Else
'Debug.Print "Subclassing:End"
pDelMsg s_lhWndSave, WM_COMMAND
pDelMsg s_lhWndSave, WM_MOUSEMOVE
pDelMsg s_lhWndSave, WM_LBUTTONDOWN
pDelMsg s_lhWndSave, WM_LBUTTONUP
pDelMsg s_lhWndSave, WM_RBUTTONDOWN
pDelMsg s_lhWndSave, WM_RBUTTONUP
pDelMsg s_lhWndSave, WM_MBUTTONDOWN
pDelMsg s_lhWndSave, WM_MBUTTONUP
pDelMsg s_lhWndSave, WM_NOTIFY
pDelMsg m_hWndToolBar, WM_SIZE
pDelMsg m_hWndToolBar, WM_WINDOWPOSCHANGING
pDelMsg m_hWndToolBar, WM_WINDOWPOSCHANGED
pDelMsg m_hWndToolBar, WM_SHOWWINDOW
pDelMsg m_hWndToolBar, WM_DESTROY
pDelMsg s_lhWndSave, WM_PARENTNOTIFY
pDelMsg s_lhWndSave, WM_DESTROY
s_lhWndSave = 0
m_bInSubClass = False
End If
End If
End Sub
Private Sub pTerminate()
' Clear toolbar window:
DestroyToolBar
' Background picture -> nothing if any:
Set m_pic = Nothing
End Sub
Private Sub pAttMsg(ByVal lhWnd As Long, ByVal lMsg As Long)
AttachMessage Me, lhWnd, lMsg
End Sub
Private Sub pDelMsg(ByVal lhWnd As Long, ByVal lMsg As Long)
DetachMessage Me, lhWnd, lMsg
End Sub
Public Function RaiseButtonClick(ByVal iIDButton As Long)
' Required as part of the WM_COMMAND handler:
RaiseEvent ButtonClick(iIDButton)
End Function
Private Property Let ISubclass_MsgResponse(ByVal RHS As EMsgResponse)
'
End Property
Private Property Get ISubclass_MsgResponse() As EMsgResponse
ISubclass_MsgResponse = emrPreprocess
End Property
Private Function ISubclass_WindowProc(ByVal hwnd As Long, ByVal iMsg As Long,
ByVal wParam As Long, ByVal lParam As Long) As Long
Dim msgStruct As msg
Dim hdr As NMHDR
Dim ttt As ToolTipText
Dim pt32 As POINTAPI
Dim ptx As Long
Dim pty As Long
Dim hWndOver As Long
Dim b() As Byte
Dim iB As Long
Dim ib2 As Long
Dim iBRaise As Long
Dim lButton As Long
Dim lPtr As Long
Dim iOld As Long, iNew As Long
Dim eReason As ECTBHotItemChangeReasonConstants
Dim bS As Boolean
Dim bCanInsert As Boolean
Dim bCanDelete As Boolean
Dim tR As RECT, tBR As RECT, tWR As RECT
Dim lAW As Long
Dim iStretchCount As Long
Dim bStretch As Boolean
Dim bControl As Boolean
Dim bSubMenu As Boolean
Dim wID As Long
Dim iNewCount As Long
Dim fwEvent As Long
Dim lIDChild As Long
Dim hWndChild As Long
Dim lhWnd As Long
Dim tWP As WINDOWPOS
Dim lFlag As Long
Dim lStyle As Long
On Error Resume Next
Select Case iMsg
Case WM_PARENTNOTIFY
fwEvent = (wParam And &HFFFF&)
lIDChild = (wParam And &H7FFF0000)
hWndChild = lParam
If fwEvent = WM_DESTROY Then
debugmsg m_sCtlName & ",Parent Notify:Destroy"
For lButton = ButtonCount - 1 To 0 Step -1
If m_tBInfo(lButton).hWndCapture = hWndChild Then
RemoveButton lButton
End If
Next lButton
End If
Case WM_DESTROY, WM_CLOSE, WM_SYSCOMMAND
If iMsg = WM_SYSCOMMAND Then
'Debug.Print wParam, SC_CLOSE
If wParam <> SC_CLOSE Then
Exit Function
End If
End If
debugmsg m_sCtlName & ",cToolbar:WM_DESTROY"
'pSubClass False
pTerminate
Case WM_SHOWWINDOW
Debug.Print "GOT WM_SHOWWINDOW"
If wParam = 0 Then
Debug.Print "Hiding"
m_bVisible = False
lFlag = SW_HIDE
Else
Debug.Print "Showing"
m_bVisible = True
lFlag = SW_SHOW
End If
' hiding window
For lButton = 0 To ButtonCount - 1
If m_tBInfo(lButton).hWndCapture <> 0 Then
ShowWindow m_tBInfo(lButton).hWndCapture, lFlag
'lStyle = GetWindowLong(m_tBInfo(lButton).hWndCapture, GWL_STYLE)
'If (wParam = 0) Then
' lStyle = lStyle And Not WS_VISIBLE
'Else
' lStyle = lStyle Or WS_VISIBLE
'End If
'SetWindowLong m_tBInfo(lButton).hWndCapture, GWL_STYLE, lStyle
End If
Next lButton
Case WM_COMMAND
If (lParam = m_hWndToolBar) Or (lParam = m_hWndChevronToolbar) Then
' This is the index of the button in the toolbar, which can be
different if the
' toolbar is a chevron:
iB = SendMessageLong(lParam, TB_COMMANDTOINDEX, wParam, 0)
' And this is the actual index of the button in the proper toolbar:
iBRaise = SendMessageLong(m_hWndToolBar, TB_COMMANDTOINDEX, wParam, 0)
If iB > -1 Then
bSubMenu = Not (m_tBInfo(iB).hSubMenu = 0)
If bSubMenu Then
If (m_tBInfo(iB).eStyle And CTBDropDown) = CTBDropDown Then
' sub menu is only accessible via drop down
bSubMenu = False
End If
End If
If bSubMenu Then
bS = ButtonPressed(iB)
ButtonPressed(iB) = True
' First tell the client we're about to show the menu
RaiseEvent ButtonClick(iBRaise)
' Now show the menu:
pMenuClick lParam, iB
ButtonPressed(iB) = False
ISubclass_WindowProc = 0
SendMessageLong m_hWndParentForm, WM_EXITMENULOOP, 0, 0
SendMessageLong m_hWndToolBar, TB_SETHOTITEM, -1, 0
Else
'Debug.Print "Items", m_tBInfo(iBRaise).sKey,
m_tBInfo(iBRaise).eStyle And &H2
pbSetState2 lParam, wParam, TBSTATE_PRESSED, True
If Not (m_hWndToolBar = lParam) Then
pbSetState2 m_hWndToolBar, wParam, TBSTATE_PRESSED, True
If ((m_tBInfo(iBRaise).eStyle And CTBCheck) = CTBCheck) Then
bS = (pbGetState2(lParam, wParam, TBSTATE_CHECKED))
'Debug.Print "Chevron Window Checked: "; bS
ButtonChecked(iBRaise) = bS
'Debug.Print "Toolbar Checked: "; ButtonChecked(iBRaise)
End If
End If
RaiseEvent ButtonClick(iBRaise)
pbSetState2 lParam, wParam, TBSTATE_PRESSED, False
If Not (lParam = m_hWndToolBar) Then
pbSetState2 m_hWndToolBar, wParam, TBSTATE_PRESSED, False
End If
If lParam = m_hWndChevronToolbar Then
SendMessageLong m_hWndParentForm, WM_EXITMENULOOP, 0, 0
End If
ISubclass_WindowProc = 0
End If
If (lParam = m_hWndToolBar) Then
If m_hMenu <> 0 Then
If m_bCreateFromMenu2 Then ' don't break existing apps
Dim cMenu As Object
Dim cT As Object
Dim iID As Long
CopyMemory cT, m_lPtrMenu, 4
Set cMenu = cT
CopyMemory cT, 0&, 4
iID =
cMenu.IDForItem(cMenu.IndexForKey(ButtonKey(iBRaise)))
cMenu.EmulateMenuClick iID
End If
End If
End If
End If
End If
Case WM_MOUSEMOVE, WM_LBUTTONDOWN, WM_LBUTTONUP, WM_RBUTTONDOWN,
WM_RBUTTONUP, WM_MBUTTONDOWN, WM_MBUTTONUP
With msgStruct
.lParam = lParam
.wParam = wParam
.message = iMsg
.hwnd = hwnd
End With
'Pass the structure
SendMessage hwndToolTip, TTM_RELAYEVENT, 0, msgStruct
Case WM_SIZE, WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED
' time to adjust any captured controls to match:
'GetWindowRect m_hWndToolBar, tR
If iMsg = WM_SIZE Then
lAW = lParam And &HFFFF& 'tR.right - tR.left + 1 'tWP.cx
Else
CopyMemory tWP, ByVal lParam, Len(tWP)
lAW = tWP.cx
End If
For lButton = 0 To ButtonCount - 1
If ButtonVisible(iB) Then
If m_tBInfo(lButton).bControl Then
bControl = True
bStretch = bStretch Or m_tBInfo(lButton).bStretch
If m_tBInfo(lButton).bStretch Then
iStretchCount = iStretchCount + 1
Else
SendMessage m_hWndToolBar, TB_GETITEMRECT, lButton, tR
lAW = lAW - (tR.Right - tR.Left)
End If
Else
SendMessage m_hWndToolBar, TB_GETITEMRECT, lButton, tR
lAW = lAW - (tR.Right - tR.Left)
End If
End If
Next lButton
If bControl Then
If bStretch Then
lAW = (lAW \ iStretchCount) - 1
'Debug.Print "WidthChange:", lAW
For lButton = 0 To ButtonCount - 1
If ButtonVisible(iB) Then
If m_tBInfo(lButton).bControl Then
'Debug.Print lAW, m_tBInfo(lButton).xWidth
If (m_tBInfo(lButton).bStretch) Then
If lAW >= m_tBInfo(lButton).xWidth Then
If ButtonWidth(lButton) <> lAW Then
ButtonWidth(lButton) = lAW
End If
Else
If ButtonWidth(lButton) <> m_tBInfo(lButton).xWidth
Then
ButtonWidth(lButton) = m_tBInfo(lButton).xWidth
End If
End If
Else
If ButtonWidth(lButton) <> m_tBInfo(lButton).xWidth Then
ButtonWidth(lButton) = m_tBInfo(lButton).xWidth
Else
SendMessage m_hWndToolBar, TB_GETITEMRECT, lButton,
tR
If Not (m_tBInfo(lButton).hWndCapture = 0) Then
GetWindowRect m_tBInfo(lButton).hWndCapture, tWR
LSet tBR = tR
MapWindowPoints m_hWndToolBar, HWND_DESKTOP, tBR,
2
If tWR.Left <> tBR.Left Or tWR.Top <> tBR.Top Or
tWR.Right <> tBR.Right Or tWR.Bottom <>
tBR.Bottom Then
moveChildWindow lButton
End If
End If
End If
End If
End If
End If
Next lButton
Else
For lButton = 0 To ButtonCount - 1
If ButtonVisible(iB) Then
If m_tBInfo(lButton).bControl Then
SendMessage m_hWndToolBar, TB_GETITEMRECT, lButton, tR
If Not (m_tBInfo(lButton).hWndCapture = 0) Then
GetWindowRect m_tBInfo(lButton).hWndCapture, tWR
LSet tBR = tR
MapWindowPoints m_hWndToolBar, HWND_DESKTOP, tBR, 2
'If tWR.left <> tBR.left Or tWR.top <> tBR.top Or
tWR.right <> tBR.right Or tWR.bottom <> tBR.bottom Then
moveChildWindow lButton
'End If
End If
End If
End If
Next lButton
End If
End If
Case WM_NOTIFY
CopyMemory hdr, ByVal lParam, Len(hdr)
Select Case hdr.code
Case VBALCHEVRONMENUCONST
If (hdr.hwndFrom = m_hWndToolBar) Then
Dim iIDType As Long, iBtn As Long
iID = hdr.idfrom
iIDType = iID And &H7FFF0000
Select Case iIDType
Case 0
' button visible
iBtn = iID And &HFFFF&
ButtonVisible(iBtn) = Not (ButtonVisible(iBtn))
Case 1
' customise
RaiseEvent CustomiseBegin
Case 2
' reset
RaiseEvent CustomiseResetPressed
Case 3
' ?
End Select
'
End If
Case TTN_NEEDTEXT
Dim idNum As Integer
idNum = hdr.idfrom
On Error Resume Next
iB = pbGetIndexForID(idNum)
If (iB > -1) Then
msToolTipBuffer = StrConv(ButtonToolTip(iB), vbFromUnicode)
If Err.Number = 0 Then
If (Len(msToolTipBuffer) > 0) Then
msToolTipBuffer = msToolTipBuffer & vbNullChar
' Debug.Print "Show tool tip", ButtonToolTip(iB)
CopyMemory ttt, ByVal lParam, Len(ttt)
ttt.lpszText = StrPtr(msToolTipBuffer)
CopyMemory ByVal lParam, ttt, Len(ttt)
End If
Else
Err.Clear
End If
End If
Case TBN_DROPDOWN
If (hdr.hwndFrom = m_hWndToolBar) Or (hdr.hwndFrom =
m_hWndChevronToolbar) Then
Dim nmTB As NMTOOLBAR_SHORT
CopyMemory nmTB, ByVal lParam, Len(nmTB)
iB = SendMessageLong(m_hWndToolBar, TB_COMMANDTOINDEX, nmTB.iItem,
0)
bSubMenu = Not (m_tBInfo(iB).hSubMenu = 0)
If bSubMenu Then
bS = ButtonPressed(iB)
ButtonPressed(iB) = True
' Now show the menu:
pMenuClick hdr.hwndFrom, iB
ButtonPressed(iB) = False
ISubclass_WindowProc = 0
SendMessageLong m_hWndParentForm, WM_EXITMENULOOP, 0, 0
SendMessageLong m_hWndToolBar, TB_SETHOTITEM, -1, 0
Else
RaiseEvent DropDownPress(iB)
If hdr.hwndFrom = m_hWndChevronToolbar Then
SendMessageLong m_hWndParentForm, WM_EXITMENULOOP, 0, 0
End If
End If
End If
Case TBN_HOTITEMCHANGE
If (hdr.hwndFrom = m_hWndToolBar) Then
If m_lMajorVer > 4 Or (m_lMajorVer = 4 And m_lMinorVer >= 70) Then
Dim nmTBHI As NMTBHOTITEM
CopyMemory nmTBHI, ByVal lParam, Len(nmTBHI)
eReason = nmTBHI.dwFlags
iOld = -1: iNew = -1
If (eReason And HICF_ENTERING) <> HICF_ENTERING Then
iOld = SendMessageLong(m_hWndToolBar, TB_COMMANDTOINDEX,
nmTBHI.idOld, 0)
End If
If (eReason And HICF_LEAVING) <> HICF_LEAVING Then
iNew = SendMessageLong(m_hWndToolBar, TB_COMMANDTOINDEX,
nmTBHI.idNew, 0)
End If
RaiseEvent HotItemChange(iNew, iOld, eReason)
End If
End If
Case TBN_BEGINADJUST
' begin adjust:
If (hdr.hwndFrom = m_hWndToolBar) Then
RaiseEvent CustomiseBegin
End If
Case TBN_QUERYINSERT
' toolbar is asking whether a button can be inserted to the left of the
' button specified in the NMTOOLBAR structure:
If (hdr.hwndFrom = m_hWndToolBar) Then
CopyMemory nmTB, ByVal lParam, Len(nmTB)
iB = SendMessageLong(m_hWndToolBar, TB_COMMANDTOINDEX, nmTB.iItem,
0)
bCanInsert = True
RaiseEvent CustomiseCanInsertBefore(iB, bCanInsert)
If bCanInsert Then
g_lCustomiseResponse = 1
ISubclass_WindowProc = 1
Else
g_lCustomiseResponse = 0
ISubclass_WindowProc = 0
End If
End If
ISubclass_WindowProc = g_lCustomiseResponse
Case TBN_QUERYDELETE
' toolbar is asking if button can be deleted:
If (hdr.hwndFrom = m_hWndToolBar) Then
CopyMemory nmTB, ByVal lParam, Len(nmTB)
iB = SendMessageLong(m_hWndToolBar, TB_COMMANDTOINDEX, nmTB.iItem,
0)
bCanDelete = True
RaiseEvent CustomiseCanDelete(iB, bCanDelete)
If bCanDelete Then
g_lCustomiseResponse = 1
Else
g_lCustomiseResponse = 0
End If
End If
ISubclass_WindowProc = g_lCustomiseResponse
Case TBN_GETBUTTONINFO
If (hdr.hwndFrom = m_hWndToolBar) Then
Dim nmTBF As NMTOOLBAR
CopyMemory nmTBF, ByVal lParam, Len(nmTBF)
'Debug.Print "TBN_GETBUTTONINFO", nmTBF.iItem, nmTBF.cchText,
nmTBF.lpszString
ReDim b(0 To nmTBF.cchText) As Byte
CopyMemory b(0), ByVal nmTBF.lpszString, nmTBF.cchText
'Debug.Print StrConv(b, vbUnicode)
g_lCustomiseResponse = 1
End If
ISubclass_WindowProc = g_lCustomiseResponse
Case TBN_CUSTHELP
If (hdr.hwndFrom = m_hWndToolBar) Then
RaiseEvent CustomiseHelpPressed
End If
Case TBN_RESET
If (hdr.hwndFrom = m_hWndToolBar) Then
RaiseEvent CustomiseResetPressed
End If
Case TBN_DELETINGBUTTON
If (hdr.hwndFrom = m_hWndToolBar) Then
CopyMemory nmTB, ByVal lParam, Len(nmTB)
wID = nmTB.iItem
iB = SendMessageLong(m_hWndToolBar, TB_COMMANDTOINDEX, wID, 0)
If iB > -1 Then
If Not (m_tBInfo(iB).hWndCapture = 0) Then
'SetParent m_tBInfo(iB).hWndCapture,
m_tBInfo(iB).hWndParentOrig
End If
iNewCount = ButtonCount
If iNewCount = 0 Then
Erase m_tBInfo
Else
For lButton = iB To iNewCount - 1
LSet m_tBInfo(lButton) = m_tBInfo(lButton + 1)
Next lButton
ReDim Preserve m_tBInfo(0 To iNewCount - 1) As ButtonInfoStore
End If
End If
End If
End Select
End Select
End Function
Private Sub moveChildWindow(ByVal lButton As Long)
Dim lhWnd As Long
Dim tR As RECT
Dim tWR As RECT
Dim iB As Long
iB = findFirstNonVisibleButton()
If iB < 0 Then iB = ButtonCount()
If lButton >= iB Then
ShowWindow m_tBInfo(lButton).hWndCapture, SW_HIDE
End If
SendMessage m_hWndToolBar, TB_GETITEMRECT, lButton, tR
lhWnd = GetParent(m_tBInfo(lButton).hWndCapture)
MapWindowPoints m_hWndToolBar, lhWnd, tR, 2
GetWindowRect m_tBInfo(lButton).hWndCapture, tWR
If tWR.Left <> tR.Left Or tWR.Right <> tR.Right Or tWR.Top <> tR.Top Or
tWR.Bottom <> tR.Bottom Then
SetWindowPos m_tBInfo(lButton).hWndCapture, 0, tR.Left, tR.Top, tR.Right
- tR.Left, tR.Bottom - tR.Top, SWP_FRAMECHANGED Or SWP_NOOWNERZORDER Or
SWP_NOZORDER Or SWP_NOACTIVATE
End If
If lButton < iB Then
If IsWindowVisible(m_tBInfo(lButton).hWndCapture) = 0 Then
ShowWindow m_tBInfo(lButton).hWndCapture, SW_SHOW
End If
End If
End Sub
Private Function findFirstNonVisibleButton() As Long
Dim lhWnd As Long
Dim sBuf As String
Dim tWR As RECT
Dim iNotVisibleIndex As Long
Dim i As Long
Dim tR As RECT
iNotVisibleIndex = -1
lhWnd = GetParent(m_hWndToolBar)
sBuf = String$(255, 0)
GetClassName lhWnd, sBuf, 255
'Debug.Print sBuf
If LCase$(Left$(sBuf, 7)) = "thunder" Then ' VB Control or Form
GetClientRect lhWnd, tWR
' ElseIf (left$(sBuf, Len(REBARCLASSNAME))) = REBARCLASSNAME Then
' LSet tWR = m_tRebarBand
' OffsetRect tWR, -tWR.left, -tWR.top
Else
GetClientRect m_hWndToolBar, tWR
End If
If Not (m_bVisible) Then
findFirstNonVisibleButton = 0
Exit Function
End If
For i = 0 To ButtonCount - 1
SendMessage m_hWndToolBar, TB_GETITEMRECT, i, tR
If tR.Right > tWR.Right Then
If Not (m_tBInfo(i).eStyle = CTBSeparator) Then
iNotVisibleIndex = i
Exit For
End If
ElseIf tR.Bottom > tWR.Bottom Then
If Not (m_tBInfo(i).eStyle = CTBSeparator) Then
iNotVisibleIndex = i
Exit For
End If
End If
Next i
findFirstNonVisibleButton = iNotVisibleIndex
End Function
Private Sub UserControl_Initialize()
debugmsg "cToolbar:Initialize"
If Not (ComCtlVersion(m_lMajorVer, m_lMinorVer, m_lBuild)) Then
m_lMajorVer = 4
m_lMinorVer = 0
m_lBuild = 0
End If
m_eImageSourceType = -1
m_sChevronAdditionalButton(CTBChevronAdditionalAddorRemove) = "&Add or
Remove Buttons..."
m_sChevronAdditionalButton(CTBChevronAdditionalReset) = "&Reset Toolbar..."
m_sChevronAdditionalButton(CTBChevronAdditionalCustomise) = "&Customise..."
m_bVisible = True
End Sub
Private Sub UserControl_InitProperties()
' Initialise the control
pInitialise
End Sub
Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
' Read properties:
On Error Resume Next
m_sCtlName = UserControl.Extender.Name
Err.Clear
On Error GoTo 0
' Initialise the control
pInitialise
End Sub
Private Sub UserControl_Terminate()
debugmsg m_sCtlName & ",cToolbar:Enter Terminate"
pTerminate
debugmsg m_sCtlName & ",cToolbar:Exit Terminate"
'MsgBox "cToolbar:Terminate"
End Sub
Private Sub UserControl_WriteProperties(PropBag As PropertyBag)
' Write properties:
End Sub
|
|