Announcement

Collapse
No announcement yet.

Where in my PC can I find where the Windows 10 Magnification is Located?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts
    Tim Lakinir
    Member

  • Tim Lakinir
    replied
    Thanks Pierre

    Leave a comment:

  • Pierre Bellisle
    Member

  • Pierre Bellisle
    replied
    In that event, to work with a .res file, just change
    #RESOURCE "GetScaleFactorForMonitor.pbr"
    to
    #RESOURCE RES, "GetScaleFactorForMonitor.RES"

    Also, in the PowerBASIC editor, you got the menu OPTIONS / Compiler / Create a .PBR when compiling .RC files

    Leave a comment:

  • Tim Lakinir
    Member

  • Tim Lakinir
    replied
    Hi Pierre

    refering to your post #6
    I tried compiling GetScaleFactorForMonitor.rc to get GetScaleFactorForMonitor.pbr but got GetScaleFactorForMonitor.res instead

    And in the main program when I changed the name to GetScaleFactorForMonitor.res from GetScaleFactorForMonitor.pbr
    the main program cannot compile and gives the error

    Error 478 in C:\PB tst2\Monitor scalefactor\Monitor scaleFactor.bas(10:001): Resource file error
    Line 10: #RESOURCE "GetScaleFactorForMonitor.res" 'Need 'urn:schemas-microsoft-com:compatibility.v1'



    Changing back to GetScaleFactorForMonitor.pbr also give the same error message

    What's the problem as I'm using PB Win 10.03 ?




    Leave a comment:

  • Pierre Bellisle
    Member

  • Pierre Bellisle
    replied
    Great!

    Leave a comment:

  • Bob Scott
    Member

  • Bob Scott
    replied
    Click image for larger version

Name:	Peter 4K.png
Views:	98
Size:	19.2 KB
ID:	810842
    Mystery solved. I had missed the very last line in the RC (")") - just sloppy. Thank you very much Peter!

    \

    Leave a comment:

  • Pierre Bellisle
    Member

  • Pierre Bellisle
    replied
    One may get erroneous result like that if the manifest is not there.
    First thing would be to double check that the mandatory manifest
    embedded in the rc file is there with the "Compatibility section" as shown above in my first post.

    Leave a comment:

  • Bob Scott
    Member

  • Bob Scott
    replied
    Peter,

    I was away from PowerBasic for three years while I was taking care of my wife who had ALS and also since I am an octogenarian I decided not to upgrade to version 10 so I am running version 9.05. I changed your version 10 program just enough to compile in 9.05 which was just change the FUNCTION Declares from IMPORT to LIB which allows a 9.05 compile but I get funny numbers. On my 2K 100% machine it looks good but on my 4K 200% machine - not so good. Do you see anything that should also be changed?

    Thanks much,


    Bob Click image for larger version

