ETO Userform Problems with Touch Screen Laptop

Hi,

I have a Dell Precision 5540 laptop which has a touch screen and have scaling issues when viewing on the laptop versus viewing on an external monitor. My forms are built in Rhino 6 using ETO Forms and there are two problems I cannot overcome:

The fonts are too large for the text boxes and get cut off:
image

The forms display fine on an external monitor but the larger forms get the bottom cut off. I have enabled scroll bars and that allows me to get to the bottom of the form by scrolling, but it is still annoying that the bottom of the userform is under the task bar:

Any help would be greatly appreciated.

Eric

Hi @eric.bunn,

Do the two monitors use different DPI settings? Does the issue follow which monitor Rhino is started on?

– Dale

I only have the issue when I’m using the laptop by itself with no external monitors. It’s a touch screen laptop. The problem doesn’t exist on my monitors, only the laptop. I have my monitor set for 100% scaling and the laptop is set for 125%. If I set the laptop for 100% I do not have the problem, but my old eyes can’t read the text and icons very well at 100% on the laptop. 125% is the recommended setting for the laptop in display settings. If I change the scaling on the monitor to 125% the form scales properly to the new setting. It is the laptop that is causing the issue.

Eric

Dale,

Is there a way to get the window size of the open Rhino Window? Rhino always sizes appropriately when maximized. If I could get the height of the Rhino Window I could set my form to a matching height and that would satisfy my needs.

Eric

Hi @eric.bunn,

How about this?

import Rhino
import ctypes
from ctypes import wintypes

hwnd = Rhino.RhinoApp.MainWindowHandle()
rect = wintypes.RECT()
ctypes.windll.user32.GetWindowRect(hwnd, ctypes.byref(rect))

print 'Left/Top: ' + str(rect.left) + ',' + str(rect.top)
print 'Right/Bottom: ' + str(rect.right) + ',' + str(rect.bottom)
print 'Width/Height: ' + str(rect.right - rect.left) + ',' + str(rect.bottom - rect.top)

– Dale

1 Like

Dale,

This is perfect. Thank you much. I just spent two hours trying to do Google searches to put this exact code together. Again, many thanks.

Eric

Dale,

I’ve included my final code below that worked perfectly in tiling my userform to the left of Rhino and it opens the same way on my External Monitor and High Res Laptop. I threw in some other macros that work together. GetWorkArea will get the working area of the main screen and also return the taskbar size, PPP returns the pixel density of the main screen, GetRect is your function for getting the size of the Rhino Window, and SetWindowPos resizes and relocates the Rhino Window so the userform and the Rhino Window tile side by side. Thought maybe someone else could use the code so I shared it all.

Many thanks again.

Eric

def GetWorkArea(self):
    """Get working area for monitor.  Returns Top,Bottom,Left,Right"""
    import ctypes
    SPI_GETWORKAREA=48
    class RECT(ctypes.Structure):
       _fields_ = [('left',ctypes.c_ulong),
                   ('top',ctypes.c_ulong),
                   ('right',ctypes.c_ulong),
                   ('bottom',ctypes.c_ulong)]
    x = ctypes.windll.user32
    r = RECT()
    x.SystemParametersInfoA(SPI_GETWORKAREA,0,ctypes.byref(r),0)
    retvals = [r.top,r.bottom,r.left,r.right]
    
    #Calc Height of Userform and Set##############################
    size = rs.ScreenSize()#X,Y
    work = retvals#GetWorkArea()#Top,Bottom,Right,Left
    tBar = size[1]-abs(work[0] - work[1])
    UF_H = size[1] - (tBar*2)
    self.ClientSize = drawing.Size(UF_W,UF_H) #sets the (Width, Height)(Optional only)
    #Calc Height of Userform and Set##############################
    
    return work,tBar
@staticmethod
def PPP():
    """Gets the Screen Resolution and Pixel Density"""
    from ctypes import *
    CreateDC = windll.gdi32.CreateDCA
    GetDeviceCaps = windll.gdi32.GetDeviceCaps
    
    NULL = c_int(0)
    HORZRES = c_int(8)
    VERTRES = c_int(10)
    LOGPIXELSX = 88
    POINTS_PER_INCH = 72
    
    screen = CreateDC(c_char_p("DISPLAY"),NULL,NULL,NULL)
    x = GetDeviceCaps(screen,HORZRES)
    y = GetDeviceCaps(screen,VERTRES)
    lDotsPerInch = GetDeviceCaps(screen,LOGPIXELSX)
    PointsPerPixel = float(POINTS_PER_INCH) / float(lDotsPerInch)
#        
#        x = x * PointsPerPixel
#        y = y * PointsPerPixel
    
    return lDotsPerInch,x,y
@staticmethod
def GetRect():
    """Gets the size of the Rhino Parent Window"""
    import ctypes
    from ctypes import wintypes
    
    hwnd = Rhino.RhinoApp.MainWindowHandle()
    rect = wintypes.RECT()
    ctypes.windll.user32.GetWindowRect(hwnd, ctypes.byref(rect))
    width = rect.right - rect.left
    height = rect.bottom - rect.top
    return rect.top,rect.bottom,rect.left,rect.right,width,height
@staticmethod
def SetWindowPos(x=0,y=0,w=0,h=0):
    """Sets Window Position for Left and Top and Size of Window (width,height)"""
    import rhinoscriptsyntax as rs
    from ctypes import *
    HWND_TOPMOST = c_int(-1)
    HWND_NOTOPMOST = c_int(-2)
    SWP_NOMOVE = 0x02
    SWP_NOSIZE = 0x01
    TOGGLE_HIDEWINDOW = 0x80
    TOGGLE_UNHIDEWINDOW = 0x40
    SetWindowPos = windll.user32.SetWindowPos
    SetWindowPos(rs.WindowHandle(),HWND_TOPMOST, x, y, w, h, TOGGLE_UNHIDEWINDOW)