Detect screen lock - FMX in Win32

只愿长相守 提交于 2019-12-01 14:07:57

Use WTSRegisterSessionNotification() to register an HWND to receive WTS_SESSION_(UN)LOCK notifications via the WM_WTSSESSION_CHANGE window message.

You can use FMX's 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 on MSDN) to receive the WM_WTSSESSION_CHANGE window message:

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

Alternatively, you can use the RTL's AllocateHWnd() function to create a hidden HWND and provide it with a custom WndProc() method:

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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!