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.
Here's a page that discusses much of this.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
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

