2015-05-19 105 views
0

在我的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); 


     } 
+0

发布您的CHtmlView派生类代码 –

+0

干杯!添加了相关的代码。 – Raiden616

+0

好吧更新:如果我在调用Navigate2()之前添加“睡眠(1000)”,它似乎修复它。或者至少解决它。这给任何人提供任何线索?我宁愿修好它... – Raiden616

回答

0

这里是我的派生类CHtmlView的的。我直接将HTML加载到浏览器中。适用于我,也许你可以使用它:

#include "stdafx.h" 
#include "GMHtmlView.h" 

#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 

IMPLEMENT_DYNCREATE(CGMHtmlView, CHtmlView) 

CGMHtmlView::CGMHtmlView(IHtmlEventNotifier* pHEN) 
{ 
    EnableToolTips(FALSE); 
    m_pBrowser = NULL; 
    m_pBrowserDispatch = NULL; 
    m_pHEN = pHEN; 
    m_strPrefix = "http://"; 
} 

void CGMHtmlView::DoDataExchange(CDataExchange* pDX) 
{ 
    CHtmlView::DoDataExchange(pDX); 
} 

BEGIN_MESSAGE_MAP(CGMHtmlView, CHtmlView) 
END_MESSAGE_MAP() 

BOOL CGMHtmlView::Create(const RECT &rect,CWnd* pParentWnd) 
{ 
    BOOL bRet = CHtmlView::Create(NULL,NULL,WS_VISIBLE,rect,pParentWnd,AFX_IDW_PANE_FIRST); 

    // Pointer auf Browser herausfinden 
    if(bRet) 
    { 
     LPUNKNOWN unknown = GetDlgItem(0)->GetControlUnknown(); 
     HRESULT hr = unknown->QueryInterface(IID_IWebBrowser2,(void **)&m_pBrowser); 

     if (SUCCEEDED(hr)) 
      hr = unknown->QueryInterface(IID_IDispatch,(void **)&m_pBrowserDispatch); 
    } 

    return bRet; 
} 

void CGMHtmlView::SetPrefix(const CString& prefix) 
{ 
    m_strPrefix = prefix; 
} 

void CGMHtmlView::OnBeforeNavigate2(LPCTSTR lpszURL, DWORD nFlags, LPCTSTR lpszTargetFrameName, CByteArray& baPostedData, LPCTSTR lpszHeaders, BOOL* pbCancel) 
{ 
    CString url(lpszURL); 
    url.MakeLower(); 

    // Sperre: alles andere als die leere Seite 
    // und unser Inhalt wird gesperrt 

    if(url == "about:blank") 
    { 
     CHtmlView::OnBeforeNavigate2(lpszURL,nFlags,lpszTargetFrameName,baPostedData,lpszHeaders,pbCancel); 
     return; 
    } 

    if(url.Find(m_strPrefix) != 0) 
    { 
     *pbCancel = TRUE; 
     return; 
    } 

    // jetzt die Adresse nach aussen weiterleiten 
    if(m_pHEN) 
    { 
     url = url.Right(url.GetLength() - m_strPrefix.GetLength()); 
     m_pHEN->UrlNotify(url); 
    } 
} 

void CGMHtmlView::Clear() 
{ 
    if(!IsWindow(m_hWnd)) 
     return; 

    IHTMLDocument2* pDoc = GetDocument(); 

    if(!pDoc) 
    { 
     Navigate2("about:blank"); 
     return; 
    } 

    pDoc->close(); 

    VARIANT open_name; 
    VARIANT open_features; 
    VARIANT open_replace; 
    IDispatch *open_window = NULL; 

    ::VariantInit(&open_name); 

    open_name.vt  = VT_BSTR; 
    open_name.bstrVal = ::SysAllocString(L"_self"); 

    ::VariantInit(&open_features); 
    ::VariantInit(&open_replace); 

    HRESULT hr = pDoc->open(::SysAllocString(L"text/html"),open_name,open_features, 
     open_replace,&open_window); 

    if (hr == S_OK) 
     Refresh(); 

    if (open_window != NULL) 
     open_window->Release(); 

} 

void CGMHtmlView::LoadHTML(const CString& html) 
{ 
    if(!IsWindow(m_hWnd)) 
     return; 

    Clear(); 

    IHTMLDocument2* pDoc = GetDocument(); 

    if(!pDoc) 
     return; 

    SAFEARRAY* sa = SafeArrayCreateVector(VT_VARIANT,0,1); 
    VARIANT* var; 

    SafeArrayAccessData(sa,(LPVOID*) &var); 
    var->vt = VT_BSTR; 
    var->bstrVal = html.AllocSysString(); 
    SafeArrayUnaccessData(sa); 

    pDoc->write(sa); 
    pDoc->Release(); 
} 

IHTMLDocument2* CGMHtmlView::GetDocument() 
{ 
    IHTMLDocument2* document = NULL; 

    if (m_pBrowser != NULL) 
    { 
     IDispatch *document_dispatch = NULL; 
     HRESULT hr = m_pBrowser->get_Document(&document_dispatch); 

     if (SUCCEEDED(hr) && (document_dispatch != NULL)) 
     { 
      hr = document_dispatch->QueryInterface(IID_IHTMLDocument2,(void **)&document); 
      document_dispatch->Release(); 
     } 
    } 

    return document; 
} 

void CGMHtmlView::AssertValid() const 
{ 
    //CHtmlView::AssertValid(); 
} 

void CGMHtmlView::PostNcDestroy() 
{ 
    //CHtmlView::PostNcDestroy(); 
} 
+0

不幸的是,我已经尝试过你的课,并得到完全相同的问题... – Raiden616

相关问题