This code (compiled under Delphi 7) works nice under XP and Win7:
var
_SetSuspendState: function (Hibernate, ForceCritical, DisableWakeEvent: BOOL): BOOL stdcall;
// Hibernate: SetSuspendState(True , False, False);
// Standby : SetSuspendState(False, False, False);
function SetSuspendState(Hibernate, ForceCritical, DisableWakeEvent: Boolean): Boolean;
function LinkAPI(const module, functionname: string): Pointer;
...
function LinkAPI(const module, functionname: string): Pointer;
var
hLib: HMODULE;
begin
hLib := GetModulehandle(PChar(module));
if hLib = 0 then
hLib := LoadLibrary(PChar(module));
if hLib <> 0 then
Result := getProcAddress(hLib, PChar(functionname))
else
Result := nil;
end;
function SetSuspendState(Hibernate, ForceCritical, DisableWakeEvent: Boolean): Boolean;
begin
if not Assigned(_SetSuspendState) then
@_SetSuspendState := LinkAPI('POWRPROF.dll', 'SetSuspendState');
if Assigned(_SetSuspendState) then
Result := _SetSuspendState(Hibernate, ForceCritical, DisableWakeEvent)
else
Result := False;
end;
But how do I make it work under Windows 10, too?
If I test it on a Win10 TabletPC (by calling: SetSuspendState(False, False, False);
the device is shutting down completely.
Update2:
Tried to send a virtual "Sleep" button press too:
const
VK_SLEEP = $5F;
begin
keybd_event(VK_SLEEP, 0, 0, 0);
Application.ProcessMessages;
keybd_event(VK_SLEEP, 0, KEYEVENTF_KEYUP, 0);
Application.ProcessMessages;
But the application's OnKeyDown event could not catch it, like it was never sent.
Update3:
After thorough investigation of the problem during last days I've realized following things:
Summarized:
So my first code is basically affected by Power-configurations and problems of Win10 drivers and OS.
That's why I think the only solution would be to circumvent the whole problem by simply simulating a "Keyboard-SLEEP-KEY-PRESS" (as I've tried at 'Update2').
Found the same conclusions at this topic:
programmatically-enter-connected-standby-in-c-sharp
Solution is to send a monitor-turn-off signal:
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, 2);