잘못된 정보가 있다면, 꼭 댓글로 알려주세요(비로그인 익명도 가능).

여러분의 피드백이 저와 방문자 모두를 올바른 정보로 인도할 수 있습니다.

감사합니다. -현록

후원해주실 분은 여기로→

현록의 기록저장소

원클릭 해상도 변경 (주사율(Hz) 추가, 모니터 지정 추가) 본문

PC원격제어/help

원클릭 해상도 변경 (주사율(Hz) 추가, 모니터 지정 추가)

현록 2019. 5. 16. 10:49

[PC원격제어/help] - 원클릭 모니터변경 종결 (다중모니터,해상도,주사율,배율,회전,위치,...)

 

원클릭 모니터변경 종결 (다중모니터,해상도,주사율,배율,회전,위치,...)

[서론 및 소개] [사용법] [서론 및 소개] 원격 제어를 애용하면서 그동안 사용했던 모니터 설정 방법을 공유했었다. PC에 모니터를 3개나 연결해보면서 원하는 모니터 그룹만 켜두는 것이 Windows 기

ydeer.tistory.com

위 포스트에서 소개한 기능이 더 강력하므로, 위의 포스트를 추천합니다.

 

 


컴퓨터의 해상도를 클릭 한 번으로 변경하는 방법입니다.

질문 댓글이 달린 김에 백업 겸 정리해둡니다.

윈도우 타일메뉴에 다음과 같이 설치해서 언제든 가로/세로 와 해상도를 바꿀 수 있습니다.

이미지가 움직이지 않는다면, 클릭해서 보시면 됩니다.


 

우선, 존재 의의 중 하나는

데스크탑과 스마트폰과 태블릿의 해상도비가 다른 점입니다.

 

애플 제품으로 봤을 때,

데스크탑과 아이폰(스마트폰)은 16:9(1920x1080)이라면,

아이패드(태블릿)는 4:3(1280x960)입니다.

 

그래서 해상도비가 다른 기기에서 원격연결을 하게되면, 위아래에 검은 여백이 생깁니다.

그냥 이대로 사용할 때도 있지만;;

원한다면 해상도를 바꿔서 꽉찬 화면으로 쓸 수 있게 하고 있습니다.

물론 원격어플마다 자동지원이 되는 어플도 있습니다.

 

 

두번째로는, 클라이언트 기기의 가로/세로 상태가 호스트에 반영되지 않는다는 점입니다.

특히 태블릿으로 원격을 하면 세로로 길게 보고 싶을 때도 있기 마련인데,

호스트의 상태가 고정된채 위아래로 큰 여백만 생길 뿐입니다.

여기서 회전 버튼을 눌러 호스트 화면을 회전시킬 수 있습니다.

 

 


(※ 아래 과정이 난해하신 분들을 위해, 맨 아래에 Sample.zip도 첨부해둡니다.)

 

 

해상도 조절을 위해 윈도우 기본 내장 PowerShell과 cmd명령구문을 사용할겁니다.

먼저, 아래 파일을 다운 받거나,

Set-ScreenResolution.ps1
0.00MB
Set-ScreenResolution_Multi.ps1
0.01MB

(Multi는 모니터번호를 지정해야 하고, 아닌건 항상 주모니터만 바꿉니다.)

 

빈 메모장을 연 후, 아래와 같이 입력하고, UTF-8로 Set-ScreenResolution.ps1 라는 이름으로 파일을 저장합니다.

