From: Jon Lewis on
No but............

I was using Access 2007 (albeit mdb file format). Just opened the file in
Access 2000 and yes I get what you get - very strange. It loses it's Modal
state but the code (at least from the calling procedure) is still suspended
i.e. my "frm2 closed" message doesn't appear until I close frm2.

I added Me.Modal = True to the end of frm2's On Load procedure and that
seems to bring back the Modal state.

Why A2K7 & A2k should be different must be down to version differences in
how the Access Forms (as windows) are subclassed. I doubt you'll get to the
bottom of what's going on although you could try different api calls (maybe
SetWindowPos or MoveWindow) to see if the effect is the same.

Hopefully the extra Me.Modal = True will work for you as code is definitely
suspended in the calling procedure anyway and re-setting the Modal state
should replicate acDialog elsewhere.

HTH

Jon

"MacDermott" <macdermott(a)NoSpam.com> wrote in message
news:%23SVD3qA2KHA.5796(a)TK2MSFTNGP06.phx.gbl...
> Try this:
> Put a second command button on frm1 - have it pop up some sort of
> msgbox.
> Now click Command0 to open frm2.
> Go back and click the second button on frm1.
> I get a msgbox in this scenario - do you?
> In contrast, if I delete (or comment out) the code that changes the
> position of frm2,
> frm1 can't get the focus after frm2 has been opened.
>
> Can you reproduce this?
>
> TIA!
>
>
> "Jon Lewis" <jon.lewis(a)cutthespambtinternet.com> wrote in message
> news:uvMSHm%231KHA.2156(a)TK2MSFTNGP02.phx.gbl...
>> Sorry - I misunderstood. I can't reproduce the problem though. I'm
>> opening frm2 from a Command Button on frm1:
>>
>> On Error GoTo Err_Command0_Click
>> DoCmd.OpenForm "frm2", , , , , acDialog
>> MsgBox "frm2 closed!"
>> Exit_Command0_Click:
>> Exit Sub
>> Err_Command0_Click:
>> MsgBox Err.Description
>> Resume Exit_Command0_Click
>>
>> This is what's in frm2 On Load:
>>
>> Dim WinEst As WINDOWPLACEMENT
>> Dim rtn As Long
>> Dim rct As RECT
>> Dim rct2 As RECT
>>
>> rtn = GetWindowPlacement(Me.hwnd, WinEst)
>> rct = WinEst.rcNormalPosition
>> rct2.Bottom = (rct.Bottom - rct.Top) + 10
>> rct2.Left = 10
>> rct2.Right = (rct.Right - rct.Left) + 10
>> rct2.Top = 10
>>
>> WinEst.Length = Len(WinEst)
>> WinEst.showCmd = SW_SHOWNORMAL
>> WinEst.rcNormalPosition = rct2
>>
>> rtn = SetWindowPlacement(Me.hwnd, WinEst)
>>
>> frm2's Modularity is preserved and the MsgBox from frm1 Command0 On Click
>> doesn't appear until after frm2 is closed.
>>
>> Is this similar to what you are doing or do you have something else going
>> on to affect frm2's window mode? You mentioned "if the form ... has been
>> opened acDialog". Is it opened acWindowNormal sometimes? Could it be
>> already open (maybe hidden) when the OpenForm acDialog command is
>> executed?
>>
>> Jon
>>
>> "MacDermott" <macdermott(a)NoSpam.com> wrote in message
>> news:esKRqE%231KHA.140(a)TK2MSFTNGP05.phx.gbl...
>>> Thank you so much for your input on this, Jon!
>>>
>>> Perhaps I didn't explain the problem properly:
>>> When I open a form with acDialog (yes, I'm using DoCmd.OpenForm), the
>>> form placement is correct.
>>> The problem is that after it has been repositioned, it's no longer
>>> modal; although it's pop-up (always remains displayed as the top layer),
>>> the user can work in the form below it.
>>> The whole point of opening it acDialog was to prevent the user
>>> from working in the other form until this one is closed.
>>>
>>> Any ideas?
>>> TIA
>>>
>>> "Jon Lewis" <jon.lewis(a)cutthespambtinternet.com> wrote in message
>>> news:endnngz1KHA.5816(a)TK2MSFTNGP04.phx.gbl...
>>>> What may be happening here is that normally the SetWindowsPlacement
>>>> call will position the form relative to the main Access window but if
>>>> the form is opened acDialog then the form will be positioned relative
>>>> to the Screen.
>>>>
>>>> If a form is opened acDialog then it's presumably done with
>>>> Docmd.OpenForm, so you can use the OpenArgs parameter to indicate this.
>>>> Then your Form's On Load event can check the OpenArgs value and adjust
>>>> the SetWindowPlacement call accordingly to take into account the Access
>>>> window position in the acDialog case.
>>>>
>>>> HTH
>>>> Jon
>>>>
>>>>
>>>>
>>>>
>>>> "MacDermott" <macdermott(a)NoSpam.com> wrote in message
>>>> news:u6GCPRs1KHA.1420(a)TK2MSFTNGP02.phx.gbl...
>>>>> My client asked for functionality which would let his users save the
>>>>> position of a form, so that the next time it's opened (on that
>>>>> system), it returns to the saved position. I achieved this using the
>>>>> GetWindowPlacement and SetWindowPlacement API calls.
>>>>> That worked fine, until my client noticed that if the form being
>>>>> repositioned (this occurs in the OnLoad event) has been opened
>>>>> acDialog, it loses this property.
>>>>> I haven't even been able to figure out a way to tell whether the
>>>>> form is opened acDialog.
>>>>>
>>>>> Any ideas?
>>>>> TIA
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>


