How to get printer page width, height & margins in pixels with APIs?

Theres a bug in the programming language I use and I can not get the printer page width, height and margins in pixels without showing the page setup dialog.

I just want to get these values for the default printer.

Please see the image below, you can see my problem.

The first row shows the values I get without showing the dialog, the second row shows good values after the page setup dialog.

printsetup.jpg
mindwarpltdAsked:
Who is Participating?

[Webinar] Streamline your web hosting managementRegister Today

x
 
jkrConnect With a Mentor Commented:
Once you have a printer DC, you can get these parameters via 'GetDeviceCaps()' (http://msdn.microsoft.com/en-us/library/dd144877(VS.85).aspx), e.g.
// Width, in pixels, of the screen; or for printers, the width, in 
// pixels, of the printable area of the page.
int nHorzPixels = GetDeviceCaps(hPrinter,HORZRES);
 
// Height, in pixels, of the screen; or for printers, the heigth, in 
// pixels, of the printable area of the page.
int nVertPixels = GetDeviceCaps(hPrinter,VERTRES);
 
// For printing devices: the distance from the left edge of the 
// physical page to the left edge of the printable area, in device 
// units.
int nPhysOffsX = GetDeviceCaps(hPrinter,PHYSICALOFFSETX);
 
// For printing devices: the distance from the top edge of the 
// physical page to the top edge of the printable area, in device 
// units.
int nPhysOffsY = GetDeviceCaps(hPrinter,PHYSICALOFFSETY);

Open in new window

0
 
mindwarpltdAuthor Commented:
Can you provide me with the constants for HORZRES, VERTRES, PHYSICALOFFSETX, PHYSICALOFFSETY
0
 
mindwarpltdAuthor Commented:
Heres my code, below, I googled the constants.

hoz=1024
vert=768
OffX=0
OffY=0

This seems more like my screen resolution than my printer details, as shown in the image above
  Declare Function GetDeviceCaps Lib "Gdi32" ( hdc as Integer, index as Integer ) as Integer
  Declare Function GetDC Lib "User32" ( hwnd as Integer ) as Integer
  Declare Sub ReleaseDC Lib "User32" ( hwnd as Integer, dc as Integer )
  
  dim hdc as Integer = GetDC( 0 )
  
  Const HORZRES = 8
  Const VERTRES = 10
  Const PHYSICALOFFSETX = 112
  Const PHYSICALOFFSETY = 113
  
  dim intHorzPixels as integer
  intHorzPixels = GetDeviceCaps(hdc,HORZRES)
  
  dim intVertPixels as integer
  intVertPixels = GetDeviceCaps(hdc,VERTRES)
  
  dim intPhysOffsX as integer
  intPhysOffsX = GetDeviceCaps(hdc,PHYSICALOFFSETX)
 
  dim intPhysOffsY as integer
  intPhysOffsY = GetDeviceCaps(hdc,PHYSICALOFFSETY)
  
  ReleaseDC( 0, hdc )
  
  MsgBox "hoz=" + cstr(intHorzPixels) + EndOfLine + _
   "vert=" + cstr(intVertPixels) + EndOfLine + _
  "OffX=" + cstr(intPhysOffsX) + EndOfLine + _
   "OffY=" + cstr(intPhysOffsY)
  

Open in new window

0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
jkrCommented:
Ooops, sorry about the conatants. And yes, that's your screen resolution, since that is what

  dim hdc as Integer = GetDC( 0 )

doeas obtain. You need to use 'CreateDC()' here providing the name of the printer you want to use, e.g.

   // Get a device context for the printer.
   HDC hdcPrint = CreateDC(NULL, TEXT("\\\\printserver\\print1"), NULL, NULL);
0
 
mindwarpltdAuthor Commented:
I don't know that the default printer is though.
0
 
jkrCommented:
That you can get using 'PrintDlg()', see http://msdn.microsoft.com/en-us/vbasic/ms646964(VS.85).aspx ("Print Dialog Box")
0
 
mindwarpltdAuthor Commented:
No, thats the whole point, I don't want to show the dialog.
Thats what my current issue is, having to show the dialog.
0
 
jkrCommented:
Ah, OK - that can also be done, yet is a bit more 'archaic', as described in http://msdn.microsoft.com/en-us/library/dd183521(VS.85).aspx ("Creating a Printer Device Context"): "To use the default printer, retrieve and parse the appropriate string from the Win.ini file. This string is retrieved by calling the GetProfileString function and specifying the appropriate section and entry names. In the case of the default printer, this data is stored in the [windows] section and identified by the entry named device."
0
 
jkrCommented:
BTW, while checking MSDN for that, I found that there seems to be a 'Printer' object in VB that you can use like 'Printer.DeviceName'
0
 
mindwarpltdAuthor Commented:
Ahh yes, I already have that function.

OK, one slight issue

Looking at the image I pasted above.

I get the values shown on row 3.
Which isn't with the 25mm margins I have set.

It seems to be getting values with 0 mm margins, which aren't set with the default printer
0
 
mindwarpltdAuthor Commented:
I'm not using VB, I'm using Real Basic
0
 
jkrCommented:
>>I'm not using VB, I'm using Real Basic

Sorry, but don't expect someone who only did C/C++ the last 17 years to be able to tell the difference from a few lines of code ;o)

BTW, a '0 margin' is unrealisitc with every printer, there will always be some milimeters left for that.
0
 
mindwarpltdAuthor Commented:
>BTW, a '0 margin' is unrealisitc with every printer, there will always be some milimeters left for that.

Absolutely.
These aren't the values I want...

hoz=2892
vert=4125
OffX=42
OffY=42

These are the values I want...

hoz=2268
vert=3501
OffX=354
OffY=354

Are there some different constants I can use?
0
 
jkrCommented:
Stupid question, but are you sure you are checking the right printer?
0
 
mindwarpltdAuthor Commented:
Yes.

These values are with 0mm margin, not my default settings, but the correct printer.
hoz=2892
vert=4125
OffX=42
OffY=42

These are the correct settings for the default printer with the default 25mm
hoz=2268
vert=3501
OffX=354
OffY=354
0
 
mindwarpltdAuthor Commented:
Second values are with the correct printer too
0
 
mindwarpltdAuthor Commented:
Heres my code...
  Declare Function GetDeviceCaps Lib "Gdi32" ( hdc as Integer, index as Integer ) as Integer
  Declare Function GetDC Lib "User32" ( hwnd as Integer ) as Integer
  Declare Sub ReleaseDC Lib "User32" ( hwnd as Integer, dc as Integer )
  
  Declare Function CreateDC Lib "gdi32" Alias "CreateDCA" ( lpDriverName As CString, lpDeviceName As CString, lpOutput As CString, lpInitData As cstring ) As Integer
  
  dim defP as string = GetDefaultPrinter
  msgbox defP
  
  dim hdc as integer = CreateDC("",defP,"","")
   
  Const HORZRES = 8
  Const VERTRES = 10
  Const PHYSICALOFFSETX = 112
  Const PHYSICALOFFSETY = 113
  
  dim intHorzPixels as integer
  intHorzPixels = GetDeviceCaps(hdc,HORZRES)
  
  dim intVertPixels as integer
  intVertPixels = GetDeviceCaps(hdc,VERTRES)
  
  dim intPhysOffsX as integer
  intPhysOffsX = GetDeviceCaps(hdc,PHYSICALOFFSETX)
  
  dim intPhysOffsY as integer
  intPhysOffsY = GetDeviceCaps(hdc,PHYSICALOFFSETY)
  
  ReleaseDC( 0, hdc )
  
  MsgBox "hoz=" + cstr(intHorzPixels) + EndOfLine + _
   "vert=" + cstr(intVertPixels) + EndOfLine + _
  "OffX=" + cstr(intPhysOffsX) + EndOfLine + _
   "OffY=" + cstr(intPhysOffsY)
  

Open in new window

0
 
mindwarpltdAuthor Commented:
If these are the right values, how can I get the other ones with the 25mm margin ?

I just need to match what Real Basic is saying, maybe its wrong, but I just need the sizes its going to use to print with.
0
 
mindwarpltdAuthor Commented:
Help ?
0
 
mindwarpltdAuthor Commented:
Perhaps I can cheat.

If the default margins are always 25mm ?

at a resolution of 360 the pixels for 25mm are 354, the resolution can also be gained from that api too. I can factor that based on resolution.

What do you thing?
0
 
mindwarpltdAuthor Commented:
This solution is perfect, my problem was that the page setup dialog and printer dialog gave different values.
0
All Courses

From novice to tech pro — start learning today.