views:

962

answers:

2

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.

A: 

I think they are discontinued in VISTA,

You need to write Power-Aware Application using WM_POWERBROADCAST

as given in

http://msdn.microsoft.com/en-us/library/ms700612(VS.85).aspx

and

http://msdn.microsoft.com/en-us/library/ms703398(VS.85).aspx

concept of sample application is available in codeproject, But you need to re-program to get your values,

lakshmanaraj
I actually would like to get to a setting, not receive power events. I assume I would receive event when a user would change monitor timeout setting? Thanks for the codeproject link though, I will take a look at it and hopefully I might get another idea how to get to this setting.
mr_eko
Yes, you will receive events based on the user changes.. and also go through code project link, You will get idea to implement.
lakshmanaraj
+1  A: 

I finally did have some luck and found a function which works on both XP and Vista - GetCurrentPowerPolicies. It is very simple to call and returns a lot of the current settings including the setting I wanted VideoTimeoutAc and VideoTimeoutDc.

mr_eko