Prevent a Modal form closing all Modeless open forms upon exit

对着背影说爱祢 提交于 2020-08-05 09:29:25

问题


I ran into some peculiar behavior while using VBA Forms in Excel. I have a module which invokes a Modeless form, which serves as a hub to call other forms. The other forms are invoked as Modal. The problem is, as soon as the the child form is hidden or unloaded, the parent Modeless form gets closed as well.

I tried to find an answer to this, but even though there are questions that exist along these lines, none of them provided an answer that works.

After a bit of testing, I determined any number of open Modeless forms would be closed in the same way. Furthermore, I wasn't able to reproduce the issue using a minimal model in a new Workbook. After that, I went on to add piece-by-piece all the components (there are a few modules, 10-20 classes, and a few forms) of the original Workbook to see when the problem comes up.

I was simultaneously relieved and annoyed when I found that the problem didn't reappear even after I imported absolutely everything back. My conclusion was that this was some kind of a fluke that won't bother me again. But, soon after, when I added another such child form, with identical calling code, the same started happening again with the new one, but not with the old one.

I then proceeded to export the misbehaving form, delete it from the workbook, and then import it. And voila, it worked again.

Is there anyone who encountered such behavior before? Am I doing something wrong? Or should I treat this as an annoying but circumventable bug?

Please find below the minimum model of the problem, excluding all the content:

module calling the main form:

Sub testA()

 Dim main1 As MainForm1

 Set main1 = New MainForm1

 main1.Show (vbModeless)

End Sub

main form:

Option Explicit

Dim formobject As frmPickInjection

Private Sub CommandButton1_Click()

 Set formobject = New frmPickInjection


 With formobject
     .Show (vbModal)
     Label1.Caption = CStr(.SelectedInjection)
 End With

End Sub

child form:

Option Explicit

Public passvar As Boolean

Private Sub CheckBox1_Click()
 passvar = CheckBox1.Value
End Sub

System: Microsoft Windows 7 Enterprise 6.1.7601 (Service Pack 1 Build 7601)

Excel version: Office365 Excel 2016 (16.0.6729.1014), 64 bit

VBA version: 7.1


回答1:


I've encountered this problem before. Unsure whether this has already been resolved or not, but for future users looking to fix this:

The only way I have found of fixing this annoying and intermittent issue is to show the userform Modally then Hide and re-show the userform Modelessly.

Unload MyChildUserform
MyParentUserform.Show vbModal
MyParentUserform.Hide
MyParentUserform.Show vbModeless

It's clunky and annoying, but it seems to work and is consistent at the least.

Edit:

IMHO A much better solution is to control the modality of the form yourself.

Declarations:

Public Declare Function EnableWindow lib "user32.dll" (ByVal hWnd as Long, ByVal fEnable as Long) as Long
Public Declare Function FindWindow lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName as String, ByVal lpWindowName as String) as Long

Public Enum MakeAsModal
    Modal = 0
    Modeless = 1
End Enum

Public ghWndParent as Long

Public Sub(s):

Public Sub ChangeModality(ByRef hWnd as Long, ByVal isModal as MakeAsModal)
    On Error Resume Next
    Dim RetVal as Long
    RetVal = EnableWindow(hWnd,isModal)
End Sub

Parent Form:

Private Sub Userform_Initialize()
'Parent Form
    ghWndParent = FindWindow(vbNullString, Me.Caption)
End Sub

Private Sub CallChild()
'Parent Form
    ChildUserform.Show vbModeless
    ChangeModality ghWndParent, Modal
End Sub

Child Form:

Private Sub Userform_QueryClose(Cancel As Integer, CloseMode as Integer)
'Child Form
    ChangeModality ghWndParent, Modeless
End Sub



回答2:


I was plagued with this issue today, I found a work around that stops the closing of non-modal forms on the close event of a modal form.

Simply, set the UserForm property "ShowModal" to True

UserForm ShowModal Property to True

Then; when showing the form just use UserForm.Show (i.e. do not specify vbModal or vbModeless). In my work-around I contained this .Show call inside the UserForm_Initialize event of the respective modal UserForm. Now when you close this modal form, it won't take out every parent non-modal form with it.

This issue was vital for me to find a workaround for, since my modal Userform MUST be modal since it contains a RefEdit control. After some further investigation and troubleshooting, I cannot derive exactly what is causing this issue with Modal forms. I'd love someone with better knowledge in VBA to take a look, but I'm afraid they may have all moved on to greener pastures....



来源:https://stackoverflow.com/questions/37401393/prevent-a-modal-form-closing-all-modeless-open-forms-upon-exit

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!