Determining when user moves to webcontrol (1 Viewer)

CedarTree

Registered User.
Local time
Today, 11:56
Joined
Mar 2, 2018
Messages
248
I have a webcontrol on a form. I would like to know when they've moved to focus on that webcontrol. I also have a button on that form. What I'd like to do is know when a user has interacted with the webcontrol. I've tried setting a boolean to false when the user presses the button and then to true when the webcontrol has "enter" event, or "on focus", or "mouse move". Nothing seems to do the trick. I have a PDF open in the webcontrol. Not sure if that impacts anything. Help!?!?
 

CedarTree

Registered User.
Local time
Today, 11:56
Joined
Mar 2, 2018
Messages
248
P.S. If the user hovers over the PDF and uses their scroll wheel to navigate pages, I want to know that has happened too. Basically ANY interaction with the pdf (or webcontrol) I want to flag it. I don't need to know that they used mouse versus keyboard - just that they DID interact.
 

CedarTree

Registered User.
Local time
Today, 11:56
Joined
Mar 2, 2018
Messages
248
I tried another idea... but still no luck. I put the Access webcontrol in a subform, and tried all kinds of events trapping (whether at the form level or subform)... I still can't catch when a user interacts with the webcontrol, e.g., scrolling down the pdf either using the scroll bar or mouse wheel. My primary goal is to know when they've moved away from the initial PDF page.
 

CJ_London

Super Moderator
Staff member
Local time
Today, 16:56
Joined
Feb 19, 2013
Messages
12,766
Without the control having focus, none of the web control events will fire except the mousemove event.

focus will be received with the click and doubleclick events but suggest use the mousemove event to also set the focus to the web control.

If you use mousedown/mouseup events rather than the click events, you will get the XY coordinates of the mouse over the control - so if you know the coordinates of the button in the web form, you can determine if it has been clicked or not
 

CedarTree

Registered User.
Local time
Today, 11:56
Joined
Mar 2, 2018
Messages
248
I might try that. Is X, Y relative to the form, so that if the user moves the form, you still know where they are "in" the form?

ANOTHER QUESTION please.

I've set a global variable (say X) = Me.webControl.Object
And then I'm try to debug.print X.document.body.scrolltop... but I get Error 438 (object doesn't support this method). What am I missing?
 

CJ_London

Super Moderator
Staff member
Local time
Today, 16:56
Joined
Feb 19, 2013
Messages
12,766
X & Y are relative to the control top left

don't know about scroll top. Once the control has focus, it has a Hwnd and you can then inspect the Hwnd for all the child windows, including the scrollbars.

See this link, I've just uploaded an example. The code is what you want - in module1 you will find code which finds the scrollbar windows

https://www.access-programmers.co.uk/forums/showthread.php?p=1645701#post1645701
 

CedarTree

Registered User.
Local time
Today, 11:56
Joined
Mar 2, 2018
Messages
248
X & Y are relative to the control top left

don't know about scroll top. Once the control has focus, it has a Hwnd and you can then inspect the Hwnd for all the child windows, including the scrollbars.

See this link, I've just uploaded an example. The code is what you want - in module1 you will find code which finds the scrollbar windows

https://www.access-programmers.co.uk/forums/showthread.php?p=1645701#post1645701

The example file you have in that thread seems (I spent a little time digging) to be able to assess the Vertical and Horizontal position of a scroll bar within a form. But I think what I have is trickier. I'm looking for such variables on a scrollbar in a PDF opened up in a webcontrol. Is that possible? Further, it would help to be able to know the Maximum horizontal position of the scrollbar so that I can perhaps even estimate what page they are on.

Thanks!!!
 

CedarTree

Registered User.
Local time
Today, 11:56
Joined
Mar 2, 2018
Messages
248
To add more info... I used much of that coding as a test... e.g., fGetScrollBarPos and it seems to be grabbing information on the scroll bar on the form itself (in fact, on the form, I have NO scroll bars). The only scroll bar I have on the form, and the only one I want to get vertical pos on, is the scroll bar contained within the web control, contained on that form. And, that webcontrol is displaying a PDF which happens to be shown using Adobe.
 

