잘못된 정보가 있다면, 꼭 댓글로 알려주세요(비로그인 익명도 가능).
여러분의 피드백이 저와 방문자 모두를 올바른 정보로 인도할 수 있습니다.
감사합니다. -현록
현록의 기록저장소
원클릭 해상도 변경 (주사율(Hz) 추가, 모니터 지정 추가) 본문
[PC원격제어/help] - 원클릭 모니터변경 종결 (다중모니터,해상도,주사율,배율,회전,위치,...)
위 포스트에서 소개한 기능이 더 강력하므로, 위의 포스트를 추천합니다.
컴퓨터의 해상도를 클릭 한 번으로 변경하는 방법입니다.
질문 댓글이 달린 김에 백업 겸 정리해둡니다.
윈도우 타일메뉴에 다음과 같이 설치해서 언제든 가로/세로 와 해상도를 바꿀 수 있습니다.
우선, 존재 의의 중 하나는
데스크탑과 스마트폰과 태블릿의 해상도비가 다른 점입니다.
애플 제품으로 봤을 때,
데스크탑과 아이폰(스마트폰)은 16:9(1920x1080)이라면,
아이패드(태블릿)는 4:3(1280x960)입니다.
그래서 해상도비가 다른 기기에서 원격연결을 하게되면, 위아래에 검은 여백이 생깁니다.
그냥 이대로 사용할 때도 있지만;;
원한다면 해상도를 바꿔서 꽉찬 화면으로 쓸 수 있게 하고 있습니다.
물론 원격어플마다 자동지원이 되는 어플도 있습니다.
두번째로는, 클라이언트 기기의 가로/세로 상태가 호스트에 반영되지 않는다는 점입니다.
특히 태블릿으로 원격을 하면 세로로 길게 보고 싶을 때도 있기 마련인데,
호스트의 상태가 고정된채 위아래로 큰 여백만 생길 뿐입니다.
여기서 회전 버튼을 눌러 호스트 화면을 회전시킬 수 있습니다.
(※ 아래 과정이 난해하신 분들을 위해, 맨 아래에 Sample.zip도 첨부해둡니다.)
해상도 조절을 위해 윈도우 기본 내장 PowerShell과 cmd명령구문을 사용할겁니다.
먼저, 아래 파일을 다운 받거나,
(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)나,
설정 > 시스템 > 디스플레이에서
가능한 해상도 목록 중 원하는 해상도들을 기록해둡니다.
만약, 여기에서 당장 사용할 해상도가 없다면,
아래의 링크를 참고하여 해상도를 먼저 추가하시기 바랍니다.
빈 메모장을 열고 아래와 같이 적습니다.
. $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 으로 저장합니다.
예시파일도 올려둡니다.(이 파일을 메모장으로 열어서 수정해도 됩니다.)
(주모니터만 바꿀 수 있는, Multi가 아닌 버전 예시)
(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 로 저장합니다.
예시파일도 올려둡니다.(이 파일을 메모장으로 열어서 수정해도 됩니다.)
역시 해상도별로 여러개 준비하시면 됩니다.
복붙하면서 자체 파일명과 맨 아랫줄 가리키는 파일명만 수정하면 됩니다.
이 파일은 위 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
(제가 만든 프로그램이 아니라, 안전성을 보장해드릴 순 없습니다.)
프로그램을 우클릭하여 바로가기를 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→가로_세로.ps1→Set-ScreenResolution.ps1
+[화면 회전]
display.exe 하나
가로모드용 바로가기 하나
세로모드용 바로가기 하나
바로가기.lnk→display.exe
(바로 사용가능한 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 |
잘못된 정보가 있다면, 꼭 댓글로 알려주세요(비로그인 익명도 가능).
여러분의 피드백이 저와 방문자 모두를 올바른 정보로 인도할 수 있습니다.
감사합니다. -현록