Problem when subclassing form (1 Viewer)

NikBab

New member
Local time
Today, 21:14
Joined
Sep 16, 2019
Messages
6
Hello,


I am trying to subclass a form in order to catch the event that occurs when the caption bar of the form is double clicked. The reason for this is that I want to maximize the form when double clicking the caption bar but within the confines of the client area of the main Access window.


In order to achieve this I have a standard module with the following code:


Code:
Type Trect
      left  As Long
      top  As Long
      Right  As Long
      Bottom  As Long
End Type
Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetClientRect Lib "user32.dll" (ByVal HWindow As Long, lpRect As Trect) As Boolean
Declare Function MoveWindow Lib "user32.dll" (ByVal HWindow As Long, ByVal X As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal bRepaint As Boolean) As Boolean
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long

Global Const WM_NCLBUTTONDBLCLK = &HA3
Global Const HTCAPTION = 2
Global Const GWL_WNDPROC = (-4&)
 
Public lngDefaultProc As Long

Public Function MyProc(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Dim lngParent As Long
    Dim lngReturn As Long
    Dim lngWidth As Long
    Dim lngHeight As Long
    Dim rct As Trect
           
    On Error Resume Next
    If msg = WM_NCLBUTTONDBLCLK And wParam = HTCAPTION Then
        lngParent = GetParent(hwnd)
        If lngParent <> 0 Then
            lngReturn = GetClientRect(lngParent, rct)
            If lngReturn <> 0 Then
                lngWidth = rct.Right - rct.left
                lngHeight = rct.Bottom - rct.top
                lngReturn = MoveWindow(hwnd, rct.left, rct.top, lngWidth, lngHeight, -1)
                MyProc = 0
                Exit Function
            End If
        End If
    End If
    
    MyProc = CallWindowProc(lngDefaultProc, hwnd, msg, wParam, lParam)

End Function


Within the code moule of the form I use the Form_Load and Form_Unload
events as follows:


Code:
Private Sub Form_Load()
lngDefaultProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf MyProc)
DoEvents
End Sub

Private Sub Form_Unload(Cancel As Integer)
 If lngDefaultProc <> 0 Then
    Call SetWindowLong(Me.hwnd, GWL_WNDPROC, lngDefaultProc)
    lngDefaultProc = 0
 End If
End Sub


The problem is that when I open the form, the application freezes
and becomes unresponsive.
Could you please tell me what is it that I am doing wrong?


I am using the attached mdb file with MS Access 2003.



Thank you very much in advance!


Best Regards
 

Attachments

  • db2.mdb
    176 KB · Views: 238

Nixversteher

New member
Local time
Today, 14:14
Joined
Feb 25, 2018
Messages
16
Subclassing and VBA have never been real friends.
 
Last edited:

sonic8

AWF VIP
Local time
Today, 22:14
Joined
Oct 27, 2015
Messages
998
The problem is that when I open the form, the application freezes and becomes unresponsive.
I didn't look at your code.

However, there's a general issue you need to be aware of when using subclassing with VBA.
If the VBA-Editor is (or was!) open and you subclass a window, there will be an extra message generated for each message your window proc processes. Meaning, your code will not be able to keep up with the flood of messages this generates.

Conclusion: You must not open the VBA-Editor when subclassing the window!
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 05:14
Joined
May 7, 2009
Messages
19,169
there is no difference on double-clicking Form1 (with code) and the form I made (frmNoCode).
they all maximized confined at access window.
 

Attachments

  • db2.mdb
    304 KB · Views: 231

NikBab

New member
Local time
Today, 21:14
Joined
Sep 16, 2019
Messages
6
Thank you all for your answers!


Conclusion: You must not open the VBA-Editor when subclassing the window!


The problem is that the application hangs even if the VBA Editor window is closed


there is no difference on double-clicking Form1 (with code) and the form I made (frmNoCode). they all maximized confined at access window.


I am posting two images: 1.jpg and 2.jpg. The first one depicts what I am actually trying to achieve. That is the form is maximized to the extents of the client area of the main access window and the caption bar remains visible. The second image is the result that I get with no code just by using the native maximize functionality that ms access offers when the caption bar is double clicked or the maximize button is pressed. It is close to the desired result but the caption bar is not visible.



Best regards
 

Attachments

  • 1.jpg
    1.jpg
    93.6 KB · Views: 262
  • 2.jpg
    2.jpg
    70.3 KB · Views: 241

sonic8

AWF VIP
Local time
Today, 22:14
Joined
Oct 27, 2015
Messages
998
The problem is that the application hangs even if the VBA Editor window is closed
No, it doesn't.


To be more precise: The VBA Editor windows must never have been open before starting the subclassing.
 

Guus2005

AWF VIP
Local time
Today, 22:14
Joined
Jun 26, 2007
Messages
2,645
Fake it!

Remove the caption bar and replace it with a label.
Program the label onclick event to do what you want.

