pixels per inch Ms Access Gurus

API > GetDeviceCaps > Pixels per inch

VBA wrapper function to call the GetDeviceCaps API to determine the monitor's pixels/inch. Pixels per inch is ppi.

The api_GetPPI function is called by the CalendarMaker, an Access program that makes calendar reports, which will be posted shortly.

Quick Jump

Example

The pixel thickness of a line is divided by pixels/inch, and then multiplied by 1440 twips/inch to get twips. In this case, a light gray box is drawn inside the calendar lines for the days in the first week that are at the end of the previous month.

GetDeviceCaps from Access

Goto Top  

Code

'*************** Code Start *****************************************************
' module name: mod_api_GetDeviceCaps_PPI_s4p
'  http://msaccessgurus.com/VBA/Code/API_GetDeviceCaps_ppi.htm
'-------------------------------------------------------------------------------
' Purpose  : use GetDeviceCaps API to get ppi (pixel/inch)
' Author   : crystal (strive4peace)
' License  : below code
' Code List: www.msaccessgurus.com/code.htm
'-------------------------------------------------------------------------------
'  used by CalendarMaker
' edit 230214 using Peter Cole's API Viewer
'  https://www.thememydatabase.co.uk/access32to64.html

    Private Declare PtrSafe Function GetDC Lib  "user32" _ 
      (ByVal hwnd As LongPtr _ 
      ) As LongPtr 
   Private Declare PtrSafe Function ReleaseDC Lib  "user32" ( _ 
       ByVal hwnd As LongPtr,_ 
       ByVal hdc As LongPtr _ 
       ) As Long 
   Private Declare PtrSafe Function GetDeviceCaps Lib  "gdi32" ( _ 
       ByVal hdc As LongPtr _ 
       ,ByVal nIndex As Long _ 
       ) As Long 

'~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ api_GetPPI
Function api_GetPPI(Optional pbHorizontal As Boolean = True) As Long 
's4p 191120, 230206
'get pixels per inch. My monitor is 96 ppi.

   'PARAMETER
   '  pbHorizontal=True to return horizontal ppi, else vertical ppi
   
   Const LOGPIXELSX = 88  'pixels/inch in x, logical monitor
   Const LOGPIXELSY = 90  'pixels/inch in y

   'dimension Handle
   Dim hdc As LongPtr 
         
   'set handle
   hdc = GetDC(0) 
   
   If pbHorizontal <> True Then 
      'Vertical ppi
      api_GetPPI = GetDeviceCaps(hdc,LOGPIXELSY)  'LOGPIXELSY=90
   Else 
      'Horizontal ppi
      api_GetPPI = GetDeviceCaps(hdc,LOGPIXELSX)    'LOGPIXELSX=88
   End If 
      
   'release handle
   hdc = ReleaseDC(0,hdc) 
    
End Function 
' LICENSE
'   You may freely use and share this code
'     provided this license notice and comment lines are not changed;
'     code may be modified provided you clearly note your changes.
'   You may not sell this code alone, or as part of a collection,
'     without my handwritten permission.
'   All ownership rights reserved. Use at your own risk.
'   ~ crystal (strive4peace)  www.msaccessgurus.com
'*************** Code End *******************************************************
' Made with Color Code add-in posted on http://msaccessgurus.com/tool/Addin_ColorCode.htm

Goto Top  

Logic

At the top of the module, declare API functions from user32 to get (GetDC) and release (ReleaseDC) a DC (device caps) handle. Also declare GetDeviceCaps from gdi32 to return information about a device. Conditional compiling is used so this will work in all environments.

api_GetPPI is a wrapper function to set a handle to a device, read the value for pixel per inch, then release the device handle.

Unless pbHorizontal is false, the horizontal pixels per inch will be returned.

The index value for item = LOGPIXELSX is 88, which is pixels/inch in the X direction. The index value for item = LOGPIXELSY is 90, which is pixels/inch in the Y direction.

User32.DLL and gdi32.DLL are files with instructions for communicating with and getting information from the user interface and devices.

DLL, the file extension, stands for dynamic link library. DLL files are libraries with instructions that can be dynamically linked at runtime.

Optional Parameters

pbHorizontal

default value = True, which means that horizontal ppi will be determined; otherwise it will be for vertical.

Goto Top  

Download

Click HERE to download the zipped BAS file with the api_GetPPI function and the API declarations it needs.
(2 kb, unzips to a module BAS file)  

License

This code may be used freely, but you may not sell it in whole or in part. You may include it in applications you use yourself, and that you develop to help others. Keep attribution. Use at your own risk.

Updating a 32-bit application to work in 64-bit?