From: MacDermott on
Thanks so much for your help on this, Jon!
The insight about the behavior changing with Access version may be
enough for my client...

I've been using Access 2003 (mdb, of course).

So here's the next aspect of the problem:

This application has over 100 forms, and I would estimate at least several
dozen of them use this position tracking.
I'm not sure how many of them are opened with acDialog - I know it's a
mix.
(My client does the basic development - I only get called in when he
gets stuck...)
I'm not even sure but what some forms are sometimes opened acDialog,
sometimes not.
So I've written a generic procedure which he can call with just a single
line of code.
To implement your suggestion of adding Me.Modal = True, it would be
great if I could somehow figure out programmatically whether the form had
been opened with acDialog. Clearly, even though the behavior is a lot like
having both Modal and Popup true, normally opening a window with acDialog
doesn't set those properties...

TIA!

(I may also try using some of those other API calls...)


"Jon Lewis" <jon.lewis(a)cutthespambtinternet.com> wrote in message
news:OYjhNGB2KHA.312(a)TK2MSFTNGP05.phx.gbl...
> No but............
>
> I was using Access 2007 (albeit mdb file format). Just opened the file in
> Access 2000 and yes I get what you get - very strange. It loses it's
> Modal state but the code (at least from the calling procedure) is still
> suspended i.e. my "frm2 closed" message doesn't appear until I close frm2.
>
> I added Me.Modal = True to the end of frm2's On Load procedure and that
> seems to bring back the Modal state.
>
> Why A2K7 & A2k should be different must be down to version differences in
> how the Access Forms (as windows) are subclassed. I doubt you'll get to
> the bottom of what's going on although you could try different api calls
> (maybe SetWindowPos or MoveWindow) to see if the effect is the same.
>
> Hopefully the extra Me.Modal = True will work for you as code is
> definitely suspended in the calling procedure anyway and re-setting the
> Modal state should replicate acDialog elsewhere.
>
> HTH
>
> Jon
>
> "MacDermott" <macdermott(a)NoSpam.com> wrote in message
> news:%23SVD3qA2KHA.5796(a)TK2MSFTNGP06.phx.gbl...
>> Try this:
>> Put a second command button on frm1 - have it pop up some sort of
>> msgbox.
>> Now click Command0 to open frm2.
>> Go back and click the second button on frm1.
>> I get a msgbox in this scenario - do you?
>> In contrast, if I delete (or comment out) the code that changes the
>> position of frm2,
>> frm1 can't get the focus after frm2 has been opened.
>>
>> Can you reproduce this?
>>
>> TIA!
>>
>>
>> "Jon Lewis" <jon.lewis(a)cutthespambtinternet.com> wrote in message
>> news:uvMSHm%231KHA.2156(a)TK2MSFTNGP02.phx.gbl...
>>> Sorry - I misunderstood. I can't reproduce the problem though. I'm
>>> opening frm2 from a Command Button on frm1:
>>>
>>> On Error GoTo Err_Command0_Click
>>> DoCmd.OpenForm "frm2", , , , , acDialog
>>> MsgBox "frm2 closed!"
>>> Exit_Command0_Click:
>>> Exit Sub
>>> Err_Command0_Click:
>>> MsgBox Err.Description
>>> Resume Exit_Command0_Click
>>>
>>> This is what's in frm2 On Load:
>>>
>>> Dim WinEst As WINDOWPLACEMENT
>>> Dim rtn As Long
>>> Dim rct As RECT
>>> Dim rct2 As RECT
>>>
>>> rtn = GetWindowPlacement(Me.hwnd, WinEst)
>>> rct = WinEst.rcNormalPosition
>>> rct2.Bottom = (rct.Bottom - rct.Top) + 10
>>> rct2.Left = 10
>>> rct2.Right = (rct.Right - rct.Left) + 10
>>> rct2.Top = 10
>>>
>>> WinEst.Length = Len(WinEst)
>>> WinEst.showCmd = SW_SHOWNORMAL
>>> WinEst.rcNormalPosition = rct2
>>>
>>> rtn = SetWindowPlacement(Me.hwnd, WinEst)
>>>
>>> frm2's Modularity is preserved and the MsgBox from frm1 Command0 On
>>> Click doesn't appear until after frm2 is closed.
>>>
>>> Is this similar to what you are doing or do you have something else
>>> going on to affect frm2's window mode? You mentioned "if the form ...
>>> has been opened acDialog". Is it opened acWindowNormal sometimes? Could
>>> it be already open (maybe hidden) when the OpenForm acDialog command is
>>> executed?
>>>
>>> Jon
>>>
>>> "MacDermott" <macdermott(a)NoSpam.com> wrote in message
>>> news:esKRqE%231KHA.140(a)TK2MSFTNGP05.phx.gbl...
>>>> Thank you so much for your input on this, Jon!
>>>>
>>>> Perhaps I didn't explain the problem properly:
>>>> When I open a form with acDialog (yes, I'm using DoCmd.OpenForm),
>>>> the form placement is correct.
>>>> The problem is that after it has been repositioned, it's no longer
>>>> modal; although it's pop-up (always remains displayed as the top
>>>> layer),
>>>> the user can work in the form below it.
>>>> The whole point of opening it acDialog was to prevent the user
>>>> from working in the other form until this one is closed.
>>>>
>>>> Any ideas?
>>>> TIA
>>>>
>>>> "Jon Lewis" <jon.lewis(a)cutthespambtinternet.com> wrote in message
>>>> news:endnngz1KHA.5816(a)TK2MSFTNGP04.phx.gbl...
>>>>> What may be happening here is that normally the SetWindowsPlacement
>>>>> call will position the form relative to the main Access window but if
>>>>> the form is opened acDialog then the form will be positioned relative
>>>>> to the Screen.
>>>>>
>>>>> If a form is opened acDialog then it's presumably done with
>>>>> Docmd.OpenForm, so you can use the OpenArgs parameter to indicate
>>>>> this. Then your Form's On Load event can check the OpenArgs value and
>>>>> adjust the SetWindowPlacement call accordingly to take into account
>>>>> the Access window position in the acDialog case.
>>>>>
>>>>> HTH
>>>>> Jon
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> "MacDermott" <macdermott(a)NoSpam.com> wrote in message
>>>>> news:u6GCPRs1KHA.1420(a)TK2MSFTNGP02.phx.gbl...
>>>>>> My client asked for functionality which would let his users save the
>>>>>> position of a form, so that the next time it's opened (on that
>>>>>> system), it returns to the saved position. I achieved this using the
>>>>>> GetWindowPlacement and SetWindowPlacement API calls.
>>>>>> That worked fine, until my client noticed that if the form being
>>>>>> repositioned (this occurs in the OnLoad event) has been opened
>>>>>> acDialog, it loses this property.
>>>>>> I haven't even been able to figure out a way to tell whether the
>>>>>> form is opened acDialog.
>>>>>>
>>>>>> Any ideas?
>>>>>> TIA
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>


