Add wxTopLevelWindow::SetContentProtection()
This method allows to exclude a top level window from screen captures. Windows 7 or newer is required and any macOS version is supported. Other platforms are not implemented and will return false. The display example has been extended to demo this ability. Closes #22066.
This commit is contained in:
committed by
Vadim Zeitlin
parent
f172f53ac4
commit
0a7b3bb3cf
@@ -398,6 +398,18 @@
|
||||
|
||||
#ifndef MUI_LANGUAGE_NAME
|
||||
#define MUI_LANGUAGE_NAME 0x8
|
||||
#endif
|
||||
|
||||
#ifndef WDA_NONE
|
||||
#define WDA_NONE 0x0
|
||||
#endif
|
||||
|
||||
#ifndef WDA_MONITOR
|
||||
#define WDA_MONITOR 0x1
|
||||
#endif
|
||||
|
||||
#ifndef WDA_EXCLUDEFROMCAPTURE
|
||||
#define WDA_EXCLUDEFROMCAPTURE 0x11
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -68,6 +68,9 @@ public:
|
||||
virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL) wxOVERRIDE;
|
||||
virtual bool IsFullScreen() const wxOVERRIDE { return m_fsIsShowing; }
|
||||
|
||||
virtual wxContentProtection GetContentProtection() const wxOVERRIDE;
|
||||
virtual bool SetContentProtection(wxContentProtection contentProtection) wxOVERRIDE;
|
||||
|
||||
// wxMSW only: EnableCloseButton(false) may be used to remove the "Close"
|
||||
// button from the title bar
|
||||
virtual bool EnableCloseButton(bool enable = true) wxOVERRIDE;
|
||||
|
||||
@@ -297,6 +297,9 @@ public :
|
||||
|
||||
virtual void SetTitle( const wxString& title, wxFontEncoding encoding ) wxOVERRIDE;
|
||||
|
||||
virtual wxContentProtection GetContentProtection() const wxOVERRIDE;
|
||||
virtual bool SetContentProtection(wxContentProtection contentProtection) wxOVERRIDE;
|
||||
|
||||
virtual bool EnableCloseButton(bool enable) wxOVERRIDE;
|
||||
virtual bool EnableMaximizeButton(bool enable) wxOVERRIDE;
|
||||
virtual bool EnableMinimizeButton(bool enable) wxOVERRIDE;
|
||||
|
||||
@@ -76,6 +76,7 @@ WXDLLIMPEXP_BASE CFURLRef wxOSXCreateURLFromFileSystemPath( const wxString& path
|
||||
|
||||
#include "wx/bmpbndl.h"
|
||||
#include "wx/window.h"
|
||||
#include "wx/toplevel.h"
|
||||
|
||||
class wxTextProofOptions;
|
||||
|
||||
@@ -965,6 +966,9 @@ public :
|
||||
|
||||
virtual bool ShowFullScreen(bool show, long style)= 0;
|
||||
|
||||
virtual wxContentProtection GetContentProtection() const = 0;
|
||||
virtual bool SetContentProtection(wxContentProtection contentProtection) = 0;
|
||||
|
||||
virtual void RequestUserAttention(int flags) = 0;
|
||||
|
||||
virtual void ScreenToWindow( int *x, int *y ) = 0;
|
||||
|
||||
@@ -184,6 +184,11 @@ public :
|
||||
|
||||
virtual bool ShowFullScreen(bool show, long style);
|
||||
|
||||
virtual wxContentProtection GetContentProtection() const wxOVERRIDE
|
||||
{ return wxCONTENT_PROTECTION_NONE; }
|
||||
virtual bool SetContentProtection(wxContentProtection contentProtection) wxOVERRIDE
|
||||
{ return false; }
|
||||
|
||||
virtual void RequestUserAttention(int flags);
|
||||
|
||||
virtual void ScreenToWindow( int *x, int *y );
|
||||
|
||||
@@ -68,6 +68,9 @@ public:
|
||||
virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL) wxOVERRIDE;
|
||||
virtual bool IsFullScreen() const wxOVERRIDE;
|
||||
|
||||
virtual wxContentProtection GetContentProtection() const wxOVERRIDE;
|
||||
virtual bool SetContentProtection(wxContentProtection contentProtection) wxOVERRIDE;
|
||||
|
||||
// implementation from now on
|
||||
// --------------------------
|
||||
|
||||
|
||||
@@ -119,6 +119,13 @@ enum
|
||||
wxUSER_ATTENTION_ERROR = 2
|
||||
};
|
||||
|
||||
// Values for Get/SetContentProtection
|
||||
enum wxContentProtection
|
||||
{
|
||||
wxCONTENT_PROTECTION_NONE,
|
||||
wxCONTENT_PROTECTION_ENABLED
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxTopLevelWindow: a top level (as opposed to child) window
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -181,6 +188,11 @@ public:
|
||||
// return true if the frame is in fullscreen mode
|
||||
virtual bool IsFullScreen() const = 0;
|
||||
|
||||
virtual wxContentProtection GetContentProtection() const
|
||||
{ return wxCONTENT_PROTECTION_NONE; }
|
||||
virtual bool SetContentProtection(wxContentProtection WXUNUSED(contentProtection))
|
||||
{ return false; }
|
||||
|
||||
// the title of the top level window: the text which the
|
||||
// window shows usually at the top of the frame/dialog in dedicated bar
|
||||
virtual void SetTitle(const wxString& title) = 0;
|
||||
|
||||
@@ -14,6 +14,13 @@ enum
|
||||
wxUSER_ATTENTION_ERROR = 2 ///< Results in a more drastic action.
|
||||
};
|
||||
|
||||
// Values for wxTopLevelWindow::GetContentProtection() and wxTopLevelWindow::SetContentProtection()
|
||||
enum wxContentProtection
|
||||
{
|
||||
wxCONTENT_PROTECTION_NONE, ///< Window contents are visible in screen captures
|
||||
wxCONTENT_PROTECTION_ENABLED ///< Window contents are not visible in screen captures
|
||||
};
|
||||
|
||||
/**
|
||||
Styles used with wxTopLevelWindow::ShowFullScreen().
|
||||
*/
|
||||
@@ -682,6 +689,39 @@ public:
|
||||
*/
|
||||
virtual bool ShowFullScreen(bool show, long style = wxFULLSCREEN_ALL);
|
||||
|
||||
/**
|
||||
Get the current content protection of the window.
|
||||
|
||||
@see SetContentProtection()
|
||||
|
||||
@since 3.1.6
|
||||
*/
|
||||
virtual wxContentProtection GetContentProtection() const;
|
||||
|
||||
/**
|
||||
Set content protection for the window.
|
||||
|
||||
When content protection is enabled contents of this window will not
|
||||
be included in screen captures.
|
||||
|
||||
Obviously this can't provide absolute security as there might be
|
||||
workarounds and tools that bypass this protection. Additionally a
|
||||
screen could always be photographed.
|
||||
|
||||
@return @true if the content protection was changed, @false if running
|
||||
under an unsupported OS.
|
||||
|
||||
@note Windows 7 or newer is required but any macOS version is supported.
|
||||
|
||||
@onlyfor{wxmsw,wxosx}
|
||||
|
||||
@see GetContentProtection()
|
||||
|
||||
@since 3.1.6
|
||||
*/
|
||||
virtual bool SetContentProtection(wxContentProtection contentProtection);
|
||||
|
||||
|
||||
/**
|
||||
This method is specific to wxUniversal port.
|
||||
|
||||
|
||||
@@ -67,6 +67,7 @@ public:
|
||||
void OnQuit(wxCommandEvent& event);
|
||||
void OnFromPoint(wxCommandEvent& event);
|
||||
void OnFullScreen(wxCommandEvent& event);
|
||||
void OnContentProtection(wxCommandEvent& event);
|
||||
void OnAbout(wxCommandEvent& event);
|
||||
|
||||
#if wxUSE_DISPLAY
|
||||
@@ -115,6 +116,8 @@ enum
|
||||
// menu items
|
||||
Display_FromPoint = wxID_HIGHEST + 1,
|
||||
Display_FullScreen,
|
||||
Display_ContentProtection_None,
|
||||
Display_ContentProtection_Enable,
|
||||
|
||||
// controls
|
||||
Display_ChangeMode,
|
||||
@@ -140,6 +143,8 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
|
||||
EVT_MENU(Display_Quit, MyFrame::OnQuit)
|
||||
EVT_MENU(Display_FromPoint, MyFrame::OnFromPoint)
|
||||
EVT_MENU(Display_FullScreen, MyFrame::OnFullScreen)
|
||||
EVT_MENU(Display_ContentProtection_None, MyFrame::OnContentProtection)
|
||||
EVT_MENU(Display_ContentProtection_Enable, MyFrame::OnContentProtection)
|
||||
EVT_MENU(Display_About, MyFrame::OnAbout)
|
||||
|
||||
#if wxUSE_DISPLAY
|
||||
@@ -210,6 +215,13 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
|
||||
itemFullScreen->SetBitmap(
|
||||
wxArtProvider::GetBitmap(wxART_FULL_SCREEN, wxART_MENU)
|
||||
);
|
||||
|
||||
wxMenu* contentProtectionMenu = new wxMenu();
|
||||
contentProtectionMenu->Append(Display_ContentProtection_None, _("&None"), "", wxITEM_RADIO);
|
||||
contentProtectionMenu->Check(Display_ContentProtection_None, true);
|
||||
contentProtectionMenu->Append(Display_ContentProtection_Enable, _("&Enabled"), "", wxITEM_RADIO);
|
||||
menuDisplay->Append(wxID_ANY, _("Content &Protection"), contentProtectionMenu);
|
||||
|
||||
menuDisplay->Append(itemFullScreen);
|
||||
menuDisplay->AppendSeparator();
|
||||
menuDisplay->Append(Display_Quit, _("E&xit\tAlt-X"), _("Quit this program"));
|
||||
@@ -406,6 +418,34 @@ void MyFrame::OnFullScreen(wxCommandEvent& WXUNUSED(event))
|
||||
ShowFullScreen(!IsFullScreen());
|
||||
}
|
||||
|
||||
void MyFrame::OnContentProtection(wxCommandEvent& event)
|
||||
{
|
||||
wxContentProtection contentProtection;
|
||||
switch (event.GetId())
|
||||
{
|
||||
case Display_ContentProtection_Enable:
|
||||
contentProtection = wxCONTENT_PROTECTION_ENABLED;
|
||||
break;
|
||||
default:
|
||||
contentProtection = wxCONTENT_PROTECTION_NONE;
|
||||
}
|
||||
|
||||
if (SetContentProtection(contentProtection))
|
||||
{
|
||||
switch (GetContentProtection())
|
||||
{
|
||||
case wxCONTENT_PROTECTION_ENABLED:
|
||||
wxLogInfo("The contents of this window should now NOT be visible in screen captures.");
|
||||
break;
|
||||
case wxCONTENT_PROTECTION_NONE:
|
||||
wxLogInfo("The contents of this window should now be visible in screen captures.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
wxLogError("Content protection could not be changed");
|
||||
}
|
||||
|
||||
#if wxUSE_DISPLAY
|
||||
|
||||
void MyFrame::OnChangeMode(wxCommandEvent& event)
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "wx/module.h"
|
||||
#endif //WX_PRECOMP
|
||||
|
||||
#include "wx/dynlib.h"
|
||||
#include "wx/scopeguard.h"
|
||||
#include "wx/tooltip.h"
|
||||
|
||||
@@ -1048,6 +1049,47 @@ void wxTopLevelWindowMSW::SetIcons(const wxIconBundle& icons)
|
||||
DoSelectAndSetIcon(icons, SM_CXICON, SM_CYICON, ICON_BIG);
|
||||
}
|
||||
|
||||
wxContentProtection wxTopLevelWindowMSW::GetContentProtection() const
|
||||
{
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
typedef BOOL(WINAPI *GetWindowDisplayAffinity_t)(HWND, DWORD *);
|
||||
|
||||
wxDynamicLibrary dllUser32("user32.dll");
|
||||
GetWindowDisplayAffinity_t pfnGetWindowDisplayAffinity =
|
||||
(GetWindowDisplayAffinity_t)dllUser32.RawGetSymbol("GetWindowDisplayAffinity");
|
||||
if (pfnGetWindowDisplayAffinity)
|
||||
{
|
||||
DWORD affinity = 0;
|
||||
if (!pfnGetWindowDisplayAffinity(GetHWND(), &affinity))
|
||||
wxLogLastError("GetWindowDisplayAffinity");
|
||||
else if (affinity & WDA_MONITOR)
|
||||
return wxCONTENT_PROTECTION_ENABLED;
|
||||
}
|
||||
#endif
|
||||
return wxCONTENT_PROTECTION_NONE;
|
||||
}
|
||||
|
||||
bool wxTopLevelWindowMSW::SetContentProtection(wxContentProtection contentProtection)
|
||||
{
|
||||
#if wxUSE_DYNLIB_CLASS
|
||||
typedef BOOL(WINAPI *SetWindowDisplayAffinity_t)(HWND, DWORD);
|
||||
|
||||
wxDynamicLibrary dllUser32("user32.dll");
|
||||
SetWindowDisplayAffinity_t pfnSetWindowDisplayAffinity =
|
||||
(SetWindowDisplayAffinity_t)dllUser32.RawGetSymbol("SetWindowDisplayAffinity");
|
||||
if (pfnSetWindowDisplayAffinity)
|
||||
{
|
||||
if (pfnSetWindowDisplayAffinity(GetHWND(),
|
||||
(contentProtection == wxCONTENT_PROTECTION_ENABLED) ?
|
||||
WDA_MONITOR : WDA_NONE))
|
||||
return true;
|
||||
else
|
||||
wxLogLastError("SetWindowDisplayAffinity");
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool wxTopLevelWindowMSW::MSWEnableCloseButton(WXHWND hwnd, bool enable)
|
||||
{
|
||||
|
||||
@@ -1093,6 +1093,20 @@ void wxNonOwnedWindowCocoaImpl::SetTitle( const wxString& title, wxFontEncoding
|
||||
[m_macWindow setTitle:wxCFStringRef( title , encoding ).AsNSString()];
|
||||
}
|
||||
|
||||
wxContentProtection wxNonOwnedWindowCocoaImpl::GetContentProtection() const
|
||||
{
|
||||
return (m_macWindow.sharingType == NSWindowSharingNone) ?
|
||||
wxCONTENT_PROTECTION_ENABLED : wxCONTENT_PROTECTION_NONE;
|
||||
}
|
||||
|
||||
bool wxNonOwnedWindowCocoaImpl::SetContentProtection(wxContentProtection contentProtection)
|
||||
{
|
||||
m_macWindow.sharingType = (contentProtection == wxCONTENT_PROTECTION_ENABLED) ?
|
||||
NSWindowSharingNone : NSWindowSharingReadOnly;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wxNonOwnedWindowCocoaImpl::EnableCloseButton(bool enable)
|
||||
{
|
||||
[[m_macWindow standardWindowButton:NSWindowCloseButton] setEnabled:enable];
|
||||
|
||||
@@ -196,6 +196,16 @@ bool wxTopLevelWindowMac::IsFullScreen() const
|
||||
return m_nowpeer->IsFullScreen();
|
||||
}
|
||||
|
||||
wxContentProtection wxTopLevelWindowMac::GetContentProtection() const
|
||||
{
|
||||
return m_nowpeer->GetContentProtection();
|
||||
}
|
||||
|
||||
bool wxTopLevelWindowMac::SetContentProtection(wxContentProtection contentProtection)
|
||||
{
|
||||
return m_nowpeer->SetContentProtection(contentProtection);
|
||||
}
|
||||
|
||||
bool wxTopLevelWindowMac::EnableCloseButton(bool enable)
|
||||
{
|
||||
// Unlike in wxMSW, wxSYSTEM_MENU is not sufficient to show
|
||||
|
||||
Reference in New Issue
Block a user