Download Peter Cole's free Scanner and Viewer (comes with scanner) to find problems and lookup correct syntax for API calls.
https://www.thememydatabase.co.uk/access32to64.html
it's free -- click the Download button and then click Add to Cart in the screen that pops up. There won't be a charge.

Goto Top  

Reference

GetDeviceCaps

Docs / Windows / Windows GDI / Wingdi.h / GetDeviceCaps function

Help: GetDeviceCaps function

Device Context Functions

Docs / Windows / Windows GDI / Device Contexts / Device Context Reference

Help: Device Context Functions

Windows GDI

Docs / Windows / Windows GDI / Device Contexts / Device Context Reference

Help: Windows GDI

Wikipedia: Microsoft Windows library files

interesting article about Microsoft Windows library files on Wikipedia

Goto Top  

Constant Values for GetDeviceCaps

The GetDeviceCaps function returns information about capabilities for the specified index. What you won't find on the help link for GetDeviceCaps are the numeric values for the index constants. You'll need this information to call GetDeviceCaps from VBA. I found the constant values in a header file on my computer called wingdi.h

GetDeviceCaps Constant Values for Index

ConstantValueDescription
DRIVERVERSION0 Device driver version
TECHNOLOGY2 Device technology. Use DT_list
HORZSIZE4 Horizontal screen size in millimeters
VERTSIZE6 Vertical screen size in millimeters
HORZRES8 Horizontal width in pixels
VERTRES10 Vertical height in pixels
LOGPIXELSX88 Logical pixels inch in X
LOGPIXELSY90 Logical pixels inch in Y
BITSPIXEL12 Number of bits per pixel
PLANES14 Number of planes
NUMBRUSHES16 Number of brushes the device has
NUMPENS18 Number of pens the device has
NUMMARKERS20 Number of markers the device has
NUMFONTS22 Number of fonts the device has
NUMCOLORS24 Number of colors the device supports
ASPECTX40 Length of the X leg
ASPECTY42 Length of the Y leg
ASPECTXY44 Length of the hypotenuse
PDEVICESIZE26 Size required for device descriptor
CLIPCAPS36 Clipping capabilities
SIZEPALETTE104 Number of entries in physical palette
NUMRESERVED106 Number of reserved entries in palette
COLORRES108 Actual color resolution
PHYSICALWIDTH110 Physical Width in device units
PHYSICALHEIGHT111 Physical Height in device units
PHYSICALOFFSETX112 Physical Printable Area x margin
PHYSICALOFFSETY113 Physical Printable Area y margin
VREFRESH116 Current vertical refresh rate of the display device (for displays only) in Hz
SCALINGFACTORX114 Scaling factor x
SCALINGFACTORY115 Scaling factor y
BLTALIGNMENT119 Preferred blt alignment
SHADEBLENDCAPS120 Shading and blending caps. Use SB_list
RASTERCAPS38 Bitblt capabilities. Use RC_list
CURVECAPS28 Curve capabilities. Use CC_list
LINECAPS30 Line capabilities. Use LC_list
POLYGONALCAPS32 Polygonal capabilities. Use PC_list
TEXTCAPS34 Text capabilities. Use TC_list
COLORMGMTCAPS121 Color Management caps. Use CM_list

TECHNOLOGY values

DT_PLOTTER0Vector plotter
DT_RASDISPLAY1Raster display
DT_RASPRINTER2Raster printer
DT_RASCAMERA3Raster camera
DT_CHARSTREAM4Character-stream, PLP
DT_METAFILE5Metafile, VDM
DT_DISPFILE6Display-file

SHADEBLENDCAPS values

SB_NONE0x00000000device doesn't support SB capabilities
SB_CONST_ALPHA0x00000001handles SourceConstantAlpha
SB_PIXEL_ALPHA0x00000002Capable of per-pixel alpha in AlphaBlend
SB_PREMULT_ALPHA0x00000004Capable of premultiplied alpha in AlphaBlend
SB_GRAD_RECT0x00000010Capable of GradientFill rectangles
SB_GRAD_TRI0x00000020Capable of GradientFill triangles

RASTERCAPS values

RC_NONEdevice doesn't support RC capabilities
RC_BITBLT1Can do standard BLT
RC_BANDING2requires banding support
RC_SCALING4requires scaling support
RC_BITMAP648supports >64K bitmap
RC_GDI20_OUTPUT0x0010has 2.0 output calls
RC_GDI20_STATE0x0020
RC_SAVEBITMAP0x0040
RC_DI_BITMAP0x0080supports DIB to memory
RC_PALETTE0x0100supports a palette
RC_DIBTODEV0x0200supports DIBitsToDevice
RC_BIGFONT0x0400supports >64K fonts
RC_STRETCHBLT0x0800supports StretchBlt
RC_FLOODFILL0x1000supports FloodFill
RC_STRETCHDIB0x2000supports StretchDIBits
RC_OP_DX_OUTPUT0x4000
RC_DEVBITS0x8000

