0

I am working on a project where I have to return number of millimeters or centimeters or whatever traversed by a mouse.

Now, whoops, this is a bit tricky as every screen is different.

I found a nice function: wx.DC.GetSizeMM() that should have solved this problem for me.

My hopes went up, but it gives me some extremely dubious results.

On my PC under Windows:

>>> app = wx.App()
>>> dc = wx.ScreenDC()
>>> dc.GetSize() # Get resolution in pixels:
wx.Size(1680, 1050)
>>> dc.GetSizeMM() # Now this is completely off as these should be mm we're looking at:
wx.Size(432, 270)
>>>

My screen is at least 1 cm wider than dc.GetSizeMM() thinks it is.

For a: wx.MemoryDC(wx.EmptyBitmap(100, 100)).GetSizeMM() I get wx.Size(25, 25). I mean, come on, completely ridiculous!

Edit: OK, maybe not so completely. :D

It is obvious that aspect ratio is fine, but what factor is used to convert?

What am I missing? Why doesn't it work?

Dalen
  • 4,128
  • 1
  • 17
  • 35
  • "I get wx.Size(25, 25)" if you use `dc.GetPPI()` I'd hazard a guess that it will return 96 pixels per inch, so 25,25 (1 inch by 1 inch) is about right. Although clearly for the entire screen, there is some sort of stretching going on that `dc` isn't picking up on. – Rolf of Saxony Feb 10 '17 at 16:39
  • using `dc.SetUserScale(0.88,0.88)` gives me figures that are really quite close to the actual size of my screen. Although I have no idea why this should be. – Rolf of Saxony Feb 10 '17 at 16:52
  • You just beat me to some short comment and deletion of the question, because I realized that Windows are messing with DPI scaling and I don't want people confused. I found something about it here: http://stackoverflow.com/questions/3129322/how-do-i-get-monitor-resolution-in-python So, let say that wx.DC.GetSizeMM() i.e. wx.GetDisplaySizeMM() is essentially right and wrong at the same time. Depending on what Windows is doing. Now I probably confused everyone even further. :D – Dalen Feb 10 '17 at 18:50
  • The trouble is that ctypes.windll.user32.SetProcessDPIAware() isn't present on XP, so I cannot check what would happen if I make my process DPI aware. I expect "kind of stretching", as you put it, has something to do with the scaling. Thing is, setting user scale doesn't make any difference on my machine. How did you come by scaling factor of 0.88 anyway? Empirically? You are correct, my dc.GetPPI() is 96x96 DPI. You are also correct, 432 mm is close to my screen width, but isn't exact. My screen is a bit bigger. – Dalen Feb 10 '17 at 18:51
  • I think that I'll just save myself a trouble and make users calibrate before doing anything significant. Otherwise I'll end up tangled in scaling and rescaling (resizing and zooming...) and correctness of the returned values, and multiscreen environment problems and then I'll probably make some inexcusable mistake along the way thus making my product fit for trash. Oh, yeah, did I mention that everything should be cross-platform at the end? Slight nightmare. :D – Dalen Feb 10 '17 at 18:53
  • I played a little with values and I need recheck. Can you verify how well this fits your screen size please: PPI = float(dc.GetPPI()[0]); w, h = dc.GetSize(); wmm = (w/PPI)*25.4; hmm = (h/PPI)*25.4 – Dalen Feb 10 '17 at 19:28
  • Bit pointless, as that will give the same result as `dc.GetSizeMM()`. The conversion factor, empirically, would be 28.86 and not what we know it to actually be 25.4. Note that `wx.GetDisplaySizeMM()` provides the same information, so no luck there either. – Rolf of Saxony Feb 11 '17 at 11:25
  • Not pointles as by using the formula I get 444.5 mm by 277.8 mm instead of 432x270 mm returned by dc.GetSizeMM(). Width is much closer to the real width of the monitor. Your values didn't vary from returned ones? – Dalen Feb 11 '17 at 14:50
  • On my Linux box, the figures comeback pretty much the same, give or take some decimals :( – Rolf of Saxony Feb 11 '17 at 16:41

0 Answers0