libcef3——自定义右键菜单,复制图片和图片另存为

前言

利用libcef3实现了一个客户端,当预览截图的时候,发现自带的菜单点击图片的时候没有复制按钮。
在这里插入图片描述
研究了一下,自带的例子中有增加菜单的示例:

void ClientHandler::OnBeforeContextMenu(CefRefPtr<CefBrowser> browser,
                                        CefRefPtr<CefFrame> frame,
                                        CefRefPtr<CefContextMenuParams> params,
                                        CefRefPtr<CefMenuModel> model) {
  CEF_REQUIRE_UI_THREAD();

  if ((params->GetTypeFlags() & (CM_TYPEFLAG_PAGE | CM_TYPEFLAG_FRAME)) != 0) {
    // Add a separator if the menu already has items.
    if (model->GetCount() > 0)
      model->AddSeparator();

    // Add DevTools items to all context menus.
    model->AddItem(CLIENT_ID_SHOW_DEVTOOLS, "&Show DevTools");
    model->AddItem(CLIENT_ID_CLOSE_DEVTOOLS, "Close DevTools");
    model->AddSeparator();
    model->AddItem(CLIENT_ID_INSPECT_ELEMENT, "Inspect Element");

    if (HasSSLInformation(browser)) {
      model->AddSeparator();
      model->AddItem(CLIENT_ID_SHOW_SSL_INFO, "Show SSL information");
    }

    // Test context menu features.
    BuildTestMenu(model);
  }

  if (delegate_)
    delegate_->OnBeforeContextMenu(model);
}

经过一番研究:

  1. 判断选中的对象是否是图片
  2. 增加菜单
  3. 处理点击事件
enum client_menu_ids {
    CLIENT_ID_COPY_IMAGE = MENU_ID_USER_FIRST, // 复制
    CLIENT_ID_SAVE_IMAGE_AS,                   // 另存为
};

    // CefContextMenuHandler methods
    void BrowserHandler::OnBeforeContextMenu(CefRefPtr<CefBrowser> browser,
            CefRefPtr<CefFrame> frame,
            CefRefPtr<CefContextMenuParams> params,
            CefRefPtr<CefMenuModel> model) {
        REQUIRE_UI_THREAD();
        
		// CM_TYPEFLAG_MEDIA 包含图片、视频、文件等等
		// 可以再进行细化判断:params->GetMediaType() & CM_MEDIATYPE_IMAGE != 0
		if ((params->GetTypeFlags() & CM_TYPEFLAG_MEDIA) != 0 && (params->GetMediaType() & CM_MEDIATYPE_IMAGE != 0)) {
		    if (model->GetCount() > 0) {
		        // 禁止右键菜单
		        model->Clear();
		    }
		
		    model->InsertItemAt(0, CLIENT_ID_COPY_IMAGE, L"复制图片");
		    model->InsertItemAt(1, CLIENT_ID_SAVE_IMAGE_AS, L"图片另存为...");
		    model->InsertSeparatorAt(2);
		    model->AddItem(MENU_ID_PRINT, L"打印");
		}
    }

// 处理点击事件
bool BrowserHandler::OnContextMenuCommand(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefContextMenuParams> params, int command_id, EventFlags event_flags) {
        // 复制图片到剪切板
        if (command_id == CLIENT_ID_COPY_IMAGE) {
            frame->Copy();

        } else if (command_id == CLIENT_ID_SAVE_IMAGE_AS) {
            // 存储图片
            frame->GetBrowser().get()->GetHost().get()->StartDownload(frame->GetURL());
        }

        if (handle_delegate_)
            return handle_delegate_->OnContextMenuCommand(browser, frame, params, command_id, event_flags);

        else
            return false;
    }

 // 存储图片后,会回调到这里,弹出保存文件框
 // 注意使用了windows api,#include <shlobj.h>
 void BrowserHandler::OnBeforeDownload(
        CefRefPtr<CefBrowser> browser,
        CefRefPtr<CefDownloadItem> download_item,
        const CefString& suggested_name,
        CefRefPtr<CefBeforeDownloadCallback> callback) {
        CEF_REQUIRE_UI_THREAD();
        
        TCHAR szFolderPath[MAX_PATH];
        std::string path;
        const std::string& file_name = suggested_name;

        // Save the file in the user's "My Documents" folder.
        if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL | CSIDL_FLAG_CREATE, NULL,
                                      0, szFolderPath))) {
            path = CefString(szFolderPath);
            path += "\\" + file_name;
        }

        callback->Continue(path, true);//第一个参数是设置文件保存全路径包含文件名

        if (handle_delegate_)
            handle_delegate_->OnBeforeDownload(browser, download_item, suggested_name, callback);
    }

如果没生效,检查这里是不是重载了:

virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() OVERRIDE { return this; }

效果

在这里插入图片描述
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值