Attribute VB_Name = "modScreenRes"
' ----------------------------------------------------------------------------
'  Copyright (C) 2009 Noda (Yohan Lasorsa) - http://nodadev.wordpress.com
' ----------------------------------------------------------------------------
'  This software Is provided 'as-is', without any express or implied
'  warranty. In no event will the author be held liable for any damages
'  arising from the use of this software.
'
'  Permission is granted to anyone to use this software for any purpose,
'  including commercial applications, and to alter it and redistribute it
'  freely, subject to the following restrictions:
'
'  1. The origin of this software must not be misrepresented; you must not
'     claim that you wrote the original software. If you use this software
'     in a product, an acknowledgment in the product documentation would be
'     appreciated but is not required.
'  2. Altered source versions must be plainly marked as such, and must not be
'     misrepresented as being the original software.
'  3. This notice may not be removed or altered from any source distribution.
' ----------------------------------------------------------------------------

Option Explicit

Private Declare Function EnumDisplaySettings Lib "user32" Alias "EnumDisplaySettingsA" _
   (ByVal lpszDeviceName As Long, ByVal iModeNum As Long, lpDevMode As Any) As Boolean

Private Declare Function ChangeDisplaySettings Lib "user32" Alias "ChangeDisplaySettingsA" _
   (lpDevMode As Any, ByVal dwFlags As Long) As Long

Private Const CCHDEVICENAME = 32
Private Const CCHFORMNAME = 32
Private Const CDS_UPDATEREGISTRY = &H1
Private Const CDS_TEST = &H2
Private Const DISP_CHANGE_SUCCESSFUL = 0
Private Const DISP_CHANGE_RESTART = 1
Private Const DM_WIDTH = &H80000
Private Const DM_HEIGHT = &H100000

Private Const INTEL_REG_PATH As String = "System\CurrentControlSet\Services\ialm\Device0"

Private Type DEVMODE
    dmDeviceName As String * CCHDEVICENAME
    dmSpecVersion As Integer
    dmDriverVersion As Integer
    dmSize As Integer
    dmDriverExtra As Integer
    dmFields As Long
    dmOrientation As Integer
    dmPaperSize As Integer
    dmPaperLength As Integer
    dmPaperWidth As Integer
    dmScale As Integer
    dmCopies As Integer
    dmDefaultSource As Integer
    dmPrintQuality As Integer
    dmColor As Integer
    dmDuplex As Integer
    dmYResolution As Integer
    dmTTOption As Integer
    dmCollate As Integer
    dmFormName As String * CCHFORMNAME
    dmUnusedPadding As Integer
    dmBitsPerPel As Integer
    dmPelsWidth As Long
    dmPelsHeight As Long
    dmDisplayFlags As Long
    dmDisplayFrequency As Long
End Type

'Public downscalingEnabled As Boolean
Public modeCustom As Boolean

Public Sub InitVideoRegHack()
    If (RegDoesKeyExist(HKEY_LOCAL_MACHINE, INTEL_REG_PATH)) Then
        RegCreateKeyValue HKEY_LOCAL_MACHINE, INTEL_REG_PATH, "PruningMode", 0
        RegCreateKeyValue HKEY_LOCAL_MACHINE, INTEL_REG_PATH, "Display1_DownScalingSupported", 1
        
        If (CLng(RegQueryKey(HKEY_LOCAL_MACHINE, INTEL_REG_PATH, "Display1_DownScalingEnabled")) = &H1) Then
            settings.downscaling = True
        End If
    End If
End Sub

Public Sub SetDownscaling(bEnabled As Boolean)
    Dim val As Long
    If (RegDoesKeyExist(HKEY_LOCAL_MACHINE, INTEL_REG_PATH)) Then
        If (bEnabled) Then
            val = &H1
        Else
            val = &H0
        End If
        RegCreate4BytesBinaryKeyValue HKEY_LOCAL_MACHINE, INTEL_REG_PATH, "Display1_DownScalingEnabled", val
        settings.downscaling = bEnabled
        If (modeCustom) Then
            ChangeScreenRes 1024, 600
            Sleep 100
            ChangeScreenRes settings.resolutionWidth, settings.resolutionHeight
        End If
    End If
End Sub

Public Sub ChangeScreenRes(sgWidth As Long, sgHeight As Long)
    Dim valid As Boolean
    Dim id As Long
    Dim result As Long
    Dim dmScreen As DEVMODE
    
    If ((sgWidth = settings.resolutionWidth) And (sgHeight = settings.resolutionHeight)) Then
        modeCustom = True
    Else
        modeCustom = False
    End If

    id = 0
    Do
        valid = EnumDisplaySettings(0, id, dmScreen)
        id = id + 1
    Loop While valid <> 0
    
    With dmScreen
        .dmFields = DM_WIDTH Or DM_HEIGHT
        .dmPelsWidth = sgWidth
        .dmPelsHeight = sgHeight
    End With
    
    result = ChangeDisplaySettings(dmScreen, CDS_TEST)
    Select Case result
        Case DISP_CHANGE_RESTART
            MsgBox "Can't change resolution", vbSystemModal, "Error"
        Case DISP_CHANGE_SUCCESSFUL
            Call ChangeDisplaySettings(dmScreen, CDS_UPDATEREGISTRY)
'        Case Else
'            MsgBox "Screen mode not supported", vbSystemModal, "Error"
    End Select
End Sub

Public Function GetScreenResX() As Long
    GetScreenResX = Screen.Width / Screen.TwipsPerPixelX
End Function

Public Function GetScreenResY() As Long
    GetScreenResY = Screen.Height / Screen.TwipsPerPixelY
End Function