HTH:D
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 05:14
Joined
May 7, 2009
Messages
19,169
the inside "window" you are referring is of Class "mdiClient".
you should find a way to get the window Handle of this class, then use WindowRect to get its dimension.
if you are able to do that you can confine the form to that area only.
 

sonic8

AWF VIP
Local time
Today, 22:14
Joined
Oct 27, 2015
Messages
998
the inside "window" you are referring is of Class "mdiClient".
you should find a way to get the window Handle of this class, then use WindowRect to get its dimension.
if you are able to do that you can confine the form to that area only.
This is exactly what the code in the original post does. - It works, when not opening the VBA Editor.
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 05:14
Joined
May 7, 2009
Messages
19,169
no it's not:
Code:
        lngParent = GetParent(hwnd)
the parent of the form is MsAccess (Classname "oMain")
class "oMain" has other child window class: navigation pane, ribbon, vba editor, the MDIClient (the blank space to the right of navigation pane), combobox, etc
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 05:14
Joined
May 7, 2009
Messages
19,169
alredy checked that one
Code:
Private Sub Form_Load()
lngDefaultProc = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf MyProc)
DoEvents
End Sub
it passed the handle of Form1.

lngParent = GetParent(hwnd)

it get the handle of the Parent window (MSAccess) of Form1.
 

sonic8

AWF VIP
Local time
Today, 22:14
Joined
Oct 27, 2015
Messages
998
lngParent = GetParent(hwnd)

it get the handle of the Parent window (MSAccess) of Form1.
Then the form of the window handle is a pop up form. A pop up form it is not a child of the MDI client, it's parent is indeed the Access main window.

However, the form in the sample db provided by @NikBab is not a pop up form. His code will retrieve the window handle of the MDI client window.
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 05:14
Joined
May 7, 2009
Messages
19,169
all my samples are not pop up.

see this final example.
i am using the MDIClient, the form is not pop-up.
this will achieve what the OP want. but...

you cannot subclass a form in access, coz' it's heavily subclassed.
you can't double click on the title (access already has hooked on it) to maximize it without the title disappearing.

the form name is FinalForm.
 

Attachments

  • db2.mdb
    316 KB · Views: 227

Nixversteher

New member
Local time
Today, 14:14
Joined
Feb 25, 2018
Messages
16
This is an experiment (only 32bit) with your subclassing title bar double-click code where the editor can be open (hopefully).
But I think if you want to use subclassing it is better to outsource this to a dll using a suitable language.
 

Attachments

  • DblKlickTitelleiste.mdb
    272 KB · Views: 227

sonic8

AWF VIP
Local time
Today, 22:14
Joined
Oct 27, 2015
Messages
998
arnelgp, I've a hard time following you here.
Your line of argumentation appears to be contradicting the fact that the original sample posted by @NikBab does work.
you cannot subclass a form in access, coz' it's heavily subclassed.
Well, I read this claim a couple of times. Unfortunately, it always was missing convincing evidence or background information. Why is that so and who subclassed it? Microsoft? They have direct access to the source, why would they use subclassing?

Subclassing in VBA is certainly beyond what this language was intended for. I don't want to advocate it and one should only using it as a last resort after carefully considering the implications. However, your argument against is not compelling.
 
Last edited:

sonic8

AWF VIP
Local time
Today, 22:14
Joined
Oct 27, 2015
Messages
998
This is an experiment (only 32bit) with your subclassing title bar double-click code where the editor can be open (hopefully).
Thank you! This is impressive.

First, I'd like to confirm this actually works without the usual subclassing problem of the VBA Editor overwhelming itself with messages.

Second, I have to admit, I understand only very roughly what you are doing in your example's code. I guess, I lack the understanding of the underlying low level instructions.
Is there anything you would recommend for further reading to gain more understanding of your implementation?
 

NikBab

New member
Local time
Today, 21:14
Joined
Sep 16, 2019
Messages
6
I agree with sonic8 that the solution posted by Nixversteher works very well:
the application does not freeze and the form gets maximized as intended.
Thanks a lot!

However, I too would like some more information (if possible) regarding the implementation

Best regards
 

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 05:14
Joined
May 7, 2009
Messages
19,169
went back and review the sequence of events of the form.
when you double-click the title bar of the form, the Resize event fires.
so I capture it and direct it to my user defined sub.

there is no timer, no class, no subclassing here.
uses api to get the mdiClient of MSAccess.

32bit and 64bit mso compatible.
also tested on MSA 2019 x64.
 

Attachments

  • db2 (1).mdb
    276 KB · Views: 216

arnelgp

..forever waiting... waiting for jellybean!
Local time
Tomorrow, 05:14
Joined
May 7, 2009
Messages
19,169
arnelgp, I've a hard time following you here.
try googling the mdiClient window in access.

it is the middle portion of msa, where you create/edit forms/reports/queries/tables.
In short the workarea.
just right side of navigation pane, left of property sheet, below the ribbon.
 

Users who are viewing this thread

Top Bottom