Function Set-ScreenResolution { 
param ( 
[Parameter(Mandatory=$true, 
           Position = 0)] 
[int] 
$Width, 
[Parameter(Mandatory=$true, 
           Position = 1)] 
[int] 
$Height,
[Parameter(Mandatory=$false, 
           Position = 2)] 
[int] 
$Frequency 
) 
$pinvokeCode = @" 
using System; 
using System.Runtime.InteropServices; 
namespace Resolution 
{ 
    [StructLayout(LayoutKind.Sequential)] 
    public struct DEVMODE1 
    { 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
        public string dmDeviceName; 
        public short dmSpecVersion; 
        public short dmDriverVersion; 
        public short dmSize; 
        public short dmDriverExtra; 
        public int dmFields; 
        public short dmOrientation; 
        public short dmPaperSize; 
        public short dmPaperLength; 
        public short dmPaperWidth; 
        public short dmScale; 
        public short dmCopies; 
        public short dmDefaultSource; 
        public short dmPrintQuality; 
        public short dmColor; 
        public short dmDuplex; 
        public short dmYResolution; 
        public short dmTTOption; 
        public short dmCollate; 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
        public string dmFormName; 
        public short dmLogPixels; 
        public short dmBitsPerPel; 
        public int dmPelsWidth; 
        public int dmPelsHeight; 
        public int dmDisplayFlags; 
        public int dmDisplayFrequency; 
        public int dmICMMethod; 
        public int dmICMIntent; 
        public int dmMediaType; 
        public int dmDitherType; 
        public int dmReserved1; 
        public int dmReserved2; 
        public int dmPanningWidth; 
        public int dmPanningHeight; 
    }; 
    class User_32 
    { 
        [DllImport("user32.dll")] 
        public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode); 
        [DllImport("user32.dll")] 
        public static extern int ChangeDisplaySettings(ref DEVMODE1 devMode, int flags); 
        public const int ENUM_CURRENT_SETTINGS = -1; 
        public const int CDS_UPDATEREGISTRY = 0x01; 
        public const int CDS_TEST = 0x02; 
        public const int DISP_CHANGE_SUCCESSFUL = 0; 
        public const int DISP_CHANGE_RESTART = 1; 
        public const int DISP_CHANGE_FAILED = -1; 
    } 
    public class PrmaryScreenResolution 
    { 
        static public string ChangeResolution(int width, int height, int frequency) 
        { 
            DEVMODE1 dm = GetDevMode1(); 
            if (0 != User_32.EnumDisplaySettings(null, User_32.ENUM_CURRENT_SETTINGS, ref dm)) 
            { 
                dm.dmPelsWidth = width; 
                dm.dmPelsHeight = height; 
                if (frequency > 0) {
                    dm.dmDisplayFrequency = frequency;
                    dm.dmFields = 0x580000;
                }
                else
                {
                    dm.dmFields = 0x180000;
                }
                int iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_TEST); 
                if (iRet == User_32.DISP_CHANGE_FAILED) 
                { 
                    return "Unable To Process Your Request. Sorry For This Inconvenience."; 
                } 
                else 
                { 
                    iRet = User_32.ChangeDisplaySettings(ref dm, User_32.CDS_UPDATEREGISTRY); 
                    switch (iRet) 
                    { 
                        case User_32.DISP_CHANGE_SUCCESSFUL: 
                            { 
                                return "Success"; 
                            } 
                        case User_32.DISP_CHANGE_RESTART: 
                            { 
                                return "You Need To Reboot For The Change To Happen.\n If You Feel Any Problem After Rebooting Your Machine\nThen Try To Change Resolution In Safe Mode."; 
                            } 
                        default: 
                            { 
                                return "Failed To Change The Resolution"; 
                            } 
                    } 
                } 
            } 
            else 
            { 
                return "Failed To Change The Resolution."; 
            } 
        } 
        private static DEVMODE1 GetDevMode1() 
        { 
            DEVMODE1 dm = new DEVMODE1(); 
            dm.dmDeviceName = new String(new char[32]); 
            dm.dmFormName = new String(new char[32]); 
            dm.dmSize = (short)Marshal.SizeOf(dm); 
            return dm; 
        } 
    } 
} 
"@ 
Add-Type $pinvokeCode -ErrorAction SilentlyContinue 
[Resolution.PrmaryScreenResolution]::ChangeResolution($width,$height,$frequency) 
}

(위는 모니터 번호 지정없이 주모니터만 바꾸는 버전. 위의 다운로드에서 Multi가 안 붙은.)

 

