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; | |
} |