dcsimg
Page 2 of 2 FirstFirst 12
Results 41 to 44 of 44

Thread: DPI + GdipDrawImageRectI

  1. #41
    PowerPoster Elroy's Avatar
    Join Date
    Jun 2014
    Location
    Near Nashville TN
    Posts
    4,603

    Re: DPI + GdipDrawImageRectI

    Here's a bit more stuff I threw into the top of Form1 of Dilettante's demo project (leaving everything else there).

    Code:
    
    Private Type RECT
        Left   As Long
        Top    As Long
        Right  As Long ' This is +1 (right - left = width)
        Bottom As Long ' This is +1 (bottom - top = height)
    End Type
    Private Type MONITORINFO
        cbSize As Long
        rcMonitor As RECT
        rcWork As RECT
        dwFlags As Long
    End Type
    Private Declare Function GetMonitorInfo Lib "user32.dll" Alias "GetMonitorInfoA" (ByVal hMonitor As Long, ByRef lpmi As MONITORINFO) As Long
    '
    
    Private Function MonitorWidthPx(hMonitor As Long) As Long
        Dim uMonInfo As MONITORINFO
        uMonInfo.cbSize = LenB(uMonInfo)
        If GetMonitorInfo(hMonitor, uMonInfo) = 0 Then Exit Function
        MonitorWidthPx = uMonInfo.rcMonitor.Right - uMonInfo.rcMonitor.Left
    End Function
    
    Private Function MonitorHeightPx(hMonitor As Long) As Long
        Dim uMonInfo As MONITORINFO
        uMonInfo.cbSize = LenB(uMonInfo)
        If GetMonitorInfo(hMonitor, uMonInfo) = 0 Then Exit Function
        MonitorHeightPx = uMonInfo.rcMonitor.Bottom - uMonInfo.rcMonitor.Top
    End Function
    
    

    And here's a screenshot of running the compiled Aid program on a Win10 monitor set at 175%. This is a full-HD monitor (1920 by 1080 pixels).

    Name:  mon3.png
Views: 32
Size:  54.6 KB

    What we see is that (at 175%) our width is 1097 pixels and our height is 617 pixels. That's possibly more useful information than what's returned by the Screen object. In fact, when not dealing with 96DPI, nor 100% scaling, nor a regular landscape monitor, we may do better to just abandon all use of the Screen object. Both the Width twips and the PelX are from the Screen object, and are wrong.

    Best Regards,
    Elroy

    EDIT1: Modified code under the "Check DPI" button:

    Code:
    
    Private Sub cmdCheckDPI_Click()
        Dim s As String
        Dim DPI As Long
        Dim hMon As Long
        '
        hMon = MonitorHandleForHwnd(Me.hWnd)
        DPI = MonitorDpiSetting(hMon)
        '
        If Not DllFunctionExists("shcore.dll", "GetDpiForMonitor") Then
            s = "Old GetDeviceCaps used for DPI." & vbCrLf
            s = s & "The DPI: " & Format$(DPI) & vbCrLf & vbCrLf
            s = s & "Scale factor not available."
        Else
            s = "New GetDpiForMonitor used for DPI." & vbCrLf
            s = s & "The DPI: " & Format$(DPI) & vbCrLf & vbCrLf
            s = s & "Scale factor: " & MonitorScaleFactor(hMon) & vbCrLf
            s = s & "Twips Per PelX: " & Screen.TwipsPerPixelX & vbCrLf
            s = s & "Width twips: " & Screen.Width & vbCrLf
            s = s & "Width pels: " & MonitorWidthPx(hMon) & vbCrLf
            s = s & "Height pels: " & MonitorHeightPx(hMon) & vbCrLf
        End If
        '
        MsgBox s
    End Sub
    
    
    Last edited by Elroy; Oct 15th, 2018 at 09:16 PM.
    Any software I post in these forums written by me is provided “AS IS” without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. Please understand that I’ve been programming since the mid-1970s and still have some of that code. My contemporary VB6 project is approaching 1,000 modules. In addition, I have a “VB6 random code folder” that is overflowing. I’ve been at this long enough to truly not know with absolute certainty from whence every single line of my code has come, with much of it coming from programmers under my employ who signed intellectual property transfers. I have not deliberately attempted to remove any licenses and/or attributions from any software. If someone finds that I have inadvertently done so, I sincerely apologize, and, upon notice and reasonable proof, will re-attach those licenses and/or attributions. To all, peace and happiness.

  2. #42
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,187

    Re: DPI + GdipDrawImageRectI

    There seem to be confusion about W10 scaling.

    As I understand, the % scale are % of DPI related to 96 DPI.
    But, as soon as you change it from the screen settings, the DPI doesn't change but everything is scaled (every window) like when you resize an image with Photoshop.
    And there appear a note "Some apps won't respond to scaling changes until you sign out".
    If you want the new DPI setting to take effect instead of the Photoshop-like scaling, then log-off and log-in.

    Still, for the VB6 IDE (like any other program), if it doesn't have a manifest file, Windows will tell it that it is running in 100% (96 DPI) and will apply the scale Photoshop-like to whatever screen size.

    A current monitor may have a native resolution of 1920x1080, so the width will always be 28800 in twips, that is 1920 x 15.
    15 = 1440/96 (100%).

    If the program is compiled with a manifest stating that it is DPI aware, then it may experience other screen widths for the same monitor (I mean keeping the setting to 1920x1080 also), but if the program does not manifest itseft as DPI aware, then it will always "see" 100% (96 DPI) and Windows 10 will scale it in a Photoshop like manner to whatever DPI setting it has set.

    So, if you really want to test a project in another DPI setting then compile, manifest the program and restart Windows after changing the % scale of the screen.
    Manifest the program or, if you prefer, manifest the IDE so you don't need to compile the project to test it (but be aware: dilettante will be against it).
    vbExtra: Print preview for VB6, print FlexGrids and more.
    MSDN online for VB6, Language reference.

  3. #43
    Frenzied Member
    Join Date
    Feb 2017
    Posts
    1,187

    Re: DPI + GdipDrawImageRectI

    Quote Originally Posted by LeandroA View Post
    thanks guys for so much information, although scaling is not an easy subject, but with a little work can be achieved, I personally think that the formula exposed in the first post (nScale = 1440! / Screen.TwipsPerPixelX / 96#) solves all my problems at least in all DPI scales in my pc with windows 10 (with a monitor of a TV "55 4k) worked perfectly without having to make many changes.


    with respect to <gdiScaling>true</gdiScaling>I did not play it much with him but some things do not repaint very well.

    I would like if someone can try the attachment and tell me if it finds any fault (compile the project) I do not have two monitors to test the scaling.
    Hello,
    It seems to work right Leandro, quite amazing BTW.
    Is there anything specific that you want us to test?

    I tested under Windows 10 and under Windows XP.
    In XP it almost worked, I had to comment the line Call DwmSetWindowAttribute....
    In XP, it showed some defect at a border, something than can probably be fixed easily if you want to support back to XP.

    In W10, everything seemed to work. I tested with two monitors, no problem.
    It shouldn't be a problem since W10 handle the scaling for the monitors unless the program is manifested DPI aware PerMonitor. But almost no VB6 program use that manifest setting AFAIK.
    vbExtra: Print preview for VB6, print FlexGrids and more.
    MSDN online for VB6, Language reference.

  4. #44

    Thread Starter
    Addicted Member
    Join Date
    Dec 2008
    Location
    Argentina
    Posts
    192

    Re: DPI + GdipDrawImageRectI

    Hiuuuu, I'm sorry, now I can see my error, the problem is that it did not close session or restart, that's why my values ​​did not change, now I understand what they told me about that little mathematical difference.


    I will stay with this function for compatibility reasons

    Code:
    Public Function GetWinDPI() As Double
        Dim hDC As Long, LPX  As Double
        
        hDC = GetDC(0&)
        LPX = CDbl(GetDeviceCaps(hDC, LOGPIXELSX))
        ReleaseDC 0&, hDC
        
        If (LPX = 0) Then
            GetWinDPI = 1#
        Else
            GetWinDPI = LPX / 96#
        End If
    End Function
    nScale = GetWinDPI

    Thanks for your patience and advice
    leandroascierto.com Visual Basic 6 projects

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width