Function Set-ScreenResolution { 
param ( 
[Parameter(Mandatory=$true, 
           Position = 0)] 
[int] 
$No,
[Parameter(Mandatory=$true, 
           Position = 1)] 
[int] 
$Width, 
[Parameter(Mandatory=$true, 
           Position = 2)] 
[int] 
$Height,
[Parameter(Mandatory=$false, 
           Position = 3)] 
[int] 
$Frequency 
) 
$pinvokeCode = @" 
using System; 
using System.Runtime.InteropServices; 
namespace Resolution 
{ 
    [StructLayout(LayoutKind.Sequential)] 
    public struct DEVMODE1 
    { 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
        public string dmDeviceName; 
        public short dmSpecVersion; 
        public short dmDriverVersion; 
        public short dmSize; 
        public short dmDriverExtra; 
        public int dmFields; 
        public short dmOrientation; 
        public short dmPaperSize; 
        public short dmPaperLength; 
        public short dmPaperWidth; 
        public short dmScale; 
        public short dmCopies; 
        public short dmDefaultSource; 
        public short dmPrintQuality; 
        public short dmColor; 
        public short dmDuplex; 
        public short dmYResolution; 
        public short dmTTOption; 
        public short dmCollate; 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
        public string dmFormName; 
        public short dmLogPixels; 
        public short dmBitsPerPel; 
        public int dmPelsWidth; 
        public int dmPelsHeight; 
        public int dmDisplayFlags; 
        public int dmDisplayFrequency; 
        public int dmICMMethod; 
        public int dmICMIntent; 
        public int dmMediaType; 
        public int dmDitherType; 
        public int dmReserved1; 
        public int dmReserved2; 
        public int dmPanningWidth; 
        public int dmPanningHeight; 
    }; 
    [StructLayout(LayoutKind.Sequential)] 
    public struct DISPLAY_DEVICE 
    { 
        public int cb; 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] 
        public string DeviceName; 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
        public string DeviceString; 
        public int StateFlags; 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
        public string DeviceID; 
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] 
        public string DeviceKey; 
    }; 
    class User_32 
    { 
        [DllImport("user32.dll")] 
        public static extern int EnumDisplaySettings(string deviceName, int modeNum, ref DEVMODE1 devMode); 
        [DllImport("user32.dll")] 
        public static extern int ChangeDisplaySettingsEx(string deviceName, ref DEVMODE1 devMode, uint mustNull01, int flags, uint mustNull02);
        [DllImport("user32.dll")] 
        public static extern int EnumDisplayDevices(string lpDevice, int iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, int dwFlags); 
        public const int ENUM_CURRENT_SETTINGS = -1; 
        public const int CDS_UPDATEREGISTRY = 0x01; 
        public const int CDS_TEST = 0x02; 
        public const int DISP_CHANGE_SUCCESSFUL = 0; 
        public const int DISP_CHANGE_RESTART = 1; 
        public const int DISP_CHANGE_FAILED = -1; 
    } 
    public class ScreenResolution 
    { 
        static public string ChangeResolution(int no, int width, int height, int frequency) 
        { 
            DISPLAY_DEVICE DispDev = GetDisplayDevice(); 
            if (0 != User_32.EnumDisplayDevices(null, no, ref DispDev, 0)) 
            { 
                DEVMODE1 dm = GetDevMode1(); 
                if (0 != User_32.EnumDisplaySettings(DispDev.DeviceName, User_32.ENUM_CURRENT_SETTINGS, ref dm)) 
                { 
                    dm.dmPelsWidth = width; 
                    dm.dmPelsHeight = height; 
                    if (frequency > 0) {
                        dm.dmDisplayFrequency = frequency;
                        dm.dmFields = 0x580000;
                    }
                    else
                    {
                        dm.dmFields = 0x180000;
                    }
                    int iRet = User_32.ChangeDisplaySettingsEx(DispDev.DeviceName, ref dm, 0, User_32.CDS_TEST, 0);
                    if (iRet == User_32.DISP_CHANGE_FAILED) 
                    { 
                        return "Unable To Process Your Request. Sorry For This Inconvenience."; 
                    } 
                    else 
                    { 
                        iRet = User_32.ChangeDisplaySettingsEx(DispDev.DeviceName, ref dm, 0, User_32.CDS_UPDATEREGISTRY, 0);
                        switch (iRet) 
                        { 
                            case User_32.DISP_CHANGE_SUCCESSFUL: 
                                { 
                                    return "Success"; 
                                } 
                            case User_32.DISP_CHANGE_RESTART: 
                                { 
                                    return "You Need To Reboot For The Change To Happen.\n If You Feel Any Problem After Rebooting Your Machine\nThen Try To Change Resolution In Safe Mode."; 
                                } 
                            default: 
                                { 
                                    return "Failed To Change The Resolution"; 
                                } 
                        } 
                    } 
                } 
                else 
                { 
                    return "Failed To Change The Resolution."; 
                } 
            } 
            else 
            { 
                return "Failed To Get Monitor Device From MonitorNo"; 
            } 
        } 
        private static DEVMODE1 GetDevMode1() 
        { 
            DEVMODE1 dm = new DEVMODE1(); 
            dm.dmDeviceName = new String(new char[32]); 
            dm.dmFormName = new String(new char[32]); 
            dm.dmSize = (short)Marshal.SizeOf(dm); 
            return dm; 
        }
        private static DISPLAY_DEVICE GetDisplayDevice() 
        { 
            DISPLAY_DEVICE dv = new DISPLAY_DEVICE(); 
            dv.DeviceName = new String(new char[32]); 
            dv.DeviceString = new String(new char[128]); 
            dv.DeviceID = new String(new char[128]); 
            dv.DeviceKey = new String(new char[128]); 
            dv.cb = (int)Marshal.SizeOf(dv); 
            dv.StateFlags = 1; 
            return dv; 
        } 
    } 
} 
"@ 
Add-Type $pinvokeCode -ErrorAction SilentlyContinue 
[Resolution.ScreenResolution]::ChangeResolution($no,$width,$height,$frequency) 
}

