Hi All,

Okay, the following code will return the registry value for pixels-per-inch (DPI) for Windows 8.0 and below. It may (or may not) return it for Windows 8.1 and above.

Code:

Option Explicit
'
Public Enum HKeyEnum
    HKEY_CLASSES_ROOT = &H80000000
    HKEY_CURRENT_USER = &H80000001
    HKEY_LOCAL_MACHINE = &H80000002
    HKEY_USERS = &H80000003
    HKEY_PERFORMANCE_DATA = &H80000004
    HKEY_CURRENT_CONFIG = &H80000005
    HKEY_DYN_DATA = &H80000006
End Enum
Private Const READ_CONTROL = &H20000
Private Const SYNCHRONIZE = &H100000
Private Const STANDARD_RIGHTS_READ = (READ_CONTROL)
Private Const KEY_QUERY_VALUE = &H1
Private Const KEY_ENUMERATE_SUB_KEYS = &H8
Private Const KEY_NOTIFY = &H10
Private Const KEY_READ = ((STANDARD_RIGHTS_READ Or KEY_QUERY_VALUE Or KEY_ENUMERATE_SUB_KEYS Or KEY_NOTIFY) And (Not SYNCHRONIZE))
Private Const ERROR_SUCCESS = 0&
Private Declare Function RegOpenKeyEx Lib "advapi32.dll" Alias "RegOpenKeyExA" (ByVal hKey As Long, ByVal lpSubKey As String, ByVal ulOptions As Long, ByVal samDesired As Long, phkResult As Long) As Long
Private Declare Function RegQueryValueEx Lib "advapi32.dll" Alias "RegQueryValueExA" (ByVal hKey As Long, ByVal lpValueName As String, ByVal lpReserved As Long, lpType As Long, lpData As Any, lpcbData As Long) As Long         ' Note that if you declare the lpData parameter as String, you must pass it By Value.
Private Declare Function RegCloseKey Lib "advapi32.dll" (ByVal hKey As Long) As Long
'

Private Sub Form_Load()
    MsgBox DpiSetting
    Unload Me
End Sub

Public Function DpiSetting() As Long
    ' This uses the registry, so it circumvents any/all manifest settings.
    ' 96 is the default value for this.
    DpiSetting = GetRegistryDword(HKEY_CURRENT_USER, "Control Panel\Desktop", "LogPixels")
End Function

Public Function GetRegistryDword(ByVal hKey As HKeyEnum, ByVal Section As String, Optional ByVal Key As String = "*", Optional ByVal Default As Long = 0) As Long
    ' Section   Required. String expression containing the name of the section where the key setting is found.
    ' Key       Required. String expression containing the name of the key setting to return. "*" = default
    ' Default   Optional. Expression containing the value to return if no value is set in the key setting.
    Dim nRet As Long
    Dim hKey2 As Long
    Dim nType As Long
    Dim nBytes As Long
    Dim Buffer As Long
    '
    ' Assume failure and set return to Default.
    GetRegistryDword = Default
     '
    ' Open key
    nRet = RegOpenKeyEx(hKey, Section, 0&, KEY_READ, hKey2)
    If nRet = ERROR_SUCCESS Then
        ' Set appropriate value for default query.
        If Key = "*" Then Key = vbNullString
        ' Get data
        nRet = RegQueryValueEx(hKey2, Key, 0&, nType, Buffer, 4)
        If nRet = ERROR_SUCCESS Then GetRegistryDword = Buffer
        Call RegCloseKey(hKey2)
    End If
End Function
Here's a page that discusses much of this.


Now this all gets quite confusing because, with monitors, an inch isn't really an inch. It all depends on the size of the monitor.

However, we must "think" in terms of inches (or something related) because there are 1440 twips per inch (by definition), and we must very often think in twips.

So, as the above linked webpage states, for Windows 8.0 and prior, there was a convention adopted that 96 DPI = 100%. Or, said a bit more conveniently for programmers, 15 twips per dot(pixel) = 100%.

Here's what I want. I want a procedure (regardless of how my program is manifested) that tells me my DPI percentage (or possibly twips-per-dot) for each monitor on a Windows 8.1 or greater, multi-monitor system. I can probably work it out, and I may be working on it, but I just thought that someone might have it.

At the present time, I'm not sure if I should explore around in the monitor EDID, or possibly study that link above more, possibly digging deeper into that "HKCU\Control Panel\Desktop" area.

Any help will be appreciated.

Regards,
Elroy