CURVECAPS values

CC_NONE0Device doesn't support curves
CC_CIRCLES1Device can draw circles.
CC_PIE2Device can draw pie wedges.
CC_CHORD4Device can draw chord arcs.
CC_ELLIPSES8Device can draw ellipses.
CC_WIDE16Device can draw wide borders.
CC_STYLED32Device can draw styled borders.
CC_WIDESTYLED64Device can draw borders that are wide and styled.
CC_INTERIORS128Device can draw interiors.
CC_ROUNDRECT256Device can draw rounded rectangles.

LINECAPS values

LC_NONE0Device doesn't support lines
LC_POLYLINE2can draw polylines
LC_MARKER4can draw markers
LC_POLYMARKER8can draw multiple markers
LC_WIDE16can draw wide lines
LC_STYLED32can draw styled lines
LC_WIDESTYLED64can draw wide styled lines
LC_INTERIORS128can draw interiors

POLYGONALCAPS values

PC_NONE0Device doesn't support polygonals
PC_POLYGON1Can do polygons
PC_RECTANGLE2Can do rectangles
PC_WINDPOLYGON4Can do winding polygons
PC_TRAPEZOID4Can do trapezoids
PC_SCANLINE8Can do scanlines
PC_WIDE16Can do wide borders
PC_STYLED32Can do styled borders
PC_WIDESTYLED64Can do wide styled borders
PC_INTERIORS128Can do interiors
PC_POLYPOLYGON256Can do polypolygons
PC_PATHS512Can do paths

TEXTCAPS values

TC_OP_CHARACTER0x00000001can do character OutputPrecision
TC_OP_STROKE0x00000002can do stroke OutputPrecision
TC_CP_STROKE0x00000004can do stroke clip precision ClipPrecision
TC_CR_900x00000008can do 90-degree character rotation CharRotAbility
TC_CR_ANY0x00000010can do any character rotation CharRotAbility
TC_SF_X_YINDEP0x00000020can scale indpedently in x and y directions ScaleFreedom X_YINDEPENDENT
TC_SA_DOUBLE0x00000040 can DOUBLE ScaleAbility
TC_SA_INTEGER0x00000080ScaleAbility uses INTEGER multiples for scaling characters
TC_SA_CONTIN0x00000100ScaleAbility uses any multiples for exact CONTINUOUS scaling characters
TC_EA_DOUBLE0x00000200can do double-weight characters EmboldenAbility DOUBLE
TC_IA_ABLE0x00000400ItalisizeAbility ABLE
TC_UA_ABLE0x00000800UnderlineAbility ABLE
TC_SO_ABLE0x00001000StrikeOutAbility ABLE
TC_RA_ABLE0x00002000RasterFontAble ABLE
TC_VA_ABLE0x00004000VectorFontAble ABLE
TC_RESERVED0x00008000Reserved; must be zero
TC_SCROLLBLT0x00010000canNOT do text scroll with blt, bit-block transfer

COLORMGMTCAPS values

CM_NONE0x00000000does not support ICM, Image Color Management
CM_DEVICE_ICM0x00000001can perform ICM
CM_GAMMA_RAMP0x00000002supports Get and SetDeviceGammaRamp
CM_CMYK_COLOR0x00000004can use CMYK color space ICC color profile, International Color Consortium

Goto Top  

Backstory

GetDeviceCaps gets information about device capabilities and is in the gdi library. The user32 library is used to get a handle to the screen device, release it when done, and does a lot more! I read that user32 uses gdi for some of its functions, but I don't know if that's true; maybe user32 got pieces from gdi.

Once I found the constant values for the settings I wanted, using GetDeviceCaps turned out to be pretty easy.

Updated 14 Feb 2023
I thought this would work in 32 or 64 bit, but it didn't! Thanks to Peter Cole's super-helpful, free API Viewer, now it's fixed to work in 64-bit too!

Goto Top  

Share

Share with others ... here's the link to copy:
http://msaccessgurus.com/VBA/Code/API_GetDeviceCaps_ppi.htm

Do you have something to say?

Share your comments! Was something not clear? Did you find a bug? Is an explanation wrong or not sufficient? Do you want the code do more (there is always more)?

Some of you write to say thanks and tell me what you're doing with Access ... its nice to hear from you. I want you to be the best you can with Access, and leverage other applications like Excel, Word, and PowerPoint ... and Windows.

Are you a developer? Do you want to share? Email to ask about getting your pages added to the code index.

Let's communicate, collaborate, and appreciate ... we all get better by sharing. Email me anytime at info@msAccessGurus.com. I love hearing from you. ~ crystal

Goto Top