Name:	Peter 2K & 4K.png
Views:	115
Size:	116.5 KB
ID:	810838

    Leave a comment:

  • Pierre Bellisle
    Member

  • Pierre Bellisle
    replied
    GetScaleFactorForMonitor

    Here is a version for multi monitor using the same resource manifest as above.
    Code:
    #COMPILE EXE '#Win 10.03#
    #DIM ALL
    #INCLUDE "Win32Api.inc"
    '#INCLUDE "ShellScalingApi.inc" 'From José's API includes
    
    #RESOURCE "GetScaleFactorForMonitor.pbr" 'Need 'urn:schemas-microsoft-com:compatibility.v1'
    
    DECLARE FUNCTION GetScaleFactorForMonitor LIB "SHCORE.DLL" ALIAS "GetScaleFactorForMonitor" _
    (BYVAL hMon AS DWORD, BYREF dwScale AS LONG) AS LONG
    
    DECLARE FUNCTION RegisterScaleChangeEvent LIB "SHCORE.DLL" ALIAS "RegisterScaleChangeEvent" _
    (BYVAL hEvent AS DWORD, BYREF pdwCookie AS DWORD) AS LONG
    
    DECLARE FUNCTION UnregisterScaleChangeEvent LIB "SHCORE.DLL" ALIAS "UnregisterScaleChangeEvent" _
    (BYVAL dwCookie AS DWORD) AS LONG
    
    GLOBAL hDlg  AS DWORD
    GLOBAL sInfo AS STRING
    
    $AppName       = "GetScaleFactorForMonitor"
    %EditInfo      = 101
    %ButtonDisplay = 201
    '______________________________________________________________________________
    
    FUNCTION MonitorEnum(BYVAL hMonitor AS DWORD, BYVAL hdcMonitor AS DWORD, _
                         BYREF rectMonitor AS RECT, hMonitorArray() AS DWORD) AS LONG
     LOCAL MonitorInf AS MONITORINFOEX
     LOCAL dwScale    AS DWORD
    
     MonitorInf.cbSize = SIZEOF(MONITORINFOEX)
     GetMonitorInfo(hMonitor, BYVAL VARPTR(MonitorInf))
    
     sInfo &= "Device:   " & MonitorInf.szDevice & _
              IIF$(MonitorInf.dwFlags = %MONITORINFOF_PRIMARY, " (Primary monitor)", "") & $CRLF & _
              "Monitor:  " & FORMAT$(MonitorInf.rcMonitor.nRight  - MonitorInf.rcMonitor.nLeft) & " by " & _
                             FORMAT$(MonitorInf.rcMonitor.nBottom - MonitorInf.rcMonitor.nTop) & _
              " (LRTB: " &   FORMAT$(MonitorInf.rcMonitor.nLeft) & " " & FORMAT$(MonitorInf.rcMonitor.nRight) & " " &  _
                             FORMAT$(MonitorInf.rcMonitor.nTop)  & " " & FORMAT$(MonitorInf.rcMonitor.nBottom) & ")" & $CRLF & _
              "WorkArea: " & FORMAT$(MonitorInf.rcWork.nRight  - MonitorInf.rcWork.nLeft) & " by " & _
                             FORMAT$(MonitorInf.rcWork.nBottom - MonitorInf.rcWork.nTop) & _
              " (LRTB: " &   FORMAT$(MonitorInf.rcWork.nLeft) & " " &  FORMAT$(MonitorInf.rcWork.nRight) & " " &  _
                             FORMAT$(MonitorInf.rcWork.nTop)  & " " &  FORMAT$(MonitorInf.rcWork.nBottom) & ")" & $CRLF
    
     GetScaleFactorForMonitor(hMonitor, dwScale)
     sInfo &= "Scale is" & STR$(dwScale) & "%" & $CRLF & $CRLF
     
     FUNCTION = %TRUE 'Continue enumeration until no more monitors
    
    END FUNCTION
    '_____________________________________________________________________________
    
    THREAD FUNCTION ScaleChangeThread(BYVAL hEvent AS DWORD) AS LONG
    
     DO
       WaitForSingleObject(hEvent, %INFINITE) 'Wait for OS scale change
       PostMessage(hDlg, %WM_APP, 0, 0)
     LOOP
    
    END FUNCTION
    '_____________________________________________________________________________
    
    CALLBACK FUNCTION DlgProc
     LOCAL  hThread   AS DWORD
     STATIC hEvent    AS DWORD
     STATIC dwCookie  AS DWORD
     LOCAL  dwScale   AS DWORD
    
     SELECT CASE CBMSG
    
       CASE %WM_INITDIALOG
         hEvent = CreateEvent (BYVAL %NULL, BYVAL 0, BYVAL 0, "ScaleEvent")
         THREAD CREATE ScaleChangeThread(hEvent) TO hThread
         THREAD CLOSE hThread TO hThread
         RegisterScaleChangeEvent(hEvent, dwCookie) 'Be notified of OS scale change
         PostMessage(hDlg, %WM_APP, 0, 0) 'First time call
    
       CASE %WM_APP
         sInfo = ""
         EnumDisplayMonitors(BYVAL %NULL, BYVAL %NULL, BYVAL CODEPTR(MonitorEnum), 0) 'BYVAL VARPTR(hMonitorArray()))
         CONTROL SET TEXT hDlg, %EditInfo, sInfo
    
       CASE %WM_COMMAND
         SELECT CASE CBCTL
           CASE %ButtonDisplay
             IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
               SHELL("rundll32.exe shell32.dll,Control_RunDLL desk.cpl")
             END IF
         END SELECT
    
       CASE %WM_WINDOWPOSCHANGED
         'App window can be moved between monitors.
         GetScaleFactorForMonitor(MonitorFromWindow(hDlg, %MONITOR_DEFAULTTONEAREST), dwScale)
         SetWindowText(hDlg, "Dialog is now" & STR$(dwScale) & "%")
    
       CASE %WM_DESTROY
         UnregisterScaleChangeEvent(dwCookie)
         CloseHandle(hEvent)
    
      END SELECT
    
    END FUNCTION
    '______________________________________________________________________________
    
    FUNCTION PBMAIN()
     LOCAL hIcon AS DWORD
    
     DIALOG FONT "Segoe UI", 9
     DIALOG NEW PIXELS, %HWND_DESKTOP, $AppName, , , 400, 300, _
     %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, 0 TO hDlg
    
     CONTROL ADD TEXTBOX, hDlg, %EditInfo, "Scale info", 10, 10, 390, 240, _
     %WS_TABSTOP OR %WS_VSCROLL OR %ES_MULTILINE OR %ES_WANTRETURN, %WS_EX_CLIENTEDGE
    
     CONTROL ADD BUTTON, hDlg, %ButtonDisplay, "Change display scale", 10, 260, 200, 30
    
     hIcon = ExtractIcon(GETMODULEHANDLE(""), "Shell32.dll", 294) 'o
     SetClassLong(hDlg, %GCL_HICON, hIcon)
    
     DIALOG SHOW MODAL hDlg CALL DlgProc
    
     DestroyIcon(hIcon)
    
    END FUNCTION
    '______________________________________________________________________________
    '
    Pierre Bellisle
    Member
    Last edited by Pierre Bellisle; 13 Sep 2021, 04:21 PM.

    Leave a comment:

  • Bob Scott
    Member

  • Bob Scott
    replied
    Thanks for all the info guys. With my 2K Monitor and 100% Magnification I thought I was good but maybe with your info I can get the program working with my 4K monitor and 200% Magnification. Working.

    Thanks very much!

    Bob

    Leave a comment:

  • Pierre Bellisle
    Member

  • Pierre Bellisle
    replied
    GetScaleFactorForMonitor

    GetScaleFactorForMonitor will provide you the actual scaling.
    You may use RegisterScaleChangeEvent/UnregisterScaleChangeEvent to be notified dynamically.
    A manifest with a compatibility section is mandatory to get valid result.

    Code:
    #COMPILE EXE '#Win 10.03#
    #DIM ALL
    #INCLUDE "Win32Api.inc"
    '#INCLUDE "ShellScalingApi.inc" 'From José's API includes
    
    #RESOURCE "GetScaleFactorForMonitor.pbr" 'Need 'urn:schemas-microsoft-com:compatibility.v1'
    
    DECLARE FUNCTION GetScaleFactorForMonitor LIB "SHCORE.DLL" ALIAS "GetScaleFactorForMonitor" _
    (BYVAL hMon AS DWORD, BYREF dwScale AS LONG) AS LONG
    
    DECLARE FUNCTION RegisterScaleChangeEvent LIB "SHCORE.DLL" ALIAS "RegisterScaleChangeEvent" _
    (BYVAL hEvent AS DWORD, BYREF pdwCookie AS DWORD) AS LONG
    
    DECLARE FUNCTION UnregisterScaleChangeEvent LIB "SHCORE.DLL" ALIAS "UnregisterScaleChangeEvent" _
    (BYVAL dwCookie AS DWORD) AS LONG
    
    GLOBAL hDlg AS DWORD
    
    $AppName       = "GetScaleFactorForMonitor"
    %StaticInfo    = 101
    %ButtonDisplay = 201
    '______________________________________________________________________________
    
    THREAD FUNCTION ScaleChangeThread(BYVAL hEvent AS DWORD) AS LONG
    
     DO
       WaitForSingleObject(hEvent, %INFINITE) 'Wait for OS scale change
       PostMessage(hDlg, %WM_APP, 0, 0)
     LOOP
    
    END FUNCTION
    '_____________________________________________________________________________
    
    CALLBACK FUNCTION DlgProc
     LOCAL  hThread   AS DWORD
     LOCAL  hMonitor  AS DWORD
     STATIC hEvent    AS DWORD
     LOCAL  dwScale   AS DWORD
     STATIC dwCookie  AS DWORD
    
     SELECT CASE CBMSG
    
       CASE %WM_INITDIALOG
         hEvent = CreateEvent (BYVAL %NULL, BYVAL 0, BYVAL 0, "ScaleEvent")
         THREAD CREATE ScaleChangeThread(hEvent) TO hThread
         THREAD CLOSE hThread TO hThread
         RegisterScaleChangeEvent(hEvent, dwCookie) 'Be notified of OS scale change
         PostMessage(hDlg, %WM_APP, 0, 0) 'First time call
    
       CASE %WM_APP
         hMonitor = MonitorFromWindow(GetDesktopWindow(), %MONITOR_DEFAULTTOPRIMARY) 'Checking default monitor
         GetScaleFactorForMonitor(hMonitor, dwScale)
         CONTROL SET TEXT hDlg, %StaticInfo, "Scale is" & STR$(dwScale) & "% at " & TIME$
    
       CASE %WM_COMMAND
         SELECT CASE CBCTL
           CASE %ButtonDisplay
             IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
               SHELL("rundll32.exe shell32.dll,Control_RunDLL desk.cpl")
             END IF
         END SELECT
    
       CASE %WM_DESTROY
         UnregisterScaleChangeEvent(dwCookie)
         CloseHandle(hEvent)
    
      END SELECT
    
    END FUNCTION
    '______________________________________________________________________________
    
    FUNCTION PBMAIN()
     LOCAL hIcon AS DWORD
    
     DIALOG FONT "Segoe UI", 9
     DIALOG NEW PIXELS, %HWND_DESKTOP, $AppName, , , 400, 100, _
     %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_SYSMENU, 0 TO hDlg
    
     CONTROL ADD LABEL, hDlg, %StaticInfo, "Scale %", 10, 10, 390, 20
    
     CONTROL ADD BUTTON, hDlg, %ButtonDisplay, "Change display scale", 10, 65, 200, 30
    
     hIcon = ExtractIcon(GETMODULEHANDLE(""), "Shell32.dll", 294) 'o
     SetClassLong(hDlg, %GCL_HICON, hIcon)
    
     DIALOG SHOW MODAL hDlg CALL DlgProc
    
     DestroyIcon(hIcon)
    
    END FUNCTION
    '______________________________________________________________________________
    '
    Here is a manifest embedded in a resource file named GetScaleFactorForMonitor.rc.
    Compile it to GetScaleFactorForMonitor.pbr
    Code:
    #include "resource.h"
    
    #define IDR_MANIFEST 1
    #define RT_MANIFEST 24
    
    IDR_MANIFEST RT_MANIFEST MOVEABLE PURE
    {
     "<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
    
       <description>Windows Shell</description>
    
       <!-- Compatibility section for Program Compatibility Assistant (PCA) -->
       <compatibility xmlns='urn:schemas-microsoft-com:compatibility.v1'>
         <application>
           <supportedOS Id='{e2011457-1546-43c5-a5fe-008deee3d3f0}'/>
           <supportedOS Id='{35138b9a-5d96-4fbd-8e2d-a2440225f93a}'/>
           <supportedOS Id='{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}'/>
           <supportedOS Id='{1f676c76-80e1-4239-95bb-83d0f6d0da78}'/>
           <supportedOS Id='{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}'/>
         </application>
         // <!-- {e2011457-1546-43c5-a5fe-008deee3d3f0} Windows Vista (6.0) -->
         // <!-- {35138b9a-5d96-4fbd-8e2d-a2440225f93a} Windows 7 (6.1) -->
         // <!-- {4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38} Windows 8 (6.2) -->
         // <!-- {1f676c76-80e1-4239-95bb-83d0f6d0da78} Windows 8.1 (6.3) Needed to avoid GetVersionEx report 6.2 -->
         // <!-- {8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a} Windows 10.0 (10.0) Needed to avoid GetVersionEx report 6.2 -->
       </compatibility>
    
       <!-- Common controls section -->
       <dependency>
         <dependentAssembly>
           <assemblyIdentity
             type='win32'
             name='Microsoft.Windows.Common-Controls'
             version='6.0.0.0'
             processorArchitecture='x86'
             publicKeyToken='6595b64144ccf1df'
             language='*'
           />
         </dependentAssembly>
       </dependency>
    
       <!-- DpiAware and long path section -->
       <asmv3:application xmlns:asmv3='urn:schemas-microsoft-com:asm.v3'>
         <asmv3:windowsSettings xmlns='http:\x2F\x2Fschemas.microsoft.com/SMI/2005/WindowsSettings'>
           <dpiAware>true</dpiAware>
           <Path:LongPathAware>false</Path:LongPathAware>
         </asmv3:windowsSettings>
       </asmv3:application>
    
       <!-- RunAs section -->
       <asmv3:trustInfo xmlns:asmv3='urn:schemas-microsoft-com:asm.v3'>
         <asmv3:security>
           <asmv3:requestedPrivileges>
             <asmv3:requestedExecutionLevel
               level='asInvoker'
               uiAccess='false'
             />
           </asmv3:requestedPrivileges>
         </asmv3:security>
       </asmv3:trustInfo>
    
     </assembly>"
    }
    //
    Pierre Bellisle
    Member
    Last edited by Pierre Bellisle; 13 Sep 2021, 06:22 PM.

    Leave a comment:

  • Gary Beene
    Member

  • Gary Beene
    replied
    Howdy, Paul!

    If I exit magnification and return, it keeps the magnification levels between sessions. So, it must be kept somewhere else? I was hoping one of the API would allow retrieving it?

    Leave a comment:

  • Paul Dixon
    Member

  • Paul Dixon
    replied
    The monitor scaling is stored in the registry but it only appears to update when Windows restarts.
    HKEY_CURRENT_USER/Control Panel/Desktop/Window metrics/Applied DPI

    Leave a comment:

  • Gary Beene
    Member

  • Gary Beene
    replied
    Howdy, Bob!

    Reading here ..

    https://docs.microsoft.com/en-us/win...i/magapi-intro

    and here ...

    https://docs.microsoft.com/en-us/win...owsystemcursor

    ... looks promising for getting information.

    And, Jose has "magnification.inc" in his includes.

    I just haven't read enough yet to know how to use it!

    Leave a comment:

  • Gary Beene
    Member

  • Gary Beene
    replied
    Howdy, Bob!

    That's a great question. When I enable magnification for my users I have a variable to keep track of status. But, when they start my app, I don't have a way of knowing if magnification is already on, or what the magnification level is.

    I'll nose around some to see what I can find

    Leave a comment:

  • Bob Scott
    Member

  • Where in my PC can I find where the Windows 10 Magnification is Located?

    I wrote a macro to move the cursor, click buttons and enter data into an application which I did know the Control Handles so the cursor positions were absolute pixel based. It worked perfectly on my 2K display but I'm moving to a 4K display and set the Magnification to 200% which really messed up my Macro. I know for a 1 off I could just multiply the cursor positions by 0.5 but I would prefer to make it general purpose and sense the Magnification automatically. Does anyone know where the Magnification is stored?

    Thank you
Working...
X