当宏仍在导入工作表时,我创建了一个用户窗体来显示进度条
问题是用户可以按下将关闭的红色[X]按钮并中断完成的处理。
有没有办法隐藏这个厄运的红色按钮,以便潜在用户在运行时没有任何令人困惑的按钮。
编辑:
我试过这个
'Find the userform's Window
Private Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
'Get the current window style
Private Declare Function GetWindowLong Lib "user32" _
Alias "GetWindowLongA" ( _
ByVal hWnd As Long, _
ByVal nIndex As Long) As Long
'Set the new window style
Private Declare Function SetWindowLong Lib "user32" _
Alias "SetWindowLongA" ( _
ByVal hWnd As Long, _
ByVal nIndex As Long, _
ByVal dwNewLong As Long) As Long
Const GWL_STYLE = -16
Const WS_SYSMENU = &H80000
我在userform_initialize上使用了这个
Dim hWnd As Long, lStyle As Long
'Which type of userform
If Val(Application.Version) >= 9 Then
hWnd = FindWindow("ThunderDFrame", Me.Caption)
Else
hWnd = FindWindow("ThunderXFrame", Me.Caption)
End If
'Get the current window style and turn off the Close button
lStyle = GetWindowLong(hWnd, GWL_STYLE)
SetWindowLong hWnd, GWL_STYLE, (lStyle And Not WS_SYSMENU)
我收到此错误消息
此代码取自here。我不知道我做错了什么,我已经删除了评论。这是我发现的最简单的代码,所以我想将它集成到我的用户表单中。任何帮助表示赞赏。
以下是您可以这样调用的例程:
subRemoveCloseButton MyForm
或者从您的表单中:
subRemoveCloseButton Me
这是您需要的代码:
Private Const mcGWL_STYLE = (-16)
Private Const mcWS_SYSMENU = &H80000
'Windows API calls to handle windows
#If VBA7 Then
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#Else
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#End If
#If VBA7 Then
Private Declare PtrSafe Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
#Else
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
#End If
#If VBA7 Then
Private Declare PtrSafe Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#Else
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
#End If
Public Sub subRemoveCloseButton(frm As Object)
Dim lngStyle As Long
Dim lngHWnd As Long
lngHWnd = FindWindow(vbNullString, frm.Caption)
lngStyle = GetWindowLong(lngHWnd, mcGWL_STYLE)
If lngStyle And mcWS_SYSMENU > 0 Then
SetWindowLong lngHWnd, mcGWL_STYLE, (lngStyle And Not mcWS_SYSMENU)
End If
End Sub
您可以从以下代码段中进行处理:
选择cmdClose
按钮在菜单栏上,选择View | Code
光标闪烁的位置,输入以下代码:
Private Sub cmdClose_Click()
Unload Me
End Sub
在菜单栏上,选择View | Object
,返回UserForm。
要允许用户按Esc键关闭表单:
选择cmdClose按钮在Properties窗口中,将Cancel
属性更改为True
单击X按钮以防止用户关闭表单
当UserForm
打开时,右上方有一个X
。除了使用“关闭表单”按钮之外,人们还可以使用X关闭表单。如果要防止这种情况,请按照下列步骤操作。
右键单击UserForm的空白部分选择View | Code
从过程下拉列表右上角,选择QueryClose
光标闪烁的位置,粘贴以下示例中突出显示的代码
Private Sub UserForm_QueryClose(Cancel As Integer, _
CloseMode As Integer)
If CloseMode = vbFormControlMenu Then
Cancel = True
MsgBox "Please use the Close Form button!"
End If
End Sub
在菜单栏上,选择View | Object
,返回UserForm。现在,如果有人点击UserForm中的X
,他们会看到你的消息。
FindWindow
调用以查找Excel UserForms。原始答案中的函数搜索每个窗口类(例如,资源管理器窗口和其他程序的窗口)。因此,当其名称与UserForm同名时,可能会删除其他程序或资源管理器窗口的[x]按钮。Private Const mcGWL_STYLE = (-16)
Private Const mcWS_SYSMENU = &H80000
'Windows API calls to handle windows
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
#If Win64 Then
Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongPtrA" ( _
ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" ( _
ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#Else
Private Declare PtrSafe Function GetWindowLongPtr Lib "user32" Alias "GetWindowLongA" ( _
ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr
Private Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongA" ( _
ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr
#End If
Public Sub RemoveCloseButton(objForm As Object)
Dim lngStyle As LongPtr
Dim lngHWnd As LongPtr
Dim lpClassName As String
lpClassName = vbNullString
If Val(Application.Version) >= 9 Then
lpClassName = "ThunderDFrame"
Else
lpClassName = "ThunderXFrame"
End If
lngHWnd = FindWindow(lpClassName, objForm.Caption)
lngStyle = GetWindowLongPtr(lngHWnd, mcGWL_STYLE)
If lngStyle And mcWS_SYSMENU > 0 Then
SetWindowLongPtr lngHWnd, mcGWL_STYLE, (lngStyle And Not mcWS_SYSMENU)
End If
End Sub
ThunderDFrame? Excel中的UserForms实际上是Windows类
ThunderDFrame
,它是2002年之后Microsoft Office应用程序中所有UserFrom的类。在此之前,它是ThunderXFrame
。
询问用户是否要关闭表单 - 并丢失编辑(比方说)。基于贾斯汀和彼得的想法。
Private Sub UserForm_QueryClose(Cancel As Integer, _
CloseMode As Integer)
Dim ans
If CloseMode = vbFormControlMenu Then
Cancel = True
ans = Msgbox("Cancel edit?", vbQuestion + vbYesNo)
If ans = vbYes Then
Me.Hide
End if
End If
End Sub
编辑:实际上我意识到这有点偏离主题,因为OP想要删除X选项 - 但我仍然发现这对于交互式表单很方便。
我知道这是一个老问题,但对于OP所引用的用户类型,您不必删除,隐藏或禁用关闭按钮。有一个更简单的方法;)
对于任何没有任何用户与之交互的元素(按钮等)以及在完成其目的时将自行关闭的用户表单,只需禁用表单即可。
要禁用用户表单:在用户表单的属性中,针对Enabled设置False。用户表单将显示,直到它的代码告诉它隐藏。用户将无法对表单执行任何操作(无法关闭,无法移动等)。
另请注意,在用户表单仍显示时,是否希望用户能够在主窗口中执行任何其他操作来决定是否设置ShowModal。
禁用按钮的有用方法是执行以下操作:
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = 0 Then Cancel = True
End Sub
虽然这并没有摆脱按钮,但它确实使点击它没有任何成就。