在上一课中,我们讨论了如何创建独立于平台的窗口类,及如何利用平台特定 (Linux) 的行为对其进行扩展。如果您错过了上一课,可在此处阅读相关内容。
在本课中,我们将介绍如何连接窗口与应用程序。
首先,我们需创建自己的 BrowserMainParts 类,它在整个浏览器循环中具有重要作用。此类将处理浏览器初始化部分的所有主要功能。此类中有若干必须得到实现的重要方法。在特定步骤中(某些事件的前后),这些方法将从 BrowserMainLoop 类中被调用。这些步骤包括:
根据上述三个步骤,我们将覆盖 Browser Main Parts 子类 (browser/browser_main_parts.cc) 中的下列方法。
在 Pre Early Initialization 中,我们将初始化 UI 输入方法。
void SprocketBrowserMainParts::PreEarlyInitialization() {
ui::InitializeInputMethodForTesting();
}
在 Pre Main Message Loop Run 中,我们将初始化并创建窗口。该窗口需要有运行的消息循环,才能正确工作并处理交互操作。
void SprocketBrowserMainParts::PreMainMessageLoopRun() {
SprocketWindow::Initialize();
SprocketWindow::CreateNewWindow(gfx::Size());
在 Post Main Message Loop Run 中,我们将取消初始化并销毁窗口。
void SprocketBrowserMainParts::PostMainMessageLoopRun() {
SprocketWindow::Deinitialize();
到这里,我们尚未完成。应将 Browser Main Parts 连接到应用程序的其余部分。
接下来,需要添加我们自己的 ContentBrowserClient 类。此类的目的是为嵌入器提供 API,以便参与浏览器逻辑。
现在,我们只有一种方法,它通过特定参数实例化浏览器主要部分。
content::BrowserMainParts*
SprocketContentBrowserClient::CreateBrowserMainParts(
const content::MainFunctionParams& parameters) {
browser_main_parts_ = new SprocketBrowserMainParts(parameters);
return browser_main_parts_;
接下来,我们将添加自己的 Main Delegate 实现。您应该了解,Content Main 需要有 Main Delegate 实例(通过其构造函数传递)。在上一教程中,此参数设置为 NULL。现在,实现 Main Delegate 后,我们即可改为利用我们的类的实例。
SprocketMainDelegate delegate;
content::ContentMainParams params(&delegate);
使用此代码,可将 Main Delegate 设为负责创建 Content Browser Client。
content::ContentBrowserClient*
SprocketMainDelegate::CreateContentBrowserClient() {
browser_client_.reset(new SprocketContentBrowserClient);
return browser_client_.get();
最后只剩下一件事。我们来实现基本启动操作完成后调用的 Basic Startup Complete。
bool SprocketMainDelegate::BasicStartupComplete(int* exit_code) {
base::FilePath pak_file;
ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file);
return false;
在此方法中,我们应初始化资源包。现在,此处使用的是虚拟路径,因为我们还没有任何资源文件。在后面课程中,我们将替换此路径。
完成了!现在,您应该可以看到一个空白窗口。
下次,我们将介绍Content API 的一些上下文。
敬请期待下一课!
第二课的资源仓库在此。
附件:BrowserMainParts, ContentBrowserClient, MainDelegate.