隐藏excel vba userform上的关闭[X]按钮以进入我的进度条

时间:2013-03-01 08:29:38

标签: excel excel-vba userform vba

我创建了一个userform,以便在宏仍在导入工作表时显示进度条 enter image description here

问题是用户可以按下将关闭的红色 [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)

我收到此错误消息 enter image description here

此代码取自here。我不知道我做错了什么,我已经删除了评论。这是我发现的最简单的代码,所以我想将它集成到我的用户表单中。任何帮助表示赞赏。

6 个答案:

答案 0 :(得分:15)

以下是您可以这样调用的例程:

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

答案 1 :(得分:9)

您可以从以下代码段中解决这个问题:

选择cmdClose按钮 在菜单栏上,选择View | Code 如果光标闪烁,请输入以下代码:

Private Sub cmdClose_Click()
  Unload Me
End Sub

在菜单栏上,选择View | Object,返回UserForm。

允许用户按Esc键关闭表单:

选择cmdClose按钮 在“属性”窗口中,将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,他们就会看到您的消息。

来自http://www.contextures.com/xlUserForm01.html

答案 2 :(得分:3)

这是对@Peter Albert

的上述答案的改进
  • Windows API调用现在是Office x64安全
  • 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

答案 3 :(得分:2)

询问用户是否要关闭表单 - 并丢失编辑(比如说)。 根据Justin&amp; amp;的创意彼得。

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选项 - 但我仍然觉得这对于交互式表格很方便。

答案 4 :(得分:2)

我知道这是一个老问题,但对于引用的OP用户类型,您不必删除,隐藏或禁用关闭按钮。有一种更简单的方法;)

对于任何没有任何用户与之交互的元素(按钮等)并且在完成其目的时将自行关闭的用户表单,只需禁用表单即可。

要禁用用户表单: 在用户表单的属性中,针对Enabled设置False。用户表单将显示,直到它的代码告诉它隐藏。用户将无法对表单执行任何操作(无法关闭,无法移动等)。

另请注意,在用户表单仍然显示时,您是否希望用户能够在主窗口中执行任何其他操作来决定是否设置ShowModal。

答案 5 :(得分:2)

禁用按钮的有效方法是执行以下操作:

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    If CloseMode = 0 Then Cancel = True
End Sub

虽然这并没有摆脱按钮,但确实点击它就什么也没做。