Detecting that Windows is idle is the hardest part
Actually it is very easy. You can use GetLastInputInfo function. This is snippet from a program that I created that does exactly that:
unsigned idle_time;
// get idle time
LASTINPUTINFO last_input_info;
DWORD this_time;
last_input_info.cbSize = sizeof(LASTINPUTINFO);
GetLastInputInfo(&last_input_info);
#pragma warning(suppress: 28159) // Consider using GetTickCount64() instead
this_time = GetTickCount();
idle_time = this_time - last_input_info.dwTime;
Note that this is not event-based. You should put this in a loop and use Sleep to check the idle time from time to time, depending on how often you need. From what you describe, something like every few seconds should be OK.