MFC Windows应用中如何将WebBrowser控件默认浏览器替换为Chrome?
嘿,这个场景我太熟了——Windows XP上MFC的WebBrowser控件默认绑IE8,碰到CSS3和现代JS直接歇菜。要在应用内部嵌入Chrome内核,最靠谱的方案就是用Chromium Embedded Framework (CEF),这是专门为原生应用嵌入Chrome内核设计的框架,完全能满足你“内部打开网页”的需求。下面是一步步的实操指南:
第一步:准备适配XP的CEF环境
- 注意CEF从3.3440版本开始就不再支持Windows XP了,所以必须选3.3325.1729.gbfa3c1c这个最后支持XP的稳定版(别下错了,不然XP上跑不起来)。
- 下载对应32位的预编译包(XP基本都是32位系统),解压后能看到
include、lib、Release这些文件夹,里面是头文件、库和依赖资源。
第二步:把CEF集成进你的MFC项目
- 先配置项目路径:右键MFC项目→属性→C/C++→常规,在“附加包含目录”里加
cef_binary\include和cef_binary\include\cef;然后去链接器→常规,“附加库目录”加cef_binary\lib\Release(Debug模式就加Debug目录)。 - 链接器→输入→附加依赖项,添加
libcef.lib和libcef_dll_wrapper.lib这两个核心库。 - 字符集设置:CEF默认用多字节字符集,如果你的MFC项目是Unicode编码,要么改成多字节,要么后续自己做宽字节转多字节的兼容处理(推荐先转多字节,省得踩字符编码的坑)。
第三步:初始化CEF并嵌入浏览器窗口
- 在MFC应用的
InitInstance()里先初始化CEF:CefMainArgs main_args(AfxGetInstanceHandle()); CefSettings settings; // XP上必须开no_sandbox,不然会启动失败 settings.no_sandbox = true; // 可以自定义缓存路径,比如settings.cache_path = L"./cef_cache"; if (!CefInitialize(main_args, settings, nullptr, nullptr)) { AfxMessageBox(L"CEF初始化失败!"); return FALSE; } - 在你要放网页的对话框/视图类里,加个成员变量
CefRefPtr<CefBrowser> m_browser;,然后在窗口初始化时(比如OnInitDialog())创建浏览器:CRect clientRect; GetClientRect(&clientRect); CefWindowInfo windowInfo; // 把CEF浏览器嵌入当前MFC窗口作为子控件 windowInfo.SetAsChild(GetSafeHwnd(), clientRect); CefBrowserSettings browserSettings; // 确保JS、CSS3都启用 browserSettings.javascript_enabled = true; browserSettings.css_enabled = true; // 创建浏览器并加载目标网页 CefBrowserHost::CreateBrowser(windowInfo, this, L"https://你的网页地址", browserSettings, nullptr); - 别忘了处理窗口大小变化,不然网页会变形:
void CMyDialog::OnSize(UINT nType, int cx, int cy) { CDialogEx::OnSize(nType, cx, cy); if (m_browser) { m_browser->GetHost()->WasResized(); } } - 还要实现CEF的基础回调接口,比如继承
CefClient、CefLifeSpanHandler,不然浏览器生命周期管理会出问题(比如关闭窗口时要销毁浏览器实例)。
第四步:集成CEF和MFC的消息循环
- MFC的消息循环要和CEF的消息循环配合,修改
CMyApp::Run():int CMyApp::Run() { MSG msg; while (GetMessage(&msg, nullptr, 0, 0)) { if (!PreTranslateMessage(&msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } // 让CEF处理自身的消息 CefDoMessageLoopWork(); } return (int)msg.wParam; } - 应用退出时一定要关闭CEF,在
ExitInstance()里加:int CMyApp::ExitInstance() { CefShutdown(); return CWinAppEx::ExitInstance(); }
部署注意事项
- 把CEF解压包里
Release文件夹下的所有文件(比如libcef.dll、chrome_elf.dll、各种.pak资源文件)都复制到你的MFC程序根目录,少一个都可能跑不起来。 - XP上要确保你的程序是32位编译的,CEF的64位版本不支持XP。
- 如果网页要访问本地文件,记得在CEF初始化时设置
settings.file_access_from_file_urls_allowed = true;。
内容的提问来源于stack exchange,提问作者jeeva
相关产品推荐
相关产品推荐

