Home » Controls » How to set the Command Button’s caption color
How to set the Command Button’s caption color
Posted on January 5, 2009
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 | 'Controls - How to set the Command Button's caption color Option Explicit 'Add a Command Button to your form. Set the Command Button style property to 1 - Graphical. Private colButtons As New Collection Private Const KeyConst = "K" Private Const FormName = "ThunderFormDC" Private Const PROP_COLOR = "SMDColor" Private Const PROP_HWNDPARENT = "SMDhWndParent" Private Const PROP_LPWNDPROC = "SMDlpWndProc" Private Const GWL_WNDPROC = -4 Private Const ODA_SELECT = &H2 Private Const ODS_SELECTED = &H1 Private Const ODS_FOCUS = &H10 Private Const ODS_BUTTONDOWN = ODS_FOCUS + ODS_SELECTED Private Const WM_DESTROY = &H2 Private Const WM_DRAWITEM = &H2B Private Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type Private Type Size cx As Long cy As Long End Type Private Type DRAWITEMSTRUCT CtlType As Long CtlID As Long itemID As Long itemAction As Long itemState As Long hWndItem As Long hDC As Long rcItem As RECT itemData As Long End Type Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, _ ByVal hWnd As Long, ByVal msg As Long, ByVal wParam As Long, lParam As DRAWITEMSTRUCT) 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 Function GetParent Lib "user32" (ByVal hWnd As Long) As Long Private Declare Function GetProp Lib "user32" Alias "GetPropA" (ByVal hWnd As Long, _ 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 RemoveProp Lib "user32" Alias "RemovePropA" (ByVal hWnd As Long, _ ByVal lpString As String) As Long Private Declare Function SetProp Lib "user32" Alias "SetPropA" (ByVal hWnd As Long, _ ByVal lpString As String, ByVal hData As Long) As Long Private Declare Function SetTextColor Lib "gdi32" (ByVal hDC As Long, ByVal crColor 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 Sub Sleep Lib "kernel32" (ByVal dwMilliseconds 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 Function FindButton(sKey As String) As Boolean Dim cmdButton As CommandButton On Error Resume Next Set cmdButton = colButtons.Item(sKey) FindButton = (Err.Number = 0) End Function Private Function GetFormHandle(hWndButton As Long) As Long Dim hWndParent As Long, l As Long Dim ClassName As String * 128 hWndParent = GetParent(hWndButton) Do Until (hWndParent = 0) l = GetClassName(hWndParent, ClassName, Len(ClassName)) If Left(ClassName, l) = FormName Then Exit Do hWndParent = GetParent(hWndParent) Loop GetFormHandle = hWndParent End Function Private Function GetKey(hWnd As Long) As String GetKey = KeyConst & hWnd End Function Private Function ProcessButton(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, _ lParam As DRAWITEMSTRUCT, sKey As String) As Long Dim cmdButton As CommandButton Dim bRC As Boolean Dim lRC As Long Dim x As Long Dim y As Long Dim lpWndProc As Long Dim lButtonWidth As Long Dim lButtonHeight As Long Dim lPrevColor As Long Dim lColor As Long Dim TextSize As Size Dim sCaption As String Const PushOffset = 2 Set cmdButton = colButtons.Item(sKey) sCaption = cmdButton.Caption lColor = GetProp(cmdButton.hWnd, PROP_COLOR) lPrevColor = SetTextColor(lParam.hDC, lColor) lRC = GetTextExtentPoint32(lParam.hDC, sCaption, Len(sCaption), TextSize) lButtonHeight = lParam.rcItem.Bottom - lParam.rcItem.Top lButtonWidth = lParam.rcItem.Right - lParam.rcItem.Left If (lParam.itemAction = ODA_SELECT) And (lParam.itemState = ODS_BUTTONDOWN) Then cmdButton.SetFocus DoEvents x = (lButtonWidth - TextSize.cx + PushOffset) \ 2 y = (lButtonHeight - TextSize.cy + PushOffset) \ 2 Else x = (lButtonWidth - TextSize.cx) \ 2 y = (lButtonHeight - TextSize.cy) \ 2 End If lpWndProc = GetProp(hWnd, PROP_LPWNDPROC) ProcessButton = CallWindowProc(lpWndProc, hWnd, uMsg, wParam, lParam) bRC = TextOut(lParam.hDC, x, y, sCaption, Len(sCaption)) lRC = SetTextColor(lParam.hDC, lPrevColor) ProcessButton_Exit: Set cmdButton = Nothing End Function Private Sub RemoveForm(hWndParent As Long) Dim hWndButton As Long, I As Integer UnsubclassForm hWndParent On Error GoTo RemoveForm_Exit For I = colButtons.Count - 1 To 0 Step -1 hWndButton = colButtons(I).hWnd If GetProp(hWndButton, PROP_HWNDPARENT) = hWndParent Then RemoveProp hWndButton, PROP_COLOR RemoveProp hWndButton, PROP_HWNDPARENT colButtons.Remove I End If Next I RemoveForm_Exit: Exit Sub End Sub Private Function UnsubclassForm(hWnd As Long) As Boolean Dim lRC As Long, lpWndProc As Long lpWndProc = GetProp(hWnd, PROP_LPWNDPROC) If lpWndProc = 0 Then UnsubclassForm = False Else lRC = SetWindowLong(hWnd, GWL_WNDPROC, lpWndProc) RemoveProp hWnd, PROP_LPWNDPROC UnsubclassForm = True End If End Function Private Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, _ lParam As DRAWITEMSTRUCT) As Long Dim lpWndProc As Long Dim bProcessButton As Boolean Dim sButtonKey As String bProcessButton = False If (uMsg = WM_DRAWITEM) Then sButtonKey = GetKey(lParam.hWndItem) bProcessButton = FindButton(sButtonKey) End If If bProcessButton Then ProcessButton hWnd, uMsg, wParam, lParam, sButtonKey Else lpWndProc = GetProp(hWnd, PROP_LPWNDPROC) WindowProc = CallWindowProc(lpWndProc, hWnd, uMsg, wParam, lParam) If uMsg = WM_DESTROY Then RemoveForm hWnd End If End Function Public Function RegisterButton(Button As CommandButton, Forecolor As Long) Dim hWndParent As Long, lpWndProc As Long Dim sButtonKey As String sButtonKey = GetKey(Button.hWnd) If FindButton(sButtonKey) Then SetProp Button.hWnd, PROP_COLOR, Forecolor Button.Refresh Else hWndParent = GetFormHandle(Button.hWnd) If (hWndParent = 0) Then RegisterButton = False Exit Function End If colButtons.Add Button, sButtonKey SetProp Button.hWnd, PROP_COLOR, Forecolor SetProp Button.hWnd, PROP_HWNDPARENT, hWndParent lpWndProc = GetProp(hWndParent, PROP_LPWNDPROC) If (lpWndProc = 0) Then lpWndProc = SetWindowLong(hWndParent, _ GWL_WNDPROC, AddressOf WindowProc) SetProp hWndParent, PROP_LPWNDPROC, lpWndProc End If End If RegisterButton = True End Function Public Function UnregisterButton(Button As CommandButton) As Boolean Dim hWndParent As Long Dim sKeyButton As String sKeyButton = GetKey(Button.hWnd) If (FindButton(sKeyButton) = False) Then UnregisterButton = False Exit Function End If hWndParent = GetProp(Button.hWnd, PROP_HWNDPARENT) UnregisterButton = UnsubclassForm(hWndParent) colButtons.Remove sKeyButton RemoveProp Button.hWnd, PROP_COLOR RemoveProp Button.hWnd, PROP_HWNDPARENT End Function 'Add the following code to your form: Private Sub Form_Load() 'Replace 'Command1' with the name of your Command Button, 'Replace 'vbRed' with the caption color. You can put here the Hex value of the color. RegisterButton Command1, vbRed End Sub |
Enjoy this article?
Filed under: Controls
Leave a comment