Ali*_*son 8 windows delphi winapi delphi-2009
如何检测用户何时在Windows 7中锁定/解锁屏幕?
我发现这个问题有一个C#的答案,但我想在Delphi 2009中使用它.我猜有一些Windows消息(像这些)可以完成这项工作.这是我试过的代码,但它不起作用:
const
NOTIFY_FOR_ALL_SESSIONS = 1;
{$EXTERNALSYM NOTIFY_FOR_ALL_SESSIONS}
NOTIFY_FOR_THIS_SESSION = 0;
{$EXTERNALSYM NOTIFY_FOR_THIS_SESSION}
type
TfrmAlisson = class(TForm)
lbl2: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
public
FLockedCount: Integer;
procedure WndProc(var Message: TMessage); override;
function WTSRegisterSessionNotification(hWnd: HWND; dwFlags: DWORD): bool; stdcall;
function WTSUnRegisterSessionNotification(hWND: HWND): bool; stdcall;
end;
implementation
uses
// my impl uses here
procedure TfrmAlisson.FormCreate(Sender: TObject);
begin
if (WTSRegisterSessionNotification(Handle, NOTIFY_FOR_THIS_SESSION)) then
ShowMessage('Nice')
else
begin
lastError := GetLastError;
ShowMessage(SysErrorMessage(lastError));
end;
end;
procedure TfrmAlisson.FormDestroy(Sender: TObject);
begin
WTSUnRegisterSessionNotification(Handle);
end;
procedure TfrmAlisson.WndProc(var Message: TMessage);
begin
case Message.Msg of
WM_WTSSESSION_CHANGE:
begin
if Message.wParam = WTS_SESSION_LOCK then
begin
Inc(FLockedCount);
end;
if Message.wParam = WTS_SESSION_UNLOCK then
begin
lbl2.Caption := 'Session was locked ' +
IntToStr(FLockedCount) + ' times.';
end;
end;
end;
inherited;
end;
function TfrmAlisson.WTSRegisterSessionNotification(hWnd: HWND; dwFlags: DWORD): bool;
external 'wtsapi32.dll' Name 'WTSRegisterSessionNotification';
function TfrmAlisson.WTSUnRegisterSessionNotification(hWND: HWND): bool;
external 'wtsapi32.dll' Name 'WTSUnRegisterSessionNotification';
Run Code Online (Sandbox Code Playgroud)
当FormCreate
执行时,WTSRegisterSessionNotification
返回false
最后操作系统错误返回无效参数.
Rem*_*eau 11
您的代码无效,因为您没有正确实现它.
您还没有宣布WTSRegisterSessionNotification()
和WTSUnRegisterSessionNotification()
正确.
此外,您没有考虑VCL在Form对象的生命周期中动态重新创建窗体窗口的可能性.因此,即使WTSRegisterSessionNotification()
成功,您也可能会失去注册而无法实现.
试试这个:
interface
uses
...;
type
TfrmAlisson = class(TForm)
lbl2: TLabel;
protected
procedure CreateWnd; override;
procedure DestroyWindowHandle; override;
procedure WndProc(var Message: TMessage); override;
public
LockedCount: Integer;
end;
implementation
const
NOTIFY_FOR_THIS_SESSION = $0;
NOTIFY_FOR_ALL_SESSIONS = $1;
function WTSRegisterSessionNotification(hWnd: HWND; dwFlags: DWORD): Boolean; stdcall; external 'wtsapi32.dll' name 'WTSRegisterSessionNotification';
function WTSUnRegisterSessionNotification(hWnd: HWND): Boolean; stdcall; external 'wtsapi32.dll' name 'WTSUnRegisterSessionNotification';
procedure TfrmAlisson.CreateWnd;
begin
inherited;
if not WTSRegisterSessionNotification(Handle, NOTIFY_FOR_THIS_SESSION) then
RaiseLastOSError;
end;
procedure TfrmAlisson.DestroyWindowHandle;
begin
WTSUnRegisterSessionNotification(Handle);
inherited;
end;
procedure TfrmAlisson.WndProc(var Message: TMessage);
begin
if Message.Msg = WM_WTSSESSION_CHANGE then
begin
case Message.wParam of
WTS_SESSION_LOCK: begin
Inc(LockedCount);
end;
WTS_SESSION_UNLOCK: begin
lbl2.Caption := Format('Session was locked %d times.', [LockedCount]);
end;
end;
end;
inherited;
end;
end.
Run Code Online (Sandbox Code Playgroud)
话虽这么说,考虑编写代码不依赖于VCL的窗口娱乐行为.您可以分配一个专用窗口来监视会话更改:
interface
uses
...;
type
TfrmAlisson = class(TForm)
lbl2: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
SessionWnd: HWND;
procedure SessionWndProc(var Message: TMessage);
public
LockedCount: Integer;
end;
implementation
const
NOTIFY_FOR_THIS_SESSION = $0;
NOTIFY_FOR_ALL_SESSIONS = $1;
function WTSRegisterSessionNotification(hWnd: HWND; dwFlags: DWORD): Boolean; stdcall; external 'wtsapi32.dll' name 'WTSRegisterSessionNotification';
function WTSUnRegisterSessionNotification(hWnd: HWND): Boolean; stdcall; external 'wtsapi32.dll' name 'WTSUnRegisterSessionNotification';
procedure TfrmAlisson.FormCreate(Sender: TObject);
begin
SessionWnd := AllocateHWnd(SessionWndProc);
if not WTSRegisterSessionNotification(SessionWnd, NOTIFY_FOR_THIS_SESSION) then
RaiseLastOSError;
end;
procedure TfrmAlisson.FormDestroy(Sender: TObject);
begin
if SessionWnd <> 0 then
begin
WTSUnRegisterSessionNotification(SessionWnd);
DeallocateHWnd(SessionWnd);
end;
end;
procedure TfrmAlisson.SessionWndProc(var Message: TMessage);
begin
if Message.Msg = WM_WTSSESSION_CHANGE then
begin
case Message.wParam of
WTS_SESSION_LOCK: begin
Inc(LockedCount);
end;
WTS_SESSION_UNLOCK: begin
lbl2.Caption := Format('Session was locked %d times.', [LockedCount]);
end;
end;
end;
Message.Result := DefWindowProc(SessionWnd, Message.Msg, Message.WParam, Message.LParam);
end;
end.
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1117 次 |
最近记录: |