检测屏幕锁定 - Win32 中的 FMX
Detect screen lock - FMX in Win32
我希望我的应用程序在屏幕锁定时 运行 一些代码(Win 7 和 10)。当用户锁定屏幕时,我的应用程序也可能在后台。
谁能给我指出正确的方向?
谢谢,
接力员
使用WTSRegisterSessionNotification()
to register an HWND
to receive WTS_SESSION_(UN)LOCK
notifications via the WM_WTSSESSION_CHANGE
window消息。
您可以在 MSDN 上使用 FMX 的 FormToHWND()
function to obtain your Form's HWND
. However, FireMonkey controls, including Forms, do not have an overridable WndProc()
method to process window messages, like VCL does, so you will have to use the Win32 API's SetWindowLongPtr()
or SetWindowSubclass()
function (see Subclassing Controls) 接收 WM_WTSSESSION_CHANGE
window 消息:
class TMyForm : public TForm
{
...
#ifdef _Windows
private:
bool MonitoringWTS;
static LRESULT CALLBACK SubclassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
protected:
virtual void __fastcall CreateHandle();
#endif
...
};
#ifdef _Windows
#include <FMX.Platform.Win.hpp>
#include <commctrl.h>
#include <wtsapi32.h>
void __fastcall TMyForm::CreateHandle()
{
MonitoringWTS = false;
TForm::CreateHandle();
// depending on which version of C++Builder you are using...
HWND hWnd = FormToHWND(this);
//HWND hWnd = WindowHandleToPlatform(Handle)->Wnd;
//HWND hWnd = FmxHandleToHWND(Handle);
if (!SetWindowSubclass(hWnd, &SubclassWndProc, 1, reinterpret_cast<DWORD_PTR>(this)))
throw Exception(_D("Could not subclass window"));
MonitoringWTS = WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_THIS_SESSION);
if (!MonitoringWTS)
RaiseLastOSError();
}
LRESULT CALLBACK TMyForm::SubclassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (uMsg)
{
case WM_NCDESTROY:
{
WTSUnRegisterSessionNotification(hWnd);
reinterpret_cast<TMyForm*>(dwRefData)->MonitoringWTS = false;
RemoveWindowSubclass(hWnd, &SubclassWndProc, uIdSubclass);
break;
}
case WM_WTSSESSION_CHANGE:
{
TMyForm *pThis = reinterpret_cast<TMyForm*>(dwRefData);
switch (wParam)
{
case WTS_SESSION_LOCK:
// do something ...
break;
case WTS_SESSION_UNLOCK:
// do something ...
break;
}
return 0;
}
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
#endif
或者,您可以使用 RTL 的 AllocateHWnd()
函数创建隐藏 HWND
并为其提供自定义 WndProc()
方法:
class TMyForm : public TForm
{
...
#ifdef _Windows
private:
HWND WndForWTS;
bool MonitoringWTS;
void __fastcall WndProcForWTS(TMessage &Message);
public:
__fastcall TMyForm(TComponent *Owner);
__fastcall ~TMyForm();
#endif
...
};
#ifdef _Windows
#include <wtsapi32.h>
__fastcall TMyForm::TMyForm(TComponent *Owner)
: TForm(Owner)
{
WndForWTS = AllocateHWnd(&WndProcForWTS);
MonitoringWTS = WTSRegisterSessionNotification(WndForWTS, NOTIFY_FOR_THIS_SESSION);
if (!MonitoringWTS)
{
int err = GetLastError();
DeallocateHWnd(WndForWTS);
RaiseLastOSError(err);
}
}
__fastcall ~TMyForm();
{
DeallocateHWnd(WndForWTS);
}
void __fastcall TMyForm::WndProcForWTS(TMessage &Message)
{
switch (Message.Msg)
{
case WM_NCDESTROY:
{
if (MonitoringWTS)
{
WTSUnRegisterSessionNotification(WndForWTS);
MonitoringWTS = false;
}
WndForWTS = NULL;
break;
}
case WM_WTSSESSION_CHANGE:
{
switch (Message.WParam)
{
case WTS_SESSION_LOCK:
// do something ...
break;
case WTS_SESSION_UNLOCK:
// do something ...
break;
}
return;
}
}
Message.Result = DefWindowProc(WndForWTS, Message.Msg, Message.WParam, Message.LParam);
}
#endif
我希望我的应用程序在屏幕锁定时 运行 一些代码(Win 7 和 10)。当用户锁定屏幕时,我的应用程序也可能在后台。
谁能给我指出正确的方向?
谢谢, 接力员
使用WTSRegisterSessionNotification()
to register an HWND
to receive WTS_SESSION_(UN)LOCK
notifications via the WM_WTSSESSION_CHANGE
window消息。
您可以在 MSDN 上使用 FMX 的 FormToHWND()
function to obtain your Form's HWND
. However, FireMonkey controls, including Forms, do not have an overridable WndProc()
method to process window messages, like VCL does, so you will have to use the Win32 API's SetWindowLongPtr()
or SetWindowSubclass()
function (see Subclassing Controls) 接收 WM_WTSSESSION_CHANGE
window 消息:
class TMyForm : public TForm
{
...
#ifdef _Windows
private:
bool MonitoringWTS;
static LRESULT CALLBACK SubclassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
protected:
virtual void __fastcall CreateHandle();
#endif
...
};
#ifdef _Windows
#include <FMX.Platform.Win.hpp>
#include <commctrl.h>
#include <wtsapi32.h>
void __fastcall TMyForm::CreateHandle()
{
MonitoringWTS = false;
TForm::CreateHandle();
// depending on which version of C++Builder you are using...
HWND hWnd = FormToHWND(this);
//HWND hWnd = WindowHandleToPlatform(Handle)->Wnd;
//HWND hWnd = FmxHandleToHWND(Handle);
if (!SetWindowSubclass(hWnd, &SubclassWndProc, 1, reinterpret_cast<DWORD_PTR>(this)))
throw Exception(_D("Could not subclass window"));
MonitoringWTS = WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_THIS_SESSION);
if (!MonitoringWTS)
RaiseLastOSError();
}
LRESULT CALLBACK TMyForm::SubclassWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
switch (uMsg)
{
case WM_NCDESTROY:
{
WTSUnRegisterSessionNotification(hWnd);
reinterpret_cast<TMyForm*>(dwRefData)->MonitoringWTS = false;
RemoveWindowSubclass(hWnd, &SubclassWndProc, uIdSubclass);
break;
}
case WM_WTSSESSION_CHANGE:
{
TMyForm *pThis = reinterpret_cast<TMyForm*>(dwRefData);
switch (wParam)
{
case WTS_SESSION_LOCK:
// do something ...
break;
case WTS_SESSION_UNLOCK:
// do something ...
break;
}
return 0;
}
}
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}
#endif
或者,您可以使用 RTL 的 AllocateHWnd()
函数创建隐藏 HWND
并为其提供自定义 WndProc()
方法:
class TMyForm : public TForm
{
...
#ifdef _Windows
private:
HWND WndForWTS;
bool MonitoringWTS;
void __fastcall WndProcForWTS(TMessage &Message);
public:
__fastcall TMyForm(TComponent *Owner);
__fastcall ~TMyForm();
#endif
...
};
#ifdef _Windows
#include <wtsapi32.h>
__fastcall TMyForm::TMyForm(TComponent *Owner)
: TForm(Owner)
{
WndForWTS = AllocateHWnd(&WndProcForWTS);
MonitoringWTS = WTSRegisterSessionNotification(WndForWTS, NOTIFY_FOR_THIS_SESSION);
if (!MonitoringWTS)
{
int err = GetLastError();
DeallocateHWnd(WndForWTS);
RaiseLastOSError(err);
}
}
__fastcall ~TMyForm();
{
DeallocateHWnd(WndForWTS);
}
void __fastcall TMyForm::WndProcForWTS(TMessage &Message)
{
switch (Message.Msg)
{
case WM_NCDESTROY:
{
if (MonitoringWTS)
{
WTSUnRegisterSessionNotification(WndForWTS);
MonitoringWTS = false;
}
WndForWTS = NULL;
break;
}
case WM_WTSSESSION_CHANGE:
{
switch (Message.WParam)
{
case WTS_SESSION_LOCK:
// do something ...
break;
case WTS_SESSION_UNLOCK:
// do something ...
break;
}
return;
}
}
Message.Result = DefWindowProc(WndForWTS, Message.Msg, Message.WParam, Message.LParam);
}
#endif