完全初始化的 CEF OS X 客户端的 Chromium 入口点

Chromium entry point for fully initialized CEF OS X client

我有一个 OS X 的 Chromium 客户端实现。我想支持对数据文件的双击操作,该文件可以在我的 Chromium 客户端中读取和显示。为此,我需要实现方法 application:openFile。在应用程序完全初始化之前很长时间调用此方法。为此,我需要在 Chromium 客户端完全初始化并且存在 NSWindow 之后调用 application:openFile

chromium完全初始化后自动调用哪个方法chrome window可用?

class CefLoadHandler 有一个名为 OnLoadEnd 的方法。当浏览器加载 web-app 时调用此方法。不过要小心!此时 web-app 的 JavaScript 部分不能 已经初始化。因此,如果您依赖完全初始化的 JavaScript(所有 JavaScript 对象等),那么您必须在 JavaScript 代码中检查它。

查看如何为 Chromium 客户端实施 application:openFile 的完整答案:

经过大量研究和调试,我想出了一个解决方案,即如何在 OS X 上为基于 Chromium 的应用程序实施 application:openFile。首先,有 3 个 parts/layers 必须解决。

  1. Cocoa 部分与 application:openFile
  2. 带有浏览器初始化代码的 Chromium 部分
  3. JavaScript 部分及其初始化部分

开始于 1:

application:openFileapplication:openFile already describes in the Discussion part, that application:openFile is called before applicationDidFinishLaunching. This means, that If you rely on a full initialized client (I can't imagine how's not?), you have to store the URL of the file somewhere, e.g. ivar/property 的 Apple 文档,或者像下面我的 Chromium handler 中的 std::vector 示例。只有当应用程序完全初始化并显示浏览器 window 时,您才能直接调用 Chromium handler method,后者又会调用相应的 JavaScript 函数!

// ***
// application:openFile
// ***

- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename {
  AUApplication * clientApp = (AUApplication *)theApplication;
  NSWindow* targetWindow = [clientApp findTargetWindow];
  //Check if browser window is up and running
  if (targetWindow) {
    [self processFile:filename];
  }
  else {
    //This method saves the file URL to open the file 
    //when the application+JavaScript is fully initialized
    au::test::Handler* handler = au::test::Handler::GetInstance();
    handler->AddPendingFile([filename UTF8String]); 
  }
  return YES;
}

// ***
// processFile
// ***

- (BOOL)processFile:(NSString *)file
{
  //This method calls the JavaScript function to open the file
  std::string fileName([file UTF8String]);
  au::test::Handler* handler = au::test::Handler::GetInstance();
  handler->OnOpenFile(fileName); 
  return YES;
}

2部分:

Chromium side 上,您必须将文件 URL 存储在适当的结构中。我为此使用 std::vector。文件 URL 保存在 Chromium 方法 OnLoadEnd 中。 Chromium 已在浏览器中加载了您的 HTML+JavaScript 部分。不过要小心。 JavaScript的初始化还没有完成!在下面的示例中,我必须分配 JavaScript 属性 来存储文件 URL.

// ***
// Handler::OnLoadEnd
// ***

void Handler::OnLoadEnd(CefRefPtr<CefBrowser> browser,
               CefRefPtr<CefFrame> frame,
               int httpStatusCode) {
  if (!m_pendingOpenFiles.empty()) {
    std::string file(m_pendingOpenFiles[0]);
    std::cout << "Pending file for later opening: " << file << std::endl;
    //This method below is calling a JavaScript function to assign
    //a property `pendingFile`
    OnPendingFile(file);
    //Don't forget to pop the file URL afterwards 
    //or use another store container instead of `std::vector`
    //if you don't plan to implement `application:openFiles` as well!!!
    m_pendingOpenFiles.pop_back();
  }
}

3部分:

在 JavaScript 方面,您必须在应用程序初始化后检查 属性 pendingFile 是否已分配或未正确打开文件。