libcef3-Personaliza el menú contextual, copia imágenes y guarda imágenes como

Prefacio

Se implementó un cliente usando libcef3 Al obtener una vista previa de la captura de pantalla, se encontró que el menú integrado no tenía un botón de copia al hacer clic en la imagen.
Inserte la descripción de la imagen aquí
Después de investigar, hay un ejemplo de cómo agregar un menú en el ejemplo incluido:

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);
}

Después de algunas investigaciones:

  1. Determinar si el objeto seleccionado es una imagen
  2. Agregar menú
  3. Manejo de eventos de clic
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);
    }

Si no tiene efecto, compruebe si está sobrecargado aquí:

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

efecto

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/xmcy001122/article/details/109516394
Recomendado
Clasificación