From: Jon Lewis on
Does this help:

Private Const GWL_EXSTYLE = (-20)
Private Const WS_EX_MDICHILD = &H40
Private Const GWL_STYLE = (-16)
Private Const GW_OWNER = 4

Private Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, ByVal wCmd As Long) As Long


Private Const WS_DISABLED = &H8000000
Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _
(ByVal hwnd As Long, ByVal nIndex As Long) As Long


This is the generally accepted way of testing modularity and it returns
False under these circumstances:

Private Function IsWindowModal(hwnd As Long) As Boolean
Dim hwndOwner As Long
hwndOwner = GetWindow(hwnd, GW_OWNER)
If hwndOwner Then
IsWindowModal = (GetWindowLong(hwndOwner, GWL_STYLE) _
And WS_DISABLED)
End If
End Function


However this one returns True.


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


How reliable it is I don't know because it seems to be relating modularity
just to whether a window is a MDICHILD but it does seem to work . Using
OpenArgs as below would be totally reliable or use IsModal if you want. By
the way MoveWindow doesn't remove modularity so maybe you could just use
that.

To open frm2:
DoCmd.OpenForm "frm2", , , , , acDialog, "Dialog"
In frm2's Load Event:
PosWindow Me
In a Standard Module
Sub PosWindow(frm As Form)
Dim WinEst As WINDOWPLACEMENT
Dim rtn As Long
Dim rct As RECT
Dim rct2 As RECT
rtn = GetWindowPlacement(frm.hWnd, WinEst)
rct = WinEst.rcNormalPosition
rct2.Bottom = (rct.Bottom - rct.Top) + 10
rct2.Left = 10
rct2.Right = (rct.Right - rct.Left) + 10
rct2.Top = 10
WinEst.Length = Len(WinEst)
WinEst.showCmd = SW_SHOWNORMAL
WinEst.rcNormalPosition = rct2
rtn = SetWindowPlacement(frm.hWnd, WinEst)
If frm.OpenArgs = "Dialog" Then
frm.Modal = True
End If
End Sub

Jon

"MacDermott" <macdermott(a)NoSpam.com> wrote in message
news:u%23ckppJ2KHA.5880(a)TK2MSFTNGP02.phx.gbl...
> Thanks so much for your help on this, Jon!
> The insight about the behavior changing with Access version may be
> enough for my client...
>
> I've been using Access 2003 (mdb, of course).
>
> So here's the next aspect of the problem:
>
> This application has over 100 forms, and I would estimate at least several
> dozen of them use this position tracking.
> I'm not sure how many of them are opened with acDialog - I know it's a
> mix.
> (My client does the basic development - I only get called in when
> he gets stuck...)
> I'm not even sure but what some forms are sometimes opened acDialog,
> sometimes not.
> So I've written a generic procedure which he can call with just a single
> line of code.
> To implement your suggestion of adding Me.Modal = True, it would be
> great if I could somehow figure out programmatically whether the form had
> been opened with acDialog. Clearly, even though the behavior is a lot
> like having both Modal and Popup true, normally opening a window with
> acDialog doesn't set those properties...
>
> TIA!
>
> (I may also try using some of those other API calls...)
>
>
> "Jon Lewis" <jon.lewis(a)cutthespambtinternet.com> wrote in message
> news:OYjhNGB2KHA.312(a)TK2MSFTNGP05.phx.gbl...
>> No but............
>>
>> I was using Access 2007 (albeit mdb file format). Just opened the file
>> in Access 2000 and yes I get what you get - very strange. It loses it's
>> Modal state but the code (at least from the calling procedure) is still
>> suspended i.e. my "frm2 closed" message doesn't appear until I close
>> frm2.
>>
>> I added Me.Modal = True to the end of frm2's On Load procedure and that
>> seems to bring back the Modal state.
>>
>> Why A2K7 & A2k should be different must be down to version differences in
>> how the Access Forms (as windows) are subclassed. I doubt you'll get to
>> the bottom of what's going on although you could try different api calls
>> (maybe SetWindowPos or MoveWindow) to see if the effect is the same.
>>
>> Hopefully the extra Me.Modal = True will work for you as code is
>> definitely suspended in the calling procedure anyway and re-setting the
>> Modal state should replicate acDialog elsewhere.
>>
>> HTH
>>
>> Jon
>>
>> "MacDermott" <macdermott(a)NoSpam.com> wrote in message
>> news:%23SVD3qA2KHA.5796(a)TK2MSFTNGP06.phx.gbl...
>>> Try this:
>>> Put a second command button on frm1 - have it pop up some sort of
>>> msgbox.
>>> Now click Command0 to open frm2.
>>> Go back and click the second button on frm1.
>>> I get a msgbox in this scenario - do you?
>>> In contrast, if I delete (or comment out) the code that changes the
>>> position of frm2,
>>> frm1 can't get the focus after frm2 has been opened.
>>>
>>> Can you reproduce this?
>>>
>>> TIA!
>>>
>>>
>>> "Jon Lewis" <jon.lewis(a)cutthespambtinternet.com> wrote in message
>>> news:uvMSHm%231KHA.2156(a)TK2MSFTNGP02.phx.gbl...
>>>> Sorry - I misunderstood. I can't reproduce the problem though. I'm
>>>> opening frm2 from a Command Button on frm1:
>>>>
>>>> On Error GoTo Err_Command0_Click
>>>> DoCmd.OpenForm "frm2", , , , , acDialog
>>>> MsgBox "frm2 closed!"
>>>> Exit_Command0_Click:
>>>> Exit Sub
>>>> Err_Command0_Click:
>>>> MsgBox Err.Description
>>>> Resume Exit_Command0_Click
>>>>
>>>> This is what's in frm2 On Load:
>>>>
>>>> Dim WinEst As WINDOWPLACEMENT
>>>> Dim rtn As Long
>>>> Dim rct As RECT
>>>> Dim rct2 As RECT
>>>>
>>>> rtn = GetWindowPlacement(Me.hwnd, WinEst)
>>>> rct = WinEst.rcNormalPosition
>>>> rct2.Bottom = (rct.Bottom - rct.Top) + 10
>>>> rct2.Left = 10
>>>> rct2.Right = (rct.Right - rct.Left) + 10
>>>> rct2.Top = 10
>>>>
>>>> WinEst.Length = Len(WinEst)
>>>> WinEst.showCmd = SW_SHOWNORMAL
>>>> WinEst.rcNormalPosition = rct2
>>>>
>>>> rtn = SetWindowPlacement(Me.hwnd, WinEst)
>>>>
>>>> frm2's Modularity is preserved and the MsgBox from frm1 Command0 On
>>>> Click doesn't appear until after frm2 is closed.
>>>>
>>>> Is this similar to what you are doing or do you have something else
>>>> going on to affect frm2's window mode? You mentioned "if the form ...
>>>> has been opened acDialog". Is it opened acWindowNormal sometimes?
>>>> Could it be already open (maybe hidden) when the OpenForm acDialog
>>>> command is executed?
>>>>
>>>> Jon
>>>>
>>>> "MacDermott" <macdermott(a)NoSpam.com> wrote in message
>>>> news:esKRqE%231KHA.140(a)TK2MSFTNGP05.phx.gbl...
>>>>> Thank you so much for your input on this, Jon!
>>>>>
>>>>> Perhaps I didn't explain the problem properly:
>>>>> When I open a form with acDialog (yes, I'm using DoCmd.OpenForm),
>>>>> the form placement is correct.
>>>>> The problem is that after it has been repositioned, it's no longer
>>>>> modal; although it's pop-up (always remains displayed as the top
>>>>> layer),
>>>>> the user can work in the form below it.
>>>>> The whole point of opening it acDialog was to prevent the user
>>>>> from working in the other form until this one is closed.
>>>>>
>>>>> Any ideas?
>>>>> TIA
>>>>>
>>>>> "Jon Lewis" <jon.lewis(a)cutthespambtinternet.com> wrote in message
>>>>> news:endnngz1KHA.5816(a)TK2MSFTNGP04.phx.gbl...
>>>>>> What may be happening here is that normally the SetWindowsPlacement
>>>>>> call will position the form relative to the main Access window but if
>>>>>> the form is opened acDialog then the form will be positioned relative
>>>>>> to the Screen.
>>>>>>
>>>>>> If a form is opened acDialog then it's presumably done with
>>>>>> Docmd.OpenForm, so you can use the OpenArgs parameter to indicate
>>>>>> this. Then your Form's On Load event can check the OpenArgs value and
>>>>>> adjust the SetWindowPlacement call accordingly to take into account
>>>>>> the Access window position in the acDialog case.
>>>>>>
>>>>>> HTH
>>>>>> Jon
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> "MacDermott" <macdermott(a)NoSpam.com> wrote in message
>>>>>> news:u6GCPRs1KHA.1420(a)TK2MSFTNGP02.phx.gbl...
>>>>>>> My client asked for functionality which would let his users save the
>>>>>>> position of a form, so that the next time it's opened (on that
>>>>>>> system), it returns to the saved position. I achieved this using
>>>>>>> the GetWindowPlacement and SetWindowPlacement API calls.
>>>>>>> That worked fine, until my client noticed that if the form being
>>>>>>> repositioned (this occurs in the OnLoad event) has been opened
>>>>>>> acDialog, it loses this property.
>>>>>>> I haven't even been able to figure out a way to tell whether the
>>>>>>> form is opened acDialog.
>>>>>>>
>>>>>>> Any ideas?
>>>>>>> TIA
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>
>