Link to home
Start Free TrialLog in
Avatar of SteveWaite
SteveWaite

asked on

Anyone implemented WM_POWERBROADCAST

I want to detect the system about to go into powersave/hibernate then abort if required.
MSDN docs say detect WM_POWERBROADCAST and send BROADCAST_QUERY_DENY to abort.

I was trying to do something like:

private
  procedure WMPowerBroadcast(var Msg: TMessage);
    message WM_POWERBROADCAST;

implementation
procedure TForm.WMPowerBroadcast(var Msg: TMessage);
begin
  case Msg.wParam of
    PBT_APMQUERYSUSPEND: dosomething;
    PBT_APMSUSPEND: dosomethingelse;
    etc: ..;
  end;
end;

I think delphi only has the message declerations.

Has anyone implemented this?
300 point A grade waiting to be snapped up.....

Regards,
Steve





Avatar of AvonWyss
AvonWyss
Flag of Switzerland image

Just for the record, the documentation says:


WM_POWERBROADCAST  
The WM_POWERBROADCAST message is sent to an application to notify it of power-management events.

dwPowerEvent = (DWORD) wParam;
dwData = (DWORD) lParam;

Parameters
dwPowerEvent
Event notification message. This parameter can be one of the following values:
Value
 Meaning
 
PBT_APMBATTERYLOW
 Battery power is low.
 
PBT_APMOEMEVENT
 OEM-defined event occurred.
 
PBT_APMPOWERSTATUSCHANGE
 Power status has changed.
 
PBT_APMQUERYSUSPEND
 Request for permission to suspend.
 
PBT_APMQUERYSUSPENDFAILED
 Suspension request denied.
 
PBT_APMRESUMECRITICAL
 Operation resuming after critical suspension.
 
PBT_APMRESUMESUSPEND
 Operation resuming after suspension.
 
PBT_APMSUSPEND
 System is suspending operation.
 

dwData
Function-specific data. For most messages, this parameter is reserved and not used.
However, if wParam is one of the resume notifications (PBT_APMRESUME*), the lParam parameter can specify the PBTF_APMRESUMEFROMFAILURE flag. This flag indicates that a suspend operation failed after the PBT_APMSUSPEND message was sent.

Return Values
Return TRUE to grant a request.

Return BROADCAST_QUERY_DENY to deny a request.


Therefore, to always deny, implement it like this:

procedure TForm.WMPowerBroadcast(var Msg: TMessage);
begin
  Msg.Result:=BROADCAST_QUERY_DENY;
end;

To allow it, set Msg.Result:=-1;

If this doesn't answer your question, please clarify the problem.
Avatar of SteveWaite
SteveWaite

ASKER

Many thanks,

but how do I get something like this working..

procedure TForm.WMPowerBroadcast(var Msg: TMessage);
begin
  case Msg.dwPowerEvent of
    PBT_APMSUSPEND: Msg.Result := BROADCAST_QUERY_DENY;
  end;
end;

Msg.Result := BROADCAST_QUERY_DENY; is fine but
case Msg.dwPowerEvent of
    PBT_APMSUSPEND:
is no good

Msg does not have dwPowerEvent and I cannot find a specific structure for WM_PowerBroadcast

Regards,
Steve
i was unsure of this question as to what exactly was wrong so did a test.i just tried this on my laptop ,it works perfectly,when i press the suspend button on laptop it didnt suspend and i get message 'stopped suspend powerstate' :

is it not working for you?


 procedure WMPowerBroadcast(var Msg: TMessage);
 message WM_POWERBROADCAST;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

const
  PBT_APMQUERYSUSPEND       = $0000;
  PBT_APMSUSPEND            = $0004;
 
procedure TForm1.WMPowerBroadcast(var Msg: TMessage);
begin
 case Msg.wParam of
   PBT_APMQUERYSUSPEND:
        begin
        Msg.Result:=BROADCAST_QUERY_DENY;
        Showmessage('stopped suspend powerstate');
        end;
   PBT_APMSUSPEND:
    begin
     Showmessage('shouldnt get here');
    end;
   end;
end;
Thanks inthe.

SteveWaite, as you can see in the doc excerpt I posted, the dwPowerEvent is the same as wParam in the TMessage record. Actually, you could design your own TMessage-like record defining the dwPowerEvent and dwData members, but this is not a requirement for it to work at all. In fact, the compiler will even generate identical code.
I'm sorry the question is a bit vague but I just don't know the values that inthe has kindly donated two of, namely:

const
 PBT_APMQUERYSUSPEND       = $0000;
 PBT_APMSUSPEND            = $0004;

As I suspected and pointed out in my question, Delphi has a declaration for WM_POWERBROADCAST but not for the wParam values.

AvonWyss, i'm afraid your answer leaves me asking my original question!! Many thanks for your help though!

Therefore I must award the points to inthe.
As this is for 300 points and a grade A, to finish the answer, inthe, can you post the other declarations too:
as in the values for:
PBT_APMBATTERYLOW Battery power is low.
PBT_APMOEMEVENT OEM-defined event occurred.
PBT_APMPOWERSTATUSCHANGE Power status has changed.
PBT_APMQUERYSUSPENDFAILED Suspension request denied.
PBT_APMRESUMEAUTOMATIC Operation resuming automatically after event.
PBT_APMRESUMECRITICAL Operation resuming after critical suspension.
PBT_APMRESUMESUSPEND Operation resuming after suspension.

As I often come across missing declarations, If I may, could you tell me how I find them myself in future.

Regards,
Steve
ASKER CERTIFIED SOLUTION
Avatar of inthe
inthe

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
>>oh and where to find them

well i have the platformsdk (you can download from microisoft or they can send it you on cd for a fee)and msdn libs etc so i can just check the relevent header file Pbt.h and get consts:

#define PBT_APMQUERYSUSPEND             0x0000
#define PBT_APMQUERYSTANDBY             0x0001
#define PBT_APMQUERYSUSPENDFAILED       0x0002
#define PBT_APMQUERYSTANDBYFAILED       0x0003
#define PBT_APMSUSPEND                  0x0004
#define PBT_APMSTANDBY                  0x0005
#define PBT_APMRESUMECRITICAL           0x0006
#define PBT_APMRESUMESUSPEND            0x0007
#define PBT_APMRESUMESTANDBY            0x0008
#define PBTF_APMRESUMEFROMFAILURE       0x00000001
#define PBT_APMBATTERYLOW               0x0009
#define PBT_APMPOWERSTATUSCHANGE        0x000A
#define PBT_APMOEMEVENT                 0x000B
#define PBT_APMRESUMEAUTOMATIC          0x0012
Many thanks inthe.

Gratitude also to AvonWyss, so go here:
https://www.experts-exchange.com/jsp/qManageQuestion.jsp?ta=delphi&qid=20273064
to collect some points for your help also.

Regards,
Steve