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 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318
| '***************************************************************************
'*
'* MODULE NAME: USERFORM WINDOW STYLES
'* AUTHOR: STEPHEN BULLEN, Office Automation Ltd.
'* TIM CLEM
'*
'* CONTACT: Stephen@oaltd.co.uk
'* WEB SITE: http://www.oaltd.co.uk
'*
'* DESCRIPTION: Changes userform's window styles to give different visual effects
'*
'* THIS MODULE: Changes the userform's styles so it can be resized/maximised/minimized, etc.
'* The code was initially created by Tim Clem, and expanded by Stephen Bullen.
'*
'* UPDATES:
'* DATE COMMENTS
'* 11 Jan 2005 Changed the way 'ShowInTaskBar' works, fixing a bug found by Jamie Collins
'*
'***************************************************************************
Option Explicit
'Windows API calls to do all the dirty work!
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowLong Lib "user32" 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 GetSystemMenu Lib "user32" (ByVal hWnd As Long, ByVal bRevert As Long) As Long
Private Declare Function DeleteMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, ByVal wFlags As Long) As Long
Private Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Private Declare Function EnableWindow Lib "user32" (ByVal hWnd As Long, ByVal fEnable As Long) As Long
Private Declare Function DrawMenuBar Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function SetFocus Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As Long, ByVal lpszExeFileName As String, ByVal nIconIndex As Long) As Long
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Long) As Long
Private Declare Function LockWindowUpdate Lib "user32" (ByVal hWndLock As Long) As Long
'Lots of window styles for us to play with!
Private Const GWL_STYLE As Long = (-16) 'The offset of a window's style
Private Const GWL_EXSTYLE As Long = (-20) 'The offset of a window's extended style
Private Const WS_CAPTION As Long = &HC00000 'Style to add a titlebar
Private Const WS_SYSMENU As Long = &H80000 'Style to add a system menu
Private Const WS_THICKFRAME As Long = &H40000 'Style to add a sizable frame
Private Const WS_MINIMIZEBOX As Long = &H20000 'Style to add a Minimize box on the title bar
Private Const WS_MAXIMIZEBOX As Long = &H10000 'Style to add a Maximize box to the title bar
Private Const WS_EX_APPWINDOW As Long = &H40000 'Application Window: shown on taskbar
Private Const WS_EX_TOOLWINDOW As Long = &H80 'Tool Window: small titlebar
'Constant to identify the Close menu item
Private Const SC_CLOSE As Long = &HF060
'Constants for hide or show a window
Private Const SW_HIDE As Long = 0
Private Const SW_SHOW As Long = 5
'Constants for Windows messages
Private Const WM_SETICON = &H80
'Variables to store the various selections/options
Dim mbSizeable As Boolean, mbCaption As Boolean, mbIcon As Boolean
Dim mbMaximize As Boolean, mbMinimize As Boolean, mbSysMenu As Boolean, mbCloseBtn As Boolean
Dim mbAppWindow As Boolean, mbToolWindow As Boolean, mbModal As Boolean
Dim msIconPath As String
Dim moForm As Object
Dim mhWndForm As Long
'Set the class's initial properties to be those of a default userform
Private Sub Class_Initialize()
mbCaption = True
mbSysMenu = True
mbCloseBtn = True
End Sub
'Allow the calling code to tell us which form to handle
Public Property Set Form(oForm As Object)
'Get the userform's window handle
If Val(Application.Version) < 9 Then
mhWndForm = FindWindow("ThunderXFrame", oForm.caption) 'XL97
Else
mhWndForm = FindWindow("ThunderDFrame", oForm.caption) 'XL2000+
End If
'Remember the form for later
Set moForm = oForm
'Set the form's style
SetFormStyle
'Update the form's icon
ChangeIcon
'Update the taskbar visibility
If mbAppWindow Then ShowTaskBarIcon = True
End Property
'***************************************************************
'* Property procedures to get and set the form's window styles
'***************************************************************
Public Property Let Modal(bModal As Boolean)
mbModal = bModal
'Make the form modal or modeless by enabling/disabling Excel itself
EnableWindow FindWindow(vbNullString, Application.ActiveExplorer.caption), Abs(CInt(Not mbModal))
End Property
Public Property Get Modal() As Boolean
Modal = mbModal
End Property
Public Property Let Sizeable(bSizeable As Boolean)
mbSizeable = bSizeable
SetFormStyle
End Property
Public Property Get Sizeable() As Boolean
Sizeable = mbSizeable
End Property
Public Property Let ShowCaption(bCaption As Boolean)
mbCaption = bCaption
SetFormStyle
End Property
Public Property Get ShowCaption() As Boolean
ShowCaption = mbCaption
End Property
Public Property Let SmallCaption(bToolWindow As Boolean)
mbToolWindow = bToolWindow
SetFormStyle
End Property
Public Property Get SmallCaption() As Boolean
SmallCaption = mbToolWindow
End Property
Public Property Let ShowMaximizeBtn(bMaximize As Boolean)
mbMaximize = bMaximize
SetFormStyle
End Property
Public Property Get ShowMaximizeBtn() As Boolean
ShowMaximizeBtn = mbMaximize
End Property
Public Property Let ShowMinimizeBtn(bMinimize As Boolean)
mbMinimize = bMinimize
SetFormStyle
End Property
Public Property Get ShowMinimizeBtn() As Boolean
ShowMinimizeBtn = mbMinimize
End Property
Public Property Let ShowSysMenu(bSysMenu As Boolean)
mbSysMenu = bSysMenu
SetFormStyle
End Property
Public Property Get ShowSysMenu() As Boolean
ShowSysMenu = mbSysMenu
End Property
Public Property Let ShowCloseBtn(bCloseBtn As Boolean)
mbCloseBtn = bCloseBtn
SetFormStyle
End Property
Public Property Get ShowCloseBtn() As Boolean
ShowCloseBtn = mbCloseBtn
End Property
Public Property Let ShowTaskBarIcon(bAppWindow As Boolean)
mbAppWindow = bAppWindow
'When showing/hiding the task bar icon, we have to hide and reshow the form
'to get Windows to update the task bar
If mhWndForm <> 0 Then
'Freeze the form, to avoid flicker when hiding/showing it
LockWindowUpdate mhWndForm
'Enable the Excel window, so we don't lose focus
EnableWindow FindWindow(vbNullString, Application.ActiveExplorer.caption), True 'FindWindow("XLMAIN", Application.caption), True
'Hide the form
ShowWindow mhWndForm, SW_HIDE
'Update the style bits
SetFormStyle
'Reshow the userform
ShowWindow mhWndForm, SW_SHOW
'Unfreeze the form
LockWindowUpdate 0&
'Set the Outlook window's enablement to the correct choice --Excel
EnableWindow FindWindow(vbNullString, Application.ActiveExplorer.caption), Abs(CInt(Not mbModal))
'EnableWindow FindWindow("XLMAIN", Application.caption), Abs(CInt(Not mbModal))
End If
End Property
Public Property Get ShowTaskBarIcon() As Boolean
ShowTaskBarIcon = mbAppWindow
End Property
Public Property Let ShowIcon(bIcon As Boolean)
mbIcon = Not bIcon
ChangeIcon
SetFormStyle
End Property
Public Property Get ShowIcon() As Boolean
ShowIcon = (mbIcon <> 1)
End Property
Public Property Let IconPath(sNewPath As String)
msIconPath = sNewPath
ChangeIcon
SetFormStyle
End Property
Public Property Get IconPath() As String
IconPath = msIconPath
End Property
'***************************************************************
'* Private procedures to perform the updates
'***************************************************************
'Procedure to set the form's window style
Private Sub SetFormStyle()
Dim lStyle As Long, hMenu As Long
'Have we got a form to set?
If mhWndForm = 0 Then Exit Sub
'Get the basic window style
lStyle = GetWindowLong(mhWndForm, GWL_STYLE)
'Build up the basic window style flags for the form
SetBit lStyle, WS_CAPTION, mbCaption
SetBit lStyle, WS_SYSMENU, mbSysMenu
SetBit lStyle, WS_THICKFRAME, mbSizeable
SetBit lStyle, WS_MINIMIZEBOX, mbMinimize
SetBit lStyle, WS_MAXIMIZEBOX, mbMaximize
'Set the basic window styles
SetWindowLong mhWndForm, GWL_STYLE, lStyle
'Get the extended window style
lStyle = GetWindowLong(mhWndForm, GWL_EXSTYLE)
'Build up and set the extended window style
SetBit lStyle, WS_EX_APPWINDOW, mbAppWindow
SetBit lStyle, WS_EX_TOOLWINDOW, mbToolWindow
SetWindowLong mhWndForm, GWL_EXSTYLE, lStyle
'Handle the close button differently
If mbCloseBtn Then
'We want it, so reset the control menu
hMenu = GetSystemMenu(mhWndForm, 1)
Else
'We don't want it, so delete it from the control menu
hMenu = GetSystemMenu(mhWndForm, 0)
DeleteMenu hMenu, SC_CLOSE, 0&
End If
'Update the window with the changes
DrawMenuBar mhWndForm
SetFocus mhWndForm
End Sub
'Procedure to set or clear a bit from a style flag
Private Sub SetBit(ByRef lStyle As Long, ByVal lBit As Long, ByVal bOn As Boolean)
If bOn Then
lStyle = lStyle Or lBit
Else
lStyle = lStyle And Not lBit
End If
End Sub
'Procedure to set the form's icon
Private Sub ChangeIcon()
Dim hIcon As Long
On Error Resume Next
If mhWndForm <> 0 Then
Err.Clear
If msIconPath = "" Then
hIcon = 0
ElseIf Dir(msIconPath) = "" Then
hIcon = 0
ElseIf Err.Number <> 0 Then
hIcon = 0
ElseIf Not mbIcon Then
'Get the icon from the source
hIcon = ExtractIcon(0, msIconPath, 0)
Else
hIcon = 0
End If
'Set the big (32x32) and small (16x16) icons
SendMessage mhWndForm, WM_SETICON, True, hIcon
SendMessage mhWndForm, WM_SETICON, False, hIcon
End If
End Sub |
Partager