CJ_London

Super Moderator
Staff member
Local time
Today, 16:56
Joined
Feb 19, 2013
Messages
12,766
a scrollbar is a scrollbar and is a window object. I assumed you were talking about a web control showing a pdf. So you can look at the scrollbar properties and determine its position and from that determine what part of the pdf is being displayed in the webcontrol window.

Further, it would help to be able to know the Maximum horizontal position of the scrollbar
the scrollbar object contains that information

Code:
Type SCROLLINFO
    cbSize As Long
    fMask As Long
    nMin As Long
    [COLOR="Red"]nMax As Long 'max value for nPos for last/left (vertical=no of records, horizontal=twips or pixels?[/COLOR]
    nPage As Long 'number of records visible in window (vertical) defines size of scroll button?
    nPos As Long 'position of scroll bar (0=top or left)
    nTrackPos As Long
End Type
 

CJ_London

Super Moderator
Staff member
Local time
Today, 16:56
Joined
Feb 19, 2013
Messages
12,766
revisit the link I provided, there is more discussion there - in your case a web control, in the link case, a listbox
 

CedarTree

Registered User.
Local time
Today, 11:56
Joined
Mar 2, 2018
Messages
248
OKay - excuse the ignorance. This is a level of programming that is probably just above my head. From what I can tell, is it as simple as moving focus to the object? But I think I've done that when I select the webcontrol with my mouse... I guess i just don't see how to tell VBA to grab the hwnd of the webcontrol on the form.
 

CJ_London

Super Moderator
Staff member
Local time
Today, 16:56
Joined
Feb 19, 2013
Messages
12,766
But I think I've done that when I select the webcontrol with my mouse...

when the gotfocus event is triggered the control will have focus, so a hwnd will exist. The control will have focus after a click, doubleclick, keydown or mousedown event. Or vba code to setfocus. Mousemove is insufficient on its own, which is why I said you need to setfocus with the mousemove event.

Not at all clear to me what you are trying to achieve other than detecting when a user clicks on predefined area of pdf when displayed in a web control. It would appear the whole pdf cannot be displayed, hence the need for feedback from the scrollbar to determine how far the pdf has been scrolled - so you can calculate the offset to the predefined area.

You still need to determine the coordinates for the predefined area.

Once you have done that, use the mousedown or up event to check whether the cursor is within the (offset) area and do whatever it is required. You cannot use the click, dblclick or key events because they don't return the mouse X,Y coordinates. To use those events you need additional code to get the cursor position - see the getcursorpos api. It returns a value in pixels, which you need to a) convert to twips and b) then offset for the access>form>control position. For the latter, check out the ScreenToClient api
 

CedarTree

Registered User.
Local time
Today, 11:56
Joined
Mar 2, 2018
Messages
248
Thank for your continued help and patience.
So here's what I have...
1) I have a form with the embedded webcontrol named "PDFViewer" - and I load a test PDF with many pages in it - the main form itself has no scroll bar
2) I've put in your suggested functions for determining the scrollbar and the position
3) I've created a Timer event that prints out the position every 5 seconds so I can debug

Code:
    Debug.Print fIsScrollBar(Me.Form)
    Debug.Print fGetScrollBarPos(Me.Form)
4) I've clicked on the PDF explicitly with my mouse AND the Timer event even has me.PDFViewer.setfocus - but the position isn't updating (I keep getting zero)... I still think it's look at the (non-existent) scrollbar of the form itself

Help please?!?

Just for clarity, here are the other functions I'm using...

