Recent

Author Topic: Getting True Size on Screen  (Read 1430 times)

Badger

  • Full Member
  • ***
  • Posts: 153
Getting True Size on Screen
« on: June 22, 2024, 09:32:19 am »
Not sure if this is the correct forum for this but here goes.
I want to have a panel exactly represent an A4 page on screen.
My approach was:-
   x:=ScreenInfo.PixelsPerInchX;
   Panel1.Width:=Round(21.0*x/2.54 );

The panel comes out too small.  x returned 96 and I had to force X:=101 to get the correct screen size.
This would be OK for my machine but I would like to make it portable.
What am I doing wrong.
Badger
(A bad tempered, grumpy animal that sleeps most of the winter!)

If at first you don't succeed - you're running about average!

I'm using Windows 10 Lazarus v2.2.4  FPC 3.2.2   Win 32/64

MarkMLl

  • Hero Member
  • *****
  • Posts: 8015
Re: Getting True Size on Screen
« Reply #1 on: June 22, 2024, 11:02:12 am »
I'm pretty sure that this has been asked before, and suspect that discussion petered out without a definite resolution (as it were).

I'd suggest using whatever facility your OS makes available to read the parameters (size etc. via DDC) that the screen claims to implement, and then seeing how those compare with the physical dimensions of the screen.

It's not unknown for the electronics in a screen to be fairly "generic", and not to describe the actual physical display panel that the manufacturer has used accurately.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

VisualLab

  • Hero Member
  • *****
  • Posts: 569
Re: Getting True Size on Screen
« Reply #2 on: June 22, 2024, 04:24:43 pm »
I suspect you intend to do something like:
  • print preview or
  • an editing area that is an on-screen mock-up of a piece of paper.

Or both (different editors are usually designed this way). As far as I know, this can be done in two ways:
  • reading the pixel density of the device (screen, printer) per unit of length (e.g. pixel/inch, pixel/mm) and then calculating the distance and length according to the coefficient obtained in this way - this is what you are trying to do,
  • changing the mapping mode (length units, etc.) using the operating system API.

I used to do this in Delphi to support print preview and printing on paper. For this purpose, I used WinAPI functions to draw. First of all, the SetMapMode function, used to change the mapping mode. Moreover, you can use the following functions: GetWindowExtEx, SetWindowExtEx, GetViewPortExtEx, SetViewPortExtEx, GetViewPortOrgEx, SetViewPortOrgEx.

The starting point is to change the mapping mode. You can then draw using inches or millimeters, or more precisely: 1/100, 1/1000 of an inch or 1/10 or 1/100 mm. There are more of these modes than the ones I mentioned, but these 4 refer to physical units. Their use simplifies the handling of graphics, which are to be both displayed on the monitor (editing, print preview) and later printed on a physical device (printer, plotter).

What is usually done is to first remember the current mapping mode. The SetMapMode function returns the current mapping mode, which can be stored in a variable. You then turn on the desired mapping mode just before drawing with using of physical units. You can then use the remaining functions that I mentioned earlier (Get.../Set...). Finally, the previous mapping mode is restored using the SetMapMode function, giving it the previously remembered mapping mode as an argument.

The given WinAPI functions need a handle. This is the canvas handle that is supposed to support drawing. For example, TPaintBox, TCustomControl and TBitmap have a canvas. All you need to do is pass the handle of this canvas to the WinAPI function.

I used a book that described the use of screen graphics and printing in Delphi:

"Delphi 4 Developer's Guide" by Xavier Pacheco, Steve Teixeira
« Last Edit: June 22, 2024, 04:47:16 pm by VisualLab »

Thaddy

  • Hero Member
  • *****
  • Posts: 16158
  • Censorship about opinions does not belong here.
Re: Getting True Size on Screen
« Reply #3 on: June 25, 2024, 11:42:01 am »
Indeed, that is also one of the oldest and most beautiful API's in the Windows set!
And that book is written by two former senior Borland engineers!
« Last Edit: June 25, 2024, 11:45:53 am by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

VisualLab

  • Hero Member
  • *****
  • Posts: 569
Re: Getting True Size on Screen
« Reply #4 on: June 25, 2024, 12:56:11 pm »
Indeed, that is also one of the oldest and most beautiful API's in the Windows set!
And that book is written by two former senior Borland engineers!

There was also a version of their books for Delphi 6. I also have this version ("Borland Delphi 6 Developer's Guide"). There are some differences between versions 4 and 6 (especially regarding web applications). In any case, it is still useful when it comes to basic issues at the junction of Object Pascal and WinAPI.

Thaddy

  • Hero Member
  • *****
  • Posts: 16158
  • Censorship about opinions does not belong here.
Re: Getting True Size on Screen
« Reply #5 on: June 26, 2024, 11:08:24 am »
And the api you mentioned is the answer to real world dimensions, it is extremely precise.
Stems from a request, and partly written by, AutoCAD engineers.  It already worked on 16 bit Windows.
« Last Edit: June 26, 2024, 12:13:17 pm by Thaddy »
If I smell bad code it usually is bad code and that includes my own code.

 

TinyPortal © 2005-2018