禁用 VBA UserForm 'x',但仍允许卸载我

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15808997/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 20:24:59  来源:igfitidea点击:

Disable VBA UserForm 'x', but still allow Unload Me

excelvbauserform

提问by steventnorris

I have a user form that, when closed, needs to run cleanup steps. I would like for the Xbutton to be disabled and/or not visible, but I still need to be able to unload the form. I've used code like the below, but it also blocks Unload Me.

我有一个用户表单,关闭时需要运行清理步骤。我希望X按钮被禁用和/或不可见,但我仍然需要能够卸载表单。我使用过如下代码,但它也会阻止Unload Me.

'Disables closing via x button
Sub UserForm_QueryClose(Cancel As Integer, ClsoeMode As Integer)
    If CloseMode = vbFormControlMenu Then
        MsgBox ("BLOCKED")
        Cancel = True
    End If
End Sub

回答by Siddharth Rout

Do not use the UserForm_QueryClosein such a case. Use the API RemoveMenu, GetSystemMenuand FindWindow

UserForm_QueryClose在这种情况下不要使用。使用 API RemoveMenuGetSystemMenu以及FindWindow

Thisis my fav site for APIs

是我最喜欢的 API 站点

RemoveMenu: http://allapi.mentalis.org/apilist/RemoveMenu.shtml

移除菜单http: //allapi.mentalis.org/apilist/RemoveMenu.shtml

GetSystemMenu: http://allapi.mentalis.org/apilist/GetSystemMenu.shtml

获取系统菜单http: //allapi.mentalis.org/apilist/GetSystemMenu.shtml

FindWindow: http://allapi.mentalis.org/apilist/FindWindow.shtml

查找窗口http: //allapi.mentalis.org/apilist/FindWindow.shtml

See this example

看这个例子

Option Explicit

Private Declare Function RemoveMenu Lib "user32" (ByVal hMenu As Long, ByVal nPosition As Long, _
ByVal wFlags As Long) As Long

Private Declare Function GetSystemMenu Lib "user32" (ByVal hwnd As Long, ByVal bRevert As Long) As Long

Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long

Private Const MF_BYPOSITION = &H400&

Private Sub UserForm_Initialize()
    Dim Ret As Long

    '~~> Change UserForm1 to match your userform's caption
    Ret = FindWindow("ThunderDFrame", "UserForm1")

    Do While Ret = 0
        '~~> Change UserForm1 to match your userform's caption
        Ret = FindWindow("ThunderDFrame", "UserForm1")
        DoEvents
    Loop

    RemoveMenu GetSystemMenu(Ret, 0), 6, MF_BYPOSITION
End Sub

Private Sub CommandButton1_Click()
    Unload Me
End Sub

Screenshot:

截图

enter image description here

在此处输入图片说明

回答by Jon Peltier

Instead of giving the user a message saying he can't click the red x, trap it the way you did, and do the cleanup before unloading the form:

不要给用户一条消息说他不能点击红色的 x,而是按照你的方式捕获它,并在卸载表单之前进行清理:

Sub UserForm_QueryClose(Cancel As Integer, ClsoeMode As Integer)
    If CloseMode = vbFormControlMenu Then
        ' run cleanup code here
    End If
End Sub

If the form has a close button that does the cleanup, then use something like this:

如果表单有一个关闭按钮进行清理,则使用如下内容:

Sub UserForm_QueryClose(Cancel As Integer, ClsoeMode As Integer)
    If CloseMode = vbFormControlMenu Then
        ' click event code for Close button:
        btnClose_Click 
        Cancel = True
    End If
End Sub

No need to go overboard with Windows APIs, since this is all built-in.

无需过度使用 Windows API,因为这些都是内置的。

回答by Scott M

I know this is an old feed but you spelt ClsoeModewrong. Simply change that to CloseModeand this should resolve your issue.

我知道这是一个旧的提要,但你拼错ClsoeMode了。只需将其更改为CloseMode,这应该可以解决您的问题。