Как проверить состояние формы Access 2003, модальной или немодальной? - PullRequest
3 голосов
/ 10 сентября 2009

Для проекта, работающего под Access 2003, у меня есть Форма, которая обычно устанавливается без режима, но в некоторых случаях открывается как acDialog и, следовательно, модально.

Эта форма теперь должна проверить, является ли она модальной или нет, чтобы изменить ее поведение при нажатии кнопки соответственно.

Me.Form.Modal

возвращает только значение свойства, указанное в режиме разработки, а не текущее состояние.

Я нашел аналогичный ответ для VB, который предлагает использовать API-вызов GetWindowLong для «пользователя», но это не переводит в VBA (Microsoft KnowledgeBase 77316), я боюсь: Access2003 не может найти файл «user» .

Вкратце: Есть ли надежный способ определить, является ли сама форма модальной или немодальной из этой формы?

ТИА.

Edit: Кажется, я помню, что Me.Form на самом деле эквивалентен только мне. Насколько я помню, свойство формы является значением по умолчанию, поэтому, если вы его опустите, оно будет принято. Независимо от того, Me.Modal и Me.Form.Modal предоставляют значение «false» независимо от способа открытия формы.

Ответы [ 5 ]

4 голосов
/ 17 ноября 2012

Я знаю, что это старо и ответили. Я просто хотел отметить, что решение p122 на самом деле не читает модальное состояние окна, а состояние всплывающего окна, что меня устраивает, потому что это то, что я искал.

Если форма открывается в модальном не всплывающем окне, функция Is12odal в p122 возвращает false. Если форма открывается в немодальном всплывающем окне, IsModal возвращает true. Таким образом, IsModal на самом деле IsPopup.

3 голосов
/ 11 сентября 2009

Разобрался с API (потребовал немного взлома, так как Access, я думаю, работает с формами)

Поместите это в модуль

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

Тогда в вашем событии form_Load (или где-либо еще)

  MsgBox "Hi I'm " & IIf(IsModal(me.Hwnd), "Modal", "Not Modal")
1 голос
/ 10 сентября 2009

Рассмотрите возможность передачи значения в OpenArgs, чтобы указать, была ли форма открыта с помощью acDialog.

0 голосов
/ 10 сентября 2009

Я не обязательно рекомендую это для текущей проблемы (хотя это может быть решение), но это может пригодиться в некоторых ситуациях, и это открыть форму с помощью acDialog + acHidden, изменить ее свойства, а затем установить .Visible = True. Это приводит к тому, что форма становится модальной в той точке, в которой она появляется, а не в точке, в которой она открыта. Таким образом, код выполняется до тех пор, пока форма не будет установлена ​​в .Visible, а затем остановится, как это было бы только с аргументом acDialog в команде OpenForm:

  DoCmd.OpenForm "dlgMyDialog", , , , , acDialog +acHidden 
  With Forms!dlgMyDialog
    !cmbMyComboBox.Rowsource = ...
    !cmdClose.Tag = "Modal"
    .Visible = True ' <= code pauses here
  End With

Это то, что вы можете использовать, когда вам нужно открыть модальную форму (с помощью acDialog) из другой формы, открытой с помощью acDialog. То есть откройте новый диалог с помощью acDialog + acHidden и в событии OnOpen дочерней формы установите .Visible = True и родительской (то есть вызывающей) формы .Visible = False. Чтобы перевести форму вызова в диалоговый режим, задайте .Visible = True формы вызова в событии OnClose дочерней формы.

Недостаток этого подхода, с моей точки зрения, заключается в том, что эти две формы должны слишком много знать друг о друге. Я предпочитаю, чтобы диалоговую форму можно было использовать из нескольких контекстов, что означает отсутствие зашитых ссылок на любую из форм, которые могут ее вызывать (и она может вызываться в контексте только кода, а не из другой формы). Но когда вам нужно сделать что-то подобное, это способ сделать это.

0 голосов
/ 10 сентября 2009

Я бы посоветовал вам ссылаться на объект 'screen.activeForm' вместо экземпляра 'Me' вашей формы. Чтобы понять, что я имею в виду, попробуйте следующее

(1) открыть форму

(2) перейти в окно отладки VBA

Тип:

? screen.activeForm.modal<Enter>
<Answer>True

тип

screen.activeForm.modal = False<Enter>

тип

? screen.activeForm.modal<Enter>
<Answer>False
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...