在我的C++应用程序中,使用CHTMLView将一些HTML加载到网页中。它通过将HTML写入临时文件,然后调用CHTMLView上的Navigate2()来导航到文件位置。C++ CHTMLView元素页面加载然后消失
我们发现的情况是,导航发生,文件被写入,页面上完全正确的内容出现,但它很快消失并变为空白。但这是一个视觉上的东西;右键单击并显示“查看源代码”显示正确的源代码,然后将鼠标悬停在页面上对悬停作出反应的元素上,再次显示它们(但其他所有内容都保持白色)。调整窗口大小或滚动是使所有内容都显示的唯一方法。
我试着先导航到about:blank,然后用OnDocumentComplete()事件触发导航到正确的位置。我甚至试着先导航到虚拟页面,然后从那里开始。没有什么变化。
有什么建议吗?
派生类是ScriptViewer。
ScriptViewer.h
class CScriptViewer : public CHtmlView
{
protected:
CScriptViewer(); // protected constructor used by dynamic creation
DECLARE_DYNCREATE(CScriptViewer)
// html Data
public:
//{{AFX_DATA(CScriptViewer)
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// Attributes
public:
CAMAgentDesktopDoc* m_pDoc;
CScriptDlg* m_pDlg;
CString strScriptLocation;
BOOL m_bInitialLoad;
// Operations
public:
void GetAllValues(map<CString,CString>& mValues);
void GetValuesIn(IHTMLDocument2* pHTMLDoc, map<CString,CString>& mValues);
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CScriptViewer)
public:
virtual void OnInitialUpdate();
virtual void OnBeforeNavigate2(LPCTSTR lpszURL, DWORD nFlags, LPCTSTR lpszTargetFrameName, CByteArray& baPostedData, LPCTSTR lpszHeaders, BOOL* pbCancel);
virtual void OnDocumentComplete(LPCTSTR lpszURL);
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CScriptViewer();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
CAMTrace m_trace;
// Generated message map functions
//{{AFX_MSG(CScriptViewer)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
ScriptViewer.cpp
CScriptViewer::CScriptViewer()
{
//{{AFX_DATA_INIT(CScriptViewer)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_trace.SetEXEName(_T("CScriptViewer"));
m_trace.Trace(_T("constructor"), FALSE, 0);
strScriptLocation = _T("");
m_bInitialLoad = FALSE;
m_pDoc = NULL;
m_pDlg = NULL;
}
CScriptViewer::~CScriptViewer()
{
/*
map<CString,CString> mValues;
GetAllValues(mValues);
m_pDlg->UpdateUserEnteredValues(mValues);
*/
m_trace.Trace(_T("destructor"), FALSE, 0);
}
void CScriptViewer::DoDataExchange(CDataExchange* pDX)
{
CHtmlView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CScriptViewer)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CScriptViewer, CHtmlView)
//{{AFX_MSG_MAP(CScriptViewer)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CScriptViewer diagnostics
#ifdef _DEBUG
void CScriptViewer::AssertValid() const
{
CHtmlView::AssertValid();
}
void CScriptViewer::Dump(CDumpContext& dc) const
{
CHtmlView::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CScriptViewer message handlers
void CScriptViewer::OnInitialUpdate()
{
try
{
m_trace.Trace(_T("OnInitialUpdate"));
ASSERT(m_pDoc);
ASSERT(m_pDlg);
}
catch(...)
{
}
}
void CScriptViewer::OnBeforeNavigate2(LPCTSTR lpszURL, DWORD nFlags, LPCTSTR lpszTargetFrameName, CByteArray& baPostedData, LPCTSTR lpszHeaders, BOOL* pbCancel)
{
try
{
map<CString,CString> mValues;
GetAllValues(mValues);
ASSERT(m_pDlg);
// GJS
if (!m_pDlg) return;
m_pDlg->UpdateUserEnteredValues(mValues);
CString strURL = lpszURL;
int nPosClose = strURL.Find(URL_INSTRUCTION_TO_ADAPTIVE_DESKTOP);
if (nPosClose > 0)
{
*pbCancel = TRUE;
CHtmlView::OnBeforeNavigate2(lpszURL, nFlags, lpszTargetFrameName, baPostedData, lpszHeaders, pbCancel);
m_pDlg->OnScriptInstructionToDesktop(strURL.Mid(nPosClose + _tcslen(URL_INSTRUCTION_TO_ADAPTIVE_DESKTOP)), mValues);
}
else
{
CHtmlView::OnBeforeNavigate2(lpszURL, nFlags, lpszTargetFrameName, baPostedData, lpszHeaders, pbCancel);
}
}
catch(...)
{
}
}
void CScriptViewer::OnDocumentComplete(LPCTSTR lpszURL) {
if (!m_bInitialLoad) {
//Navigate2(strScriptLocation);
//m_bInitialLoad = TRUE;
}
}
///////////////////////////////////////////////////////////////////////////////////
// accessing data values from the HTML pages, after the user has fiddled with them
void CScriptViewer::GetValuesIn(IHTMLDocument2* pHTMLDoc, map<CString,CString>& mValues)
{
try
{
if (pHTMLDoc != NULL)
{
BSTR bsURL;
VERIFY(SUCCEEDED(pHTMLDoc->get_URL(&bsURL)));
// TRACE(_T("GetValuesIn(%s)\r\n"), CString(bsURL));
IHTMLFramesCollection2* pFrames = NULL;
if (SUCCEEDED(pHTMLDoc->get_frames(&pFrames)))
{
long lNumFrames = 0;
VERIFY(SUCCEEDED(pFrames->get_length(&lNumFrames)));
for(long l = 0; l < lNumFrames; l++)
{
COleVariant v1(l);
VARIANT vDispFrame;
if (SUCCEEDED(pFrames->item(v1, &vDispFrame)))
{
if (vDispFrame.vt == VT_DISPATCH)
{
IHTMLWindow2* pWindow = NULL;
VERIFY(SUCCEEDED((vDispFrame.pdispVal)->QueryInterface(IID_IHTMLWindow2, (LPVOID*)&pWindow)));
ASSERT(pWindow);
IHTMLDocument2* pSubDoc = NULL;
if (SUCCEEDED(pWindow->get_document(&pSubDoc)))
{
GetValuesIn(pSubDoc, mValues);
pSubDoc->Release();
}
pWindow->Release();
}
}
}
pFrames->Release();
}
IHTMLElementCollection* pElemColl = NULL;
HRESULT hr = pHTMLDoc->get_all(&pElemColl);
if (SUCCEEDED(hr) && pElemColl)
{
long lNumElements = 0;
VERIFY(SUCCEEDED(pElemColl->get_length(&lNumElements)));
for(long l = 0; l < lNumElements; l++)
{
COleVariant v1(l);
COleVariant vzero((long)0);
LPDISPATCH pDispTemp = NULL;
VERIFY(SUCCEEDED(pElemColl->item(v1, vzero, &pDispTemp)));
ASSERT(pDispTemp != NULL);
IHTMLElement* pel = NULL;
VERIFY(SUCCEEDED(pDispTemp->QueryInterface(IID_IHTMLElement, (LPVOID*)&pel)));
CString str;
BSTR bsid;
pel->get_id(&bsid);
VARIANT vValue;
pel->getAttribute(CString("value").AllocSysString(), 0, &vValue);
CString strID = CString(bsid);
if (!strID.IsEmpty())
{
CString strValue = _T("");
if (vValue.vt == VT_BSTR) {
strValue = CString(vValue.bstrVal);
} else if (vValue.vt == VT_I2 || vValue.vt == VT_I4) {
strValue.Format(_T("%d"), vValue.intVal);
}
mValues[strID] = strValue;
// str.Format(_T("ID %s, value %s\r\n"),
// strID, strValue);
// strRetval += str;
}
pel->Release();
}
pElemColl->Release();
}
else
ASSERT(FALSE);
}
else
ASSERT(FALSE); // passed null object doc
}
catch(...)
{
}
}
void CScriptViewer::GetAllValues(map<CString,CString>& mValues)
{
try
{
mValues.clear();
LPDISPATCH pDisp = GetHtmlDocument();
if (pDisp)
{
IHTMLDocument2* p = NULL;
if (SUCCEEDED(pDisp->QueryInterface(IID_IHTMLDocument2, (LPVOID*)&p)) && p != NULL)
{
GetValuesIn(p, mValues);
p->Release();
}
else
ASSERT(FALSE); // unable to QI for IHTMLDocument2?
pDisp->Release();
}
}
catch(...)
{
}
}
这里是处理导航代码:
CString strFilePath = CAMMiscSharedFilePaths::GetFullPathToWindowsTempDir() + _T("\\") + m_call->m_camCampaignSettings.m_scriptView.m_strName+_T("_temp.htm");
HRESULT hr = WriteStringToTextFile(strFilePath, strRedirect); //intentionally left for html settings, as it stores data in windows temp
if (SUCCEEDED(hr)) {
pView->strScriptLocation = strFilePath;
CString str = strFilePath;
pView->Navigate2(str);
}
发布您的CHtmlView派生类代码 –
干杯!添加了相关的代码。 – Raiden616
好吧更新:如果我在调用Navigate2()之前添加“睡眠(1000)”,它似乎修复它。或者至少解决它。这给任何人提供任何线索?我宁愿修好它... – Raiden616