In an application I wrote a few years back I use function SystemParametersInfo with SPI_GETPOWEROFFTIMEOUT to get the timeout for monitor off. On Vista this doesn't work anymore.
So I decided to make this work on Vista, but after a few hours I feel like I'm no closer to a solution.
Most of the functions I am going to mention are described on http://msdn.microsoft.com/en-us/library/aa373163(VS.85).aspx
To my understanding I should: 1. use function PowerGetActiveScheme, to get current scheme 2. use PowerEnumerate with GUID_VIDEO_SUBGROUP 3. use PowerReadACValue (or DC value) to get the value.
Is this right? Seems like a lot of work to get to one setting. If this is the correct way, there is one thing I don't understand. On my system PowerEnumerate returns 3 keys. How do I know which one is for Monitor timeout?
Here is my code so far. I'm having trouble with PowerReadACValue, I probably didn't define or use it properly.
class Program
{
[DllImport("powrprof.dll")]
static extern UInt32 PowerGetActiveScheme(IntPtr UserRootPowerKey, ref IntPtr ActivePolicyGuid);
[DllImport("powrprof.dll")]
static extern uint PowerEnumerate(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
Guid SubGroupOfPowerSettingGuid,
UInt32 AcessFlags,
UInt32 Index,
ref Guid Buffer,
ref UInt32 BufferSize);
[DllImport("powrprof.dll")]
static extern uint PowerReadACValue(
IntPtr RootPowerKey,
IntPtr SchemeGuid,
IntPtr SubGroupOfPowerSettingGuid,
Guid PowerSettingGuid,
ref IntPtr Type,
ref IntPtr Buffer,
ref UInt32 BufferSize);
static void Main(string[] args)
{
IntPtr activeGuidPtr = IntPtr.Zero;
uint res = PowerGetActiveScheme(IntPtr.Zero, ref activeGuidPtr);
if (res == 0)
{
Guid VideoSettingGuid = new Guid();
UInt32 index = 0;
UInt32 BufferSize = (UInt32)Marshal.SizeOf(typeof(Guid));
while (0 == PowerEnumerate(
IntPtr.Zero, activeGuidPtr, new Guid("7516b95f-f776-4464-8c53-06167f40cc99"), 18, index, ref VideoSettingGuid, ref BufferSize))
{
Console.Write(VideoSettingGuid.ToString() + ": ");
UInt32 size = 1024;
IntPtr temp = Marshal.AllocHGlobal(1024);
IntPtr type = IntPtr.Zero;
PowerReadACValue(IntPtr.Zero, activeGuidPtr, IntPtr.Zero, VideoSettingGuid, ref type, ref temp, ref size);
Console.Write(Marshal.PtrToStringUni(temp));
Marshal.FreeHGlobal(temp);
index++;
}
}
}
}
I also tried using GetActivePwrScheme and then ReadPwrScheme, but it doesn't seem to work either. GetActivePwrScheme always returns 0, even if I switch power schemes. I also tried running ReadPwrScheme with incremental values (1,2,3). I got to 5 or 6 but it never returned the correct number for the value I set for monitor timeout in control panel.
I hope I have this totally wrong and there is a much easier way of doing this.