Jashin_212
New member
- Local time
- Today, 11:34
- Joined
- Jan 3, 2016
- Messages
- 2
Dear All,
I am new to this forum, so thank you in advance for your help with this thread.
I am trying to solve what I think is an age-old problem with Access Forms. I am developing a database where a pop-up main form opens several other pop-up forms that I want to remain within the border of the main form. When the main form is moved or resized I need to move and resize also the other open forms accordingly. I am basically trying to give my database a look similar to a real application where a main form has several child forms.
I am using the event Detail_Paint() to detect when the main form is changed in size to adjust the size of the other forms and it seems to work. However there is no event associated with the movement on screen of the form. MouseMove() does not seem to work because when the user moves the mouse curson on the form caption it doesn't fire. I have solved the problem using a Timer that checks every 10 ms the position of the main form and changes the position of the other forms accordingly. However, this creates an annoying flickering of the monitor and also problems when the user is entering text in the controls.
I have read that is possible to subclass the form and catch the WM_MOVING message to the window. I have developed some test code for this but when I try to run it Access stops working and I have to use the Task Manager to shut it down. I am using Access 2016 Professional 64bit on a Windows 10 64bit system.
Here is the code I have written so far.
' This code goes into a general module (mdl_subclass)
' When subclassing shows the coordinates of the window in its caption
Option Explicit
Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" _
(ByVal hWnd As LongPtr, _
ByVal nIndex As LongPtr, _
ByVal dwNewLong As LongPtr) As LongPtr
Declare PtrSafe Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As LongPtr, _
ByVal hWnd As LongPtr, _
ByVal Msg As LongPtr, _
ByVal wParam As LongPtr, _
ByVal lParam As LongPtr) As LongPtr
Public Const GWL_WNDPROC = (-4)
Private Const WM_MOVE = &H3
Dim m_PrevProc As LongPtr
Public Sub SubClass_On(ByVal hWnd As Long)
m_PrevProc = SetWindowLongPtr(hWnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub SubClass_Off(ByVal hWnd As Long)
SetWindowLongPtr hWnd, GWL_WNDPROC, m_PrevProc
End Sub
Private Function WindowProc(ByVal hWnd As LongPtr, ByVal uMsg As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
WindowProc = CallWindowProc(m_PrevProc, hWnd, uMsg, wParam, lParam)
If uMsg = WM_MOVE Then
Form_frm_main.Me_OnMove lParam And CLng(&HFFFF&), lParam \ CLng(&HFFFF&)
End If
End Function
' This code instead goes into the form module, starts subclassing on form loading and stop subclassing on form unload
Private Sub Form_Load()
SubClass_On Me.hWnd
End Sub
Private Sub Form_Unload(Cancel As Integer)
SubClass_Off Me.hWnd
End Sub
Friend Sub Me_OnMove(ByVal xPos As Long, ByVal yPos As Long)
Me.Caption = "x=" & xPos & "; y=" & yPos
End Sub
...any idea on how to fix my code? Or any alternative suggestions to my problem?
Thanks
I am new to this forum, so thank you in advance for your help with this thread.
I am trying to solve what I think is an age-old problem with Access Forms. I am developing a database where a pop-up main form opens several other pop-up forms that I want to remain within the border of the main form. When the main form is moved or resized I need to move and resize also the other open forms accordingly. I am basically trying to give my database a look similar to a real application where a main form has several child forms.
I am using the event Detail_Paint() to detect when the main form is changed in size to adjust the size of the other forms and it seems to work. However there is no event associated with the movement on screen of the form. MouseMove() does not seem to work because when the user moves the mouse curson on the form caption it doesn't fire. I have solved the problem using a Timer that checks every 10 ms the position of the main form and changes the position of the other forms accordingly. However, this creates an annoying flickering of the monitor and also problems when the user is entering text in the controls.
I have read that is possible to subclass the form and catch the WM_MOVING message to the window. I have developed some test code for this but when I try to run it Access stops working and I have to use the Task Manager to shut it down. I am using Access 2016 Professional 64bit on a Windows 10 64bit system.
Here is the code I have written so far.
' This code goes into a general module (mdl_subclass)
' When subclassing shows the coordinates of the window in its caption
Option Explicit
Declare PtrSafe Function SetWindowLongPtr Lib "user32" Alias "SetWindowLongPtrA" _
(ByVal hWnd As LongPtr, _
ByVal nIndex As LongPtr, _
ByVal dwNewLong As LongPtr) As LongPtr
Declare PtrSafe Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _
(ByVal lpPrevWndFunc As LongPtr, _
ByVal hWnd As LongPtr, _
ByVal Msg As LongPtr, _
ByVal wParam As LongPtr, _
ByVal lParam As LongPtr) As LongPtr
Public Const GWL_WNDPROC = (-4)
Private Const WM_MOVE = &H3
Dim m_PrevProc As LongPtr
Public Sub SubClass_On(ByVal hWnd As Long)
m_PrevProc = SetWindowLongPtr(hWnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub SubClass_Off(ByVal hWnd As Long)
SetWindowLongPtr hWnd, GWL_WNDPROC, m_PrevProc
End Sub
Private Function WindowProc(ByVal hWnd As LongPtr, ByVal uMsg As LongPtr, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
WindowProc = CallWindowProc(m_PrevProc, hWnd, uMsg, wParam, lParam)
If uMsg = WM_MOVE Then
Form_frm_main.Me_OnMove lParam And CLng(&HFFFF&), lParam \ CLng(&HFFFF&)
End If
End Function
' This code instead goes into the form module, starts subclassing on form loading and stop subclassing on form unload
Private Sub Form_Load()
SubClass_On Me.hWnd
End Sub
Private Sub Form_Unload(Cancel As Integer)
SubClass_Off Me.hWnd
End Sub
Friend Sub Me_OnMove(ByVal xPos As Long, ByVal yPos As Long)
Me.Caption = "x=" & xPos & "; y=" & yPos
End Sub
...any idea on how to fix my code? Or any alternative suggestions to my problem?
Thanks