(모니터 번호를 지정해야하지만, 원하는 모니터를 수정할 수 있는 버전. 위의 다운로드에서 Multi가 붙은.)


 

이제 원하는 해상도를 찾아봅니다.

바탕화면 우클릭 > 디스플레이 설정(D)나,

설정 > 시스템 > 디스플레이에서

가능한 해상도 목록 중 원하는 해상도들을 기록해둡니다.

설정 > 시스템 > 디스플레이

만약, 여기에서 당장 사용할 해상도가 없다면,

아래의 링크를 참고하여 해상도를 먼저 추가하시기 바랍니다.

[PC원격제어/help] - 해상도 추가하기

 

 


 

빈 메모장을 열고 아래와 같이 적습니다.

. $PSScriptRoot\Set-ScreenResolution.ps1

Set-ScreenResolution 1920 1080 144

(Multi가 아닌 버전)

맨 첫줄의 점(.) 다음에는 아까 Set-ScreenResolution.ps1 파일을 둔 경로를 적습니다.

다다음 칸에는 Set-ScreenResolution 가로크기 세로크기 주사율을 적습니다.

(주사율은 빈 칸으로 두면 특정하지 않고 해상도만으로 프로필을 찾아 변경하려고 하고,

적어주면 특정 주사율 프로필을 찾아서 변경합니다.)

. $PSScriptRoot\Set-ScreenResolution_Multi.ps1

Set-ScreenResolution 0 1920 1080 144

(Multi가 붙은, 모니터를 지정할 수 있는 버전)

위와 비교해보면, 매개변수의 가장 앞에 모니터 순서를 적습니다.

(1번 모니터가 0이고, 2번 모니터가 1... 즉, 1씩 줄이면 됩니다.)

 

이 파일을 UTF-8형식으로 원하는이름.ps1 으로 저장합니다.

예시파일도 올려둡니다.(이 파일을 메모장으로 열어서 수정해도 됩니다.)

1920_1080.ps1
0.00MB

(주모니터만 바꿀 수 있는, Multi가 아닌 버전 예시)

1920_1080_2.ps1
0.00MB

(Multi 가능 버전이고, 2번 모니터를 바꾸는 예시)

해상도별로 여러개 준비하시면 됩니다.

복붙하면서 파일명과 맨 아랫줄 가로/세로 크기만 수정하면 됩니다.

이 파일은 Set-ScreenResolution(_Multi).ps1 파일과 동일한 폴더에 함께 나란히 놓이면 됩니다.

 


 

이제 bat파일을 만들겁니다.

빈 메모장을 열고 아래와 같이 접습니다.

@echo off
Powershell.exe -noprofile -executionpolicy bypass -file 1920_1080.ps1

맨 뒤에 1920_1080.ps1 을 확인해주세요. 위에서 작성한 ps1파일의 이름과 일치해야합니다.

이것 역시 UTF-8형식으로 원하는이름.bat 로 저장합니다.

예시파일도 올려둡니다.(이 파일을 메모장으로 열어서 수정해도 됩니다.)

1920x1080.bat
0.00MB

역시 해상도별로 여러개 준비하시면 됩니다.

복붙하면서 자체 파일명과 맨 아랫줄 가리키는 파일명만 수정하면 됩니다.

