wxWidgets wxWebView::CanCopy跨平台禁止用户复制实现示例咨询
实现方案说明
单纯重写wxWebView::CanCopy无法实现全平台兼容,因为OSX WebKit后端会绕过wx层的该方法判断,需要结合自定义wxWebView子类重写事件逻辑+前端注入脚本拦截复制行为的双方案实现全平台覆盖。
步骤1:自定义wxWebView子类,拦截wx层复制行为
继承wxWebView重写核心方法,拦截复制菜单事件、系统快捷键,同时重写CanCopy方法适配Windows/Linux平台:
// 头文件定义 #include <wx/webview.h> #include <wx/event.h> class CustomWebView : public wxWebView { public: static CustomWebView* New(wxWindow* parent, wxWindowID id, bool isSubscribedUser); bool CanCopy() const override; void OnCopy(wxCommandEvent& event); void OnKeyDown(wxKeyEvent& event); private: bool m_isSubscribed = false; wxDECLARE_EVENT_TABLE(); };
// 实现逻辑 wxBEGIN_EVENT_TABLE(CustomWebView, wxWebView) EVT_MENU(wxID_COPY, CustomWebView::OnCopy) EVT_KEY_DOWN(CustomWebView::OnKeyDown) wxEND_EVENT_TABLE() CustomWebView* CustomWebView::New(wxWindow* parent, wxWindowID id, bool isSubscribedUser) { auto* webView = new CustomWebView(); webView->Create(parent, id); webView->m_isSubscribed = isSubscribedUser; return webView; } bool CustomWebView::CanCopy() const { return m_isSubscribed ? wxWebView::CanCopy() : false; } void CustomWebView::OnCopy(wxCommandEvent& event) { if (m_isSubscribed) event.Skip(); } void CustomWebView::OnKeyDown(wxKeyEvent& event) { if ((event.GetModifiers() == wxMOD_CONTROL || event.GetModifiers() == wxMOD_RAW_CONTROL) && event.GetKeyCode() == 'C' && !m_isSubscribed) { return; } event.Skip(); }
步骤2:注入前端拦截逻辑,适配OSX平台
OSX平台WebKit内核会绕过wx层事件处理,需要在加载页面时注入JS+CSS拦截前端复制行为:
// 注入拦截脚本和样式 wxString injectCode = R"( <script> document.addEventListener('copy', function(e) { if (!window.isSubscribed) { e.preventDefault(); e.stopPropagation(); return false; } }); </script> <style> body:not(.subscribed) { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; } </style> )"; // 拼接页面内容 wxString pageContent; bool isSubscribed = false; // 替换为实际用户订阅状态判断逻辑 if (isSubscribed) { pageContent = "<body class='subscribed'><script>window.isSubscribed = true;</script>" + injectCode + "****Demo Code******</body>"; } else { pageContent = "<body class='not-subscribed'>" + injectCode + "****Demo Code******</body>"; } // 初始化webview CustomWebView *webView = CustomWebView::New(this, wxID_ANY, isSubscribed); webView->SetPage(pageContent, ""); webView->SetEditable(false); webView->EnableContextMenu(false);
兼容性说明
- Windows/Linux平台:通过重写CanCopy、拦截菜单和快捷键即可完全生效
- OSX平台:前端JS拦截复制事件+CSS禁止选中文本,配合wx层快捷键拦截,覆盖所有原生复制场景
内容的提问来源于stack exchange,提问作者Amod Gokhale
相关产品推荐
相关产品推荐

