Reputation: 33
For a Project running under Access 2003 I have a Form that is normally set modeless, but in some cases is opened as acDialog and thusly modal.
This Form now needs to check if itself is Modal or not to modify its behaviour upon button-click accordingly.
Me.Form.Modal
only returns the Property-Value specified in Design-mode, not the current state.
I have found a similar answer for VB that suggests using the GetWindowLong API-Call to "user", but this does not translate to VBA (Microsoft KnowledgeBase 77316), I am afraid: Access2003 cannot find the 'user'-file.
In short: Is there a reliable way to determine if a Form itself is modal or modeless from within this form?
TIA.
Edit: I seem to remember that Me.Form is actually equivalent to just Me. As far as I recall, The Form Property is the default one, so if you omit it it is assumed. Regardless, both Me.Modal and Me.Form.Modal deliver the value 'false' regardless of the way the Form was opened.
Upvotes: 3
Views: 4102
Reputation: 41
I know this is old and answered. I just wanted to point out that p122's solution doesn't actually read the modal state of a window but the popup state, which is fine with me because that's what I was looking for.
If a form is opened in a modal non-popup window, p122's IsModal function returns false. If a form is opened in a modeless popup window, IsModal returns true. Thus IsModal is actually IsPopup.
Upvotes: 4
Reputation: 16247
Figured out the API (took a bit of hacking as Access I think does some funny stuff with forms)
Put this in a module
Const GWL_EXSTYLE = (-20)
Const WS_EX_MDICHILD = &H40
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Function IsModal(ByVal lHwnd As Long) As Boolean
Dim lWinstyle As Long
lWinstyle = GetWindowLong(lHwnd, GWL_EXSTYLE)
If (lWinstyle And WS_EX_MDICHILD) Then
IsModal = False
Else
IsModal = True
End If
End Function
Then in your form_Load event (or wherever)
MsgBox "Hi I'm " & IIf(IsModal(me.Hwnd), "Modal", "Not Modal")
Upvotes: 3
Reputation: 23067
I'm not necessarily recommending this for the current problem (though it may be a solution), but it can come in handy in some situations, and that's to open a form with acDialog + acHidden, change its properties, and then set .Visible = True. This causes the form to become modal at the point it appears, rather than at the point it's opened. That is, the code runs up until the point the form is set to .Visible and than pauses, just as it would with only the acDialog argument in the OpenForm command:
DoCmd.OpenForm "dlgMyDialog", , , , , acDialog +acHidden
With Forms!dlgMyDialog
!cmbMyComboBox.Rowsource = ...
!cmdClose.Tag = "Modal"
.Visible = True ' <= code pauses here
End With
This is something you can use when you need to open a modal form (with acDialog) from another form opened with acDialog. That is, open the new dialog with acDialog + acHidden, and in the OnOpen event of the child form set .Visible = True and the parent (i.e., calling) form's .Visible = False. To restore the calling form to dialog mode, set the calling form's .Visible = True in the child form's OnClose event.
The drawback of this approach from my point of view is that the two forms have to know too much about each other. I prefer that the dialog form be usable from multiple contexts, which means no hardwired references to any of the forms that might call it (and it might be called in a code-only context, rather than from another form). But when you need to do this kind of thing, it's a way to get it done.
Upvotes: 0
Reputation: 97101
Consider passing a value in OpenArgs to indicate whether the form was opened with acDialog.
Upvotes: 1
Reputation: 11138
I'd advise you to refer to the 'screen.activeForm' object instead of the 'Me' instance of your form. To see what I mean, try the following
(1) open your form
(2) go to the VBA debugging window
type:
? screen.activeForm.modal<Enter>
<Answer>True
type
screen.activeForm.modal = False<Enter>
type
? screen.activeForm.modal<Enter>
<Answer>False
Upvotes: -1