Moving form to 3rd monitor math on twips not adding up right? (1 Viewer)

SuperShin

Member
Local time
Today, 02:22
Joined
Feb 16, 2020
Messages
33
Hi I have some code I use to move a form to a third monitor (if one exists) and everything works correctly except the math calculations based on screen size.

intMoveX = 86000

Code:
If GetMonitorId > 2 Then 'move to monitor 3 and maximize! (getmonitorid also populates the monitorid array public var of all monitor strings
     
            FirstMonitorLeft = ReturnLeftForMonitor(MonitorID(1))
            SecondMonitorLeft = ReturnLeftForMonitor(MonitorID(2))
            ThirdMonitorLeft = ReturnLeftForMonitor(MonitorID(3))
        
            ReDim aryDisplays(2) '3 monitors
         
            aryDisplays(0) = FirstMonitorLeft
            aryDisplays(1) = SecondMonitorLeft
            aryDisplays(2) = ThirdMonitorLeft
     
         SortArray aryDisplays ' sort array sizes ascending no matter how windows has these monitors identity
     
         intMoveX = aryDisplays(2)  'use third monitor

         intMoveX = intMoveX * 15 '15 twips per pixel I was told

         intMoveY = 100
              
         Forms![frmScoreboard-Audience2].Form.SetFocus
         Forms![frmScoreboard-Audience2].Form.Move intMoveX, intMoveY
    
         DoCmd.Maximize


So the code that moves to the 2nd monitor works similarly but the 3rd has a math issue of some sort

if I have 3 monitors and the values of the lefts are all 3 are HD 1920*1080:

Code:
'return values for simplicity sake
FirstMonitorLeft =0
SecondMonitorLeft = 2880
ThirdMonitorLeft = 5760

intMoveX = aryDisplays(2)  'use third monitor 'ThirdMonitorLeft
intMoveX = intMoveX * 15 ' this is 86000

   Forms![frmScoreboard-Audience2].Form.Move intMoveX, intMoveY  'FAILS (apparently 86000 is off my screen so it goes back to screen 1)

So I started just hard coding values intMoveX to 70000 / 60000 / 50000 and they all work to move the form to the 3rd monitor but obviously i can't just fudge it like that at run time, users have all kinds of different resolutions, can anyone shed light on why this could be happening or a strategry to deal with it? Im running up against HD 4K etc and i have no idea what the resolution will be.

What am I missing here? for a quick hack that TOTALLY SUCKS i changed the twip calc to intMoveX = intMoveX * 10 but that only works in specific cases like this one, I need to udnerstand why the math doens't work here. So the final wrinkle comes in when i have laptop display + usb display + usb display, that works with this intMoveX * 10 hack. but if i close the lid on my laptop and use HDMI out + usb display + usb display only the intMoveX * 15 works. Tried multiple laptops same behavior. AT this point im about to add a global variable called 3rdMontiorVariance and let the user set it, but how stupid is that, there must be a better way.

Thanks!

David
 
Last edited:

sonic8

AWF VIP
Local time
Today, 08:22
Joined
Oct 27, 2015
Messages
998
intMoveX = intMoveX * 15 ' this is 86000
What's this line supposed to do?

First, if intMoveX is actually of type Integer, this will result in an overflow error as 86000 is beyond the supported value range of an Integer.

Second, are you trying to convert pixels to twips? Then you should not use the hardcoded factor 15. This hardcoded value is the most common but it is by no means the correct value for all circumstances. It depends on the actual display capabilities and settings. You should call GetDeviceCaps for LOGPIXELSX to determine the correct conversion factor.
 

SuperShin

Member
Local time
Today, 02:22
Joined
Feb 16, 2020
Messages
33
yes im trying to convert to TWIPS

What is the best way to do this im sure this is my issue. ill search some googles for GetDeviceCaps VBA implimentations

Honestly though everything I've read uses 15 as the factor to pixels, I'm not sure why my calc should be off so egregiously. The second monitor goes exactly where it should but not the 3rd.

(Also intMoveX is a long or I would have been getting RTEs)

David
 
Last edited:

SuperShin

Member
Local time
Today, 02:22
Joined
Feb 16, 2020
Messages
33
This gives me twips / pixel on the main display
Code:
    lDeviceHandle = GetDC(0)
but im still looking at how to determine the other displays and which is which.


FROM https://stackoverflow.com/questions...d-the-width-of-the-parent-window-in-ms-access

Code:
Type Rect
    x1 As Long
    y1 As Long
    x2 As Long
    y2 As Long
End Type

Declare Function GetClientRect Lib "user32" (ByVal hwnd As Long, lpRect As Rect) As Long

Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long

Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hdc As Long) As Long

Declare Function GetDeviceCaps Lib "gdi32" (ByVal hdc As Long, ByVal nIndex As Long) As Long

Const LOGPIXELSX = 88
Const LOGPIXELSY = 90
Const DIRECTION_VERTICAL = 1
Const DIRECTION_HORIZONTAL = 0

Public Function GetMainWindowSize()

    Dim MDIRect As Rect
    Dim lWidthPixels As Long
    Dim lWidthTwips As Long

    ' Get the screen coordinates and window size of the MDIClient area'
    GetClientRect Application.hWndAccessApp, MDIRect

    lWidthPixels = MDIRect.x2 - MDIRect.x1
    lWidthTwips = PixelsToTwips(lWidthPixels, DIRECTION_HORIZONTAL)

    MsgBox "Width (Pixels) = " & lWidthPixels & "  Width (Twips) = " & lWidthTwips

End Function


Function PixelsToTwips(lPixels As Long, lDirection As Long) As Long

    Dim lDeviceHandle As Long
    Dim lPixelsPerInch As Long

    lDeviceHandle = GetDC(0)

    If lDirection = DIRECTION_HORIZONTAL Then
        lPixelsPerInch = GetDeviceCaps(lDeviceHandle, LOGPIXELSX)
    Else

        lPixelsPerInch = GetDeviceCaps(lDeviceHandle, LOGPIXELSY)
    End If

    lDeviceHandle = ReleaseDC(0, lDeviceHandle)

    PixelsToTwips = lPixels * 1440 / lPixelsPerInch

End Function
 

Users who are viewing this thread

Top Bottom