我有一个通过MDI多试图的,包含2个选项卡的应用程序。应用程序容器是在MFC上以C++开发的,首先通过一个MainFrame 控制页面,ChildFrame用于选项卡显示,ChildFrame里面包含一个基类是CWnd的ChildView,用于不同种类页面显示,每一种页面都是基于Dialog,目前我新增了一个Dialog包含CEF的CefRefPtr,并且在OnInitDialog中新建cef显示界面用于显示本地html页面,目前的问题是当打开两个选项卡,都包含已经各自的html页面,新建时都显示正常,从Tab 2(CEF)到Tab 1(CEF)来回切换时,两个页面都无法展示内容,将鼠标悬停在标签上时,或者在右键点击打印时,html内容变得可见。
// OfdView.cpp : 实现文件
//
#include "stdafx.h"
#include "EVFReader.h"
#include "OfdView.h"
#include "afxdialogex.h"
void escallback(std::string rspstr){ /*printf("[%25s][%04d] rsp[%s] \n",__FILE__,__LINE__,rspstr.c_str());*/}
std::string status_ok="1"; // 后台返回正常码
CString g_localurl = "http://127.0.0.1:8999";
ReqCallback pESfun = escallback;
// COfdView 对话框
IMPLEMENT_DYNAMIC(COfdView, CDialogEx)
COfdView::COfdView(CWnd* pParent /*=NULL*/)
: CDialogEx(COfdView::IDD, pParent)
{
m_title = "";
}
COfdView::~COfdView()
{
if(m_title.GetLength()!=0)
{
CIniFile IniFile;
IniFile.SetPath(IniFile.GetMyDirectory() + "infofile.dat");
CString address =IniFile.GetKeyValue("default","localaddr");
if(address.GetLength()==0)
return ;
std::string url = std::string(address) + "/CleanFileCache";
HttpClient::ClearBuffer();
HttpClient::SendReqPost(url,"",pESfun);
std::string strResponse = HttpClient::GetRsp();
}
//m_ofd.Quit();
}
void COfdView::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
//DDX_Control(pDX, IDC_EXPLORER, m_ofd);
}
BEGIN_MESSAGE_MAP(COfdView, CDialogEx)
ON_WM_CREATE()
ON_WM_SIZE()
// ON_WM_ACTIVATE()
ON_WM_PAINT()
ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
// COfdView 消息处理程序
BOOL COfdView::OnInitDialog()
{
CDialogEx::OnInitDialog();
// TODO: 在此添加额外的初始化
CIniFile IniFile;
CString curdir = IniFile.GetMyDirectory();
CString m_indexfile = "file:///"+curdir+"dist/index.html";
//获取屏幕
CWnd * pParentWnd=CWnd::FromHandle(this->m_hWnd);
CRect rect;
pParentWnd->GetWindowRect(&rect);
pParentWnd->ScreenToClient(rect);
CefRefPtr<CWebClient>client(new CWebClient());
m_cWebClient= client;
CefWindowInfo info;
info.SetAsChild(GetSafeHwnd(),rect);
CefBrowserSettings browserSettings;
CefBrowserHost::CreateBrowser(info, m_cWebClient, m_indexfile.GetBuffer(), browserSettings,NULL,NULL);
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
void COfdView::OnSize(UINT nType, int cx, int cy)
{
CDialogEx::OnSize(nType, cx, cy);
CWnd *ofdViewWnd = GetDlgItem(COfdView::IDD);
if ( ofdViewWnd )
{
CRect ClientRect;
GetClientRect( &ClientRect );
MoveWindow(&ClientRect, FALSE);
}
// TODO: 在此处添加消息处理程序代码
if (m_cWebClient!=NULL)
{
CRect rect(0,cx,0,cy);
m_cWebClient->setRect(rect);
CefRefPtr<CefBrowser> browser=m_cWebClient->GetBrowser();
if(browser)
{
CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();
::MoveWindow( hwnd, 0, 0, cx, cx, FALSE);
}
}
}
int COfdView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialogEx::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: 在此添加您专用的创建代码
return 0;
}
//文件路径
void COfdView::SetTitle(CString filename)
{
if(filename.GetLength()!=0)
{
m_title = filename;
filename.Replace("\\","/");
std::string tmp = std::string(filename);
std:: string postData = "{\"filename\":\""+ tmp +"\"}";
std::string url = std::string(g_localurl) + "/SetLocalFile";
HttpClient::ClearBuffer();
HttpClient::SendReqPost(url,postData,pESfun);
std::string strResponse = HttpClient::GetRsp();
}
}
void COfdView::SetFile(CString filename, CTextString ofdData)
{
if(ofdData.GetLength()!=0)
{
m_title = filename;
filename.Replace("\\","/");
std::string str(ofdData.GetData());
std::string postData = "{\"filedata\":\""+ str +"\"}";
std::string url = std::string(g_localurl) + "/SetLocalFileData";
HttpClient::ClearBuffer();
HttpClient::SendReqPost(url,postData,pESfun);
std::string strResponse = HttpClient::GetRsp();
}
else
m_title = "中科江南文档阅读器";
}
void COfdView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此处添加消息处理程序代码
// 不为绘图消息调用 CDialogEx::OnPaint()
//RECT rect;
// GetWindowRect(&rect);
// InvalidateRect( &rect, TRUE);//刷新窗口
if (m_cWebClient!=NULL)
{
//RECT rect;
//GetClientRect(&rect);
CefRefPtr<CefBrowser> browser=m_cWebClient->GetBrowser();
if(browser)
{
CefWindowHandle hwnd = browser->GetHost()->GetWindowHandle();
// m_cWebClient->SetVisible(true,hwnd);
browser->Reload(); //尝试解决方法1
}
}
}
我在OnPaint中尝试reload 可以有效展示出来,但是这个解决方案在项目中不可行因为html页面会加载服务器上的文件,所以不能重新加载。
#pragma once
#include "explorer.h"
#include "http_client.h"
#include "IniFile.h"
#include"simple_app.h"
#include "simple_handler.h"
#include "WebClient.h"
//#include "HtmlCtrl.h"
// COfdView 对话框
class COfdView : public CDialogEx
{
DECLARE_DYNAMIC(COfdView)
public:
COfdView(CWnd* pParent = NULL); // 标准构造函数
virtual ~COfdView();
virtual BOOL OnInitDialog();
// 对话框数据
enum { IDD = IDD_DIALOG_OFD };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
//CExplorer m_ofd;
CString m_title;
CString m_indexfile;
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
CefRefPtr<CWebClient> m_cWebClient;
//CHtmlCtrl m_html;
afx_msg void OnSize(UINT nType, int cx, int cy);
void SetTitle(CString filename);
void SetFile(CString filename,CTextString ofdData);
// afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
afx_msg void OnPaint();
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
};