Solved

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

Posted on 2009-07-03
21
435 Views
Last Modified: 2013-12-04
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
0
Comment
Question by:mindwarpltd
  • 14
  • 7
21 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 500 total points
ID: 24776854
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
 

Author Comment

by:mindwarpltd
ID: 24776865
Can you provide me with the constants for HORZRES, VERTRES, PHYSICALOFFSETX, PHYSICALOFFSETY
0
 

Author Comment

by:mindwarpltd
ID: 24776897
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
 
LVL 86

Expert Comment

by:jkr
ID: 24776943
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
 

Author Comment

by:mindwarpltd
ID: 24776963
I don't know that the default printer is though.
0
 
LVL 86

Expert Comment

by:jkr
ID: 24776980
That you can get using 'PrintDlg()', see http://msdn.microsoft.com/en-us/vbasic/ms646964(VS.85).aspx ("Print Dialog Box")
0
 

Author Comment

by:mindwarpltd
ID: 24776989
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
 
LVL 86

Expert Comment

by:jkr
ID: 24777013
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
 
LVL 86

Expert Comment

by:jkr
ID: 24777018
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
 

Author Comment

by:mindwarpltd
ID: 24777024
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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:mindwarpltd
ID: 24777044
I'm not using VB, I'm using Real Basic
0
 
LVL 86

Expert Comment

by:jkr
ID: 24777062
>>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
 

Author Comment

by:mindwarpltd
ID: 24777080
>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
 
LVL 86

Expert Comment

by:jkr
ID: 24777099
Stupid question, but are you sure you are checking the right printer?
0
 

Author Comment

by:mindwarpltd
ID: 24777126
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
 

Author Comment

by:mindwarpltd
ID: 24777129
Second values are with the correct printer too
0
 

Author Comment

by:mindwarpltd
ID: 24777134
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
 

Author Comment

by:mindwarpltd
ID: 24777171
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
 

Author Comment

by:mindwarpltd
ID: 24779981
Help ?
0
 

Author Comment

by:mindwarpltd
ID: 24787090
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
 

Author Closing Comment

by:mindwarpltd
ID: 31599729
This solution is perfect, my problem was that the page setup dialog and printer dialog gave different values.
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

If you have ever found yourself doing a repetitive action with the mouse and keyboard, and if you have even a little programming experience, there is a good chance that you can use a text editor to whip together a sort of macro to automate the proce…
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
You have products, that come in variants and want to set different prices for them? Watch this micro tutorial that describes how to configure prices for Magento super attributes. Assigning simple products to configurable: We assigned simple products…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now