p122
p122

Reputation: 33

How to check the State of a Access 2003 Form, Modal or Modeless?

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

Answers (5)

echevalier
echevalier

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

DJ.
DJ.

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

David-W-Fenton
David-W-Fenton

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

HansUp
HansUp

Reputation: 97101

Consider passing a value in OpenArgs to indicate whether the form was opened with acDialog.

Upvotes: 1

Philippe Grondier
Philippe Grondier

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

Related Questions