Skip to content

Instantly share code, notes, and snippets.

@ireun
Last active April 13, 2022 10:33
Show Gist options
  • Save ireun/fc24cb66ec7b06a0be6f0fb50ce1a84f to your computer and use it in GitHub Desktop.
Save ireun/fc24cb66ec7b06a0be6f0fb50ce1a84f to your computer and use it in GitHub Desktop.

Hello

This is a program I've wrote in order to automaticly change Windows orientation, based on the information gathered from my screen ( HP Z24n G2 ), which has a built in accelerometer, and supplies this information via DDC/CI.

#include <Windows.h>
#include <iostream>
#include <lowlevelmonitorconfigurationapi.h>
#include <physicalmonitorenumerationapi.h>
#pragma comment(lib, "Dxva2.lib")
using namespace std;
BOOL CALLBACK MyInfoEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
*reinterpret_cast<HMONITOR*>(dwData) = hMonitor;
return true;
}
DWORD CheckScreenOrientation() {
HMONITOR monitorHandle = NULL; // Monitor handle
DWORD* numnerofPhysicalMonitors = new DWORD; //Needed to get physical Monitors
DWORD* currentOrinetation = new DWORD;
EnumDisplayMonitors(NULL, NULL, MyInfoEnumProc, reinterpret_cast<LPARAM>(&monitorHandle));
GetNumberOfPhysicalMonitorsFromHMONITOR(monitorHandle, numnerofPhysicalMonitors);
_PHYSICAL_MONITOR* physical_monitors = new _PHYSICAL_MONITOR[numnerofPhysicalMonitors[0]]; // Allocate array for physical monitors
if (monitorHandle != 0) {
GetPhysicalMonitorsFromHMONITOR(monitorHandle, *numnerofPhysicalMonitors, physical_monitors);
}
GetVCPFeatureAndVCPFeatureReply(physical_monitors->hPhysicalMonitor, 0xAA, NULL, currentOrinetation, NULL);
/*
Returned values ar as fallows:
00 -> Shall be ignored
01 -> Normal
02 -> 90deg clockwise
03 -> 180deg
04 -> 270deg clockwise
05 - FE -> Shall be ignored
FF -> Device doesn't support screen orientation
*/
if (currentOrinetation[0] > 4 || currentOrinetation[0] < 1) {
return 0xFF;
}
cout << "Current Orientation is: " << currentOrinetation[0] << endl;
return currentOrinetation[0];
}
void rotateDesktop(int arg) {
arg -= 1; // Adjustment for the DEVMODE structure
DEVMODE dm;
memset(&dm, 0, sizeof(dm));
dm.dmSize = sizeof(dm);
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
{
DEVMODE savemode = dm;
dm.dmDisplayOrientation = arg; // Change the value in the DEVMODE structure
// Swap height and width if they don't match the desired orientation, otherwise ChangeDisplaySetting will return DISP_CHANGE_BADPARAM
if ((arg == 0x01 || arg == 0x03) && dm.dmPelsHeight < dm.dmPelsWidth ||
(arg == 0x00 || arg == 0x02) && dm.dmPelsHeight > dm.dmPelsWidth) {
dm.dmPelsHeight ^= dm.dmPelsWidth;
dm.dmPelsWidth ^= dm.dmPelsHeight;
dm.dmPelsHeight ^= dm.dmPelsWidth;
}
LONG result = ChangeDisplaySettings(&dm, 0); // Apply the new DEVMODE to the device
if (result == DISP_CHANGE_SUCCESSFUL)
{
cout << "Screen orientation changed!" << endl;
//Add a dialog to ask the user to confirm.
//The dialog should close automatically if user is unable to confirm
//if (confirm()) return;
//Sleep(5000);
// if not, disable this feature
//ChangeDisplaySettings(&savemode, 0);
}
else
{
cout << "Error" << endl;
}
}
}
int main()
{
DWORD LastOrientation = CheckScreenOrientation();
if (LastOrientation == 0xFF) {
cout << "This screen doesn't support automatic rotation. Sorry..";
return -1;
}
while (true)
{
if (CheckScreenOrientation() != LastOrientation) { // If orientation has changed
LastOrientation = CheckScreenOrientation(); // Save new as last
rotateDesktop(LastOrientation); // Rotate the desktop to the new orientation
}
Sleep(5000); // Interval of checking
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment