You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 16:54:00