Code:
Function fGetScrollBarPos(frm As Form) As Long

    ' Return ScrollBar Thumb position
    ' for the Vertical Scrollbar attached to the
    ' Form passed to this Function.

    Dim hWndSB As Long
    Dim lngret As Long
    Dim sInfoH As SCROLLINFO
    Dim sInfoV As SCROLLINFO
    
    'Dim sInfo As SCROLLINFO
    
    ' Init SCROLLINFO structure
    sInfoV.fMask = SIF_ALL
    sInfoV.cbSize = Len(sInfoV)
    sInfoV.nPos = 0
    sInfoV.nTrackPos = 0
    
    ' Call function to get handle to
    ' ScrollBar control if it is visible
    hWndSB = fIsScrollBar(frm) '*****************
    'Debug.Print hWndSB
    If hWndSB = -1 Then
        fGetScrollBarPos = False '*******************
        Exit Function
    End If
    
    ' Get the window's ScrollBar position
    lngret = apiGetScrollInfo(hWndSB, SB_CTL, sInfoV)
    'Debug.Print "nPos:" & sInfoV.nPos & "  nPage:" & sInfoV.nPage & "  nMax:" & sInfoV.nMax; sInfoV.nTrackPos; sInfoV.fMask; sInfoV.nMin; sInfoV.cbSize
    
    'MsgBox "getscrollinfo returned " & sInfo.nPos & " , " & sInfo.nTrackPos
    fGetScrollBarPos = sInfoV.nPos + 1

End Function
Code:
Function fIsScrollBar(frm As Form) As Long
' Get ScrollBar's hWnd
Dim hWnd_VSB As Long
Dim hwnd As Long
   
hwnd = frm.hwnd
    
    ' Let's get first Child Window of the FORM
    hWnd_VSB = apiGetWindow(hwnd, GW_CHILD)
                
    ' Let's walk through every sibling window of the Form
    Do
        'Thanks to Terry Kreft for explaining
        'why the apiGetParent acll is not required.
        'Terry is in a Class by himself! :-)
        'If apiGetParent(hWnd_VSB) <> hWnd Then Exit Do
        'Debug.Print fGetClassName(hWnd_VSB)
         
        If fGetClassName(hWnd_VSB) = "NUIscrollBar" Then 'was "Scrollbar"
            If apiGetWindowLong(hWnd_VSB, GWL_STYLE) And SBS_VERT Then
                fIsScrollBar = hWnd_VSB
                Exit Function
            End If
        End If
    
    ' Let's get the NEXT SIBLING Window
    hWnd_VSB = apiGetWindow(hWnd_VSB, GW_HWNDNEXT)
    
    ' Let's Start the process from the Top again
    ' Really just an error check
    Loop While hWnd_VSB <> 0
    
    ' SORRY - NO Vertical ScrollBar control
    ' is currently visible for this Form
    fIsScrollBar = -1

End Function
Code:
Function fGetClassName(hwnd As Long)

    ' From Dev Ashish's Site
    ' The Access Web
    ' http://www.mvps.org/access/

    Dim strBuffer As String
    Dim lngLen As Long
    
    Const MAX_LEN = 255
    strBuffer = Space$(MAX_LEN)
    lngLen = apiGetClassName(hwnd, strBuffer, MAX_LEN)
    If lngLen > 0 Then fGetClassName = Left$(strBuffer, lngLen)

End Function
 

CJ_London

Super Moderator
Staff member
Local time
Today, 16:56
Joined
Feb 19, 2013
Messages
12,766
I don't have a lot of time as I am focused on paying clients today. Let me see if I can put some code together for you, but will be later today
 

CedarTree

Registered User.
Local time
Today, 11:56
Joined
Mar 2, 2018
Messages
248
By the way, just to be super clear, I'm using the "standard" Access Web Browser, not the Microsoft Web Browser (ActiveX). Not sure if that makes a difference.
 

CJ_London

Super Moderator
Staff member
Local time
Today, 16:56
Joined
Feb 19, 2013
Messages
12,766
it would appear the scrollbars for a webcontrol are actually in an internet explorer window, so can't get past the 'shell embedding' class for web controls. Would need to look a lot deeper and don't have the time.

Suggest try an alternative approach. Put your web control into a form of its own and disable scrollbars for the web control and enable them for the form. Then put the form on your mainform as a subform and use the scrollbars there instead.
 

Users who are viewing this thread

Top Bottom