이 파일은 위 ps1파일들과 동일한 폴더에 함께 나란히 놓이면 됩니다.

 


 

이제 이 bat파일을 실행하면 해상도가 바뀌게 될겁니다.

저 처럼 윈도우 타일 메뉴에 위치하게 하고 싶으시면,

C(윈도우설치드라이브):\Users\로그온한사용자\AppData\Roaming\Microsoft\Windows\Start Menu\Programs

에 바로가기를 만든 후,

모든 앱 보기를 하면 나타납니다.

 


 

그럼에도 해상도가 조절이 안되는 경우가 있는데,

그 해상도가 현재 디스플레이에서 지원하는 해상도가 아닌 경우입니다.

맨 처음 설정의 목록에서 볼 수 있는 해상도만 변경이 가능합니다.

그래서 가로/세로를 뒤집은 결과(화면이 회전된)도 이대로는 수행할 수 없습니다.

 

 

아래의 프로그램을 다운받습니다.

http://noeld.com/programs.asp#Display

(위의 개발자 개인 홈이 사라져서 여기의 Display 참고)https://download.cnet.com/developer/noel-danjou/i-70616

display.exe
0.17MB

(제가 만든 프로그램이 아니라, 안전성을 보장해드릴 순 없습니다.)

 

 

프로그램을 우클릭하여 바로가기를 2개 만듭니다.

이 바로가기를 우클릭하여 속성을 들어가셔서,

대상(T) 부분을 봅니다.

가로모드로 사용할 바로가기에는 exe뒤에 한 칸 띄운채 /rotate:0을 적어주고,

세로모드로 사용할 바로가기에는 exe뒤에 한 칸 띄운채 /rotate:90을 적어줍니다.

2번 모니터에 사용하고 싶다면, /device:2도 사이에 공백을 주면서 추가해두면 됩니다.

(/device:숫자 가 지정되어 있지 않으면 주모니터인 /device:1을 회전)

 

이제 이 바로가기를 실행하면 화면이 회전합니다.

이것도 윈도우 타일 메뉴에 위치하게 하고 싶으시면

C(윈도우설치드라이브):\Users\로그온한사용자\AppData\Roaming\Microsoft\Windows\Start Menu\Programs

에 두시면 됩니다.

 

 


회전과 해상도를 동시에 적용시키고 싶을 수 있습니다.

혹은 세로형 해상도는 반드시 세로회전이 선행되도록 한다거나...

 

이럴 땐 bat 파일을 입맛에 맞게 수정해보시기 바랍니다.

@echo off
D:\~~~\display.exe /device:2 /rotate:90
timeout 2
Powershell.exe -noprofile -executionpolicy bypass -file 960_1280.ps1

(회전상태가 확실해야 해당 해상도 변경이 제대로 이뤄지므로, 2초 기다리는 부분을 뒀습니다.)

 

원한다면 모든 모니터들을 한꺼번에 회전시키고, 해상도 변경도 가능합니다.

텍스트 크기(배율. DPI)는 주모니터만 수정할 수 있는데...

이건 이 포스트를 참고해주세요.

 

 


 

정리

 

 

[해상도 변경]

Set-ScreenResolution(_Multi).ps1 하나

가로_세로.ps1 해상도별로 여러개

가로x세로.bat 해상도별로 여러개

 

가로x세로.bat→가로_세로.ps1Set-ScreenResolution.ps1

 

 

+[화면 회전]

display.exe 하나

가로모드용 바로가기 하나

세로모드용 바로가기 하나

 

바로가기.lnk→display.exe

 

 

Sample.zip
0.09MB

(바로 사용가능한 Sample입니다.)

'PC원격제어 > help' 카테고리의 다른 글

해상도 추가하기  (1) 2020.03.15
VB-CABLE(가상 케이블)  (4) 2020.02.29
[기초설정] 기타 추천 설정  (0) 2019.04.11
[기초설정] 방화벽 포트 개방  (0) 2019.04.11
[기초설정] WOL(Wake On Lan)  (0) 2019.04.11
Comments

잘못된 정보가 있다면, 꼭 댓글로 알려주세요(비로그인 익명도 가능).

여러분의 피드백이 저와 방문자 모두를 올바른 정보로 인도할 수 있습니다.

감사합니다. -현록

후원해주실 분은 여기로→