when making a program DPI-aware on Windows 10, PB 5.31 and PB 5.40 beta 8 behave differently as for font size.
//edit 2017-06-02:
See this post below with code that seems to solve the problem.
//edit 2017-08-11:
Even better, see Blue's improved version on page 2. Many thanks for that!
The following test code is based on code by Rescator, but uses the new (i.e. Windows 8.1+) functions GetProcessDpiAwareness() and SetProcessDpiAwareness().
Code: Select all
; -- Windows 8.1+ (tested on Windows 10)
EnableExplicit
; Constants for Get/SetProcessDpiAwareness()
Enumeration
#Process_DPI_Unaware
#Process_System_DPI_Aware
#Process_Per_Monitor_DPI_Aware
EndEnumeration
Prototype.i pGetProcessDpiAwareness (hprocess.i, *level)
Prototype.i pSetProcessDpiAwareness (level.i)
Global.f g_ScaleDPIx=1.0, g_ScaleDPIy=1.0
Procedure InitScaleDPI()
Protected GetProcessDpiAwareness.pGetProcessDpiAwareness
Protected SetProcessDpiAwareness.pSetProcessDpiAwareness
Protected.i shcore, hdc, dpiaware=#Process_DPI_Unaware
; Only use this in EXEs, as DLLs inherit DPI from the calling process.
CompilerIf #PB_Compiler_ExecutableFormat = #PB_Compiler_Executable
shcore = OpenLibrary(#PB_Any, "shcore.dll")
If shcore
GetProcessDpiAwareness = GetFunction(shcore, "GetProcessDpiAwareness")
If GetProcessDpiAwareness
If GetProcessDpiAwareness(#Null, @ dpiaware) = #S_OK
Debug "Get: OK"
EndIf
Debug "DPI-awareness: " + dpiaware
EndIf
; If the exe is allready dpi aware (like through a manifest), then we skip using
; the SetProcessDpiAwareness function.
If dpiaware = #Process_DPI_Unaware
SetProcessDpiAwareness = GetFunction(shcore, "SetProcessDpiAwareness")
If SetProcessDpiAwareness
If SetProcessDpiAwareness(#Process_System_DPI_Aware) = #S_OK
Debug "Set: OK"
EndIf
EndIf
EndIf
CloseLibrary(shcore)
EndIf
CompilerEndIf
hdc = GetDC_(#Null) ; get handle to the device context for the entire screen
If hdc
g_ScaleDPIx = GetDeviceCaps_(hdc, #LOGPIXELSX) / 96.0 ; 96 is the default DPI value on Windows
g_ScaleDPIy = GetDeviceCaps_(hdc, #LOGPIXELSY) / 96.0
ReleaseDC_(#Null, hdc)
EndIf
EndProcedure
Macro DPIx (_x_)
(_x_) * g_ScaleDPIx
EndMacro
Macro DPIy (_y_)
(_y_) * g_ScaleDPIy
EndMacro
Define font
InitScaleDPI()
font = LoadFont(#PB_Any, "Segoe UI", 9, #PB_Font_HighQuality)
If font = 0
MessageRequester("Error", "Unable to load font.")
End
EndIf
SetGadgetFont(#PB_Default, FontID(font))
If OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, DPIx(180), DPIy(110), "PB " + StrF(#PB_Compiler_Version/100, 2)) = 0
MessageRequester("Error", "Unable to open main window.")
End
EndIf
TextGadget(#PB_Any, DPIx(20), DPIy(20), DPIx(80), DPIy(30), "ScaleDPIy: " + StrF(g_ScaleDPIy, 2))
TextGadget(#PB_Any, DPIx(20), DPIy(60), DPIx(80), DPIy(30), "Segoe UI 9 pt")
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Why do PB 5.31 and PB 5.40 beta 8 produce different results here?
Is there something wrong with my code, or is this a bug in PB 5.40 beta 8?
PS: Without calling any DPI related Windows API functions in the code, everything works as expected.