Standard Python Modules

Is there a way to access standard python modules from the Rhino Python Editor?

Specifically win32api

Eric

I believe that’s only a standard module in CPython. You could probably invoke it in IronPython (i.e. the .NET Python flavour implemented in Rhino) using ctypes, but since you’re already in .NET country you might as well import System, which will likely cover your requirements, depending on what they are.

I have a vba Windows API routine that I’ve used to get Pixel Density of the screen so I can size a window properly depending on the computer. I need to extract that same information in python. I’m opening Excel to read/write to and I have code that gets me the screen size but I need the pixel density as well to size it properly. I can post the windows api code if helpful. I not that familiar with ctypes although another user on the forum passed on some code to me to get the screen size and that works using ctypes.

Option Explicit

'Functions to get DPI
Private Declare PtrSafe Function GetDC Lib “user32” (ByVal hwnd As LongPtr) As LongPtr
Private Declare PtrSafe Function GetDeviceCaps Lib “gdi32” (ByVal hDC As LongPtr, ByVal nIndex As LongPtr) As LongPtr
Private Declare PtrSafe Function ReleaseDC Lib “user32” (ByVal hwnd As LongPtr, ByVal hDC As LongPtr) As LongPtr
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal Milliseconds As LongPtr)

Private Const LOGPIXELSX = 88 'Pixels/inch in X
Private Const POINTS_PER_INCH As LongPtr = 72 'A point is defined as 1/72 inches

'Return DPI
Private Function PointsPerPixel() As Double
Dim hDC As LongPtr
Dim lDotsPerInch As LongPtr

hDC = GetDC(0)
lDotsPerInch = GetDeviceCaps(hDC, LOGPIXELSX)
PointsPerPixel = POINTS_PER_INCH / lDotsPerInch
ReleaseDC 0, hDC

End Function

With a little searching and editing I was able to build this code to get what I want. Thanks for the help.

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 = POINTS_PER_INCH / lDotsPerInch

print(x,y,PointsPerPixel)

Eric

Nice, well done. Just for completeness, here’s how you could implement the .NET Screen namespace in RhinoPython to get the screen resolution etc.:

from System.Windows.Forms import Screen

psw = Screen.PrimaryScreen.Bounds.Width
psh = Screen.PrimaryScreen.Bounds.Height

That’s nice and simple. Thank you. One other problem that I have to overcome is I need to multiply those numbers times my screens PPI(96) and then divide by 72 to convert the numbers into sizes to set my .length and .width values. I do this so the program I am opening fills the screen properly. If I take the number for the screen length, for example, and multiply it times 96 (ppi) and then divide by 72 I get the program to fill the screen perfectly in length. The magic number is 96. I need to pull this number as well. This problem is unique to the high res touchscreen monitor which I discovered after upgrading to my Dell. Everything worked fine before that and I could just use the standard screen resolution to size my windows. I can’t explain it unfortunately but it works if I run the numbers through that formula. (Screen Length in pixels * PPI / 72)

GetDpiForMonitor