superrg, 分就免了,问题你再看看吧!我也希望能有解决的办法。(知秋一叶)

qqchen79 2002-01-23 12:24:41
http://www.csdn.net/expert/Topic/488/488742.shtm

BTW: 你的分真多呀!:)
...全文
53 点赞 收藏 7
写回复
7 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
superrg 2002-01-24
但我试过好像用put_URL没有作用,因为只要后来对其内容作过改动,URL就会变成about:blank,这个东东还真不好处理~~~~~~~
回复
superrg 2002-01-23
程序调试没有问题,速度也很快,唯一美中不足的是:当取Document的URL时,得到的URL是about:blank,按照这个结果推论,利用该Document对其内容进行解释时,Script以及Links都会出现问题。有没有一个简便的方法可以直接设置文档的URL属性而又不会导至文档重新下载的呢????
回复
superrg 2002-01-23
非常感谢知秋一叶,Let me try again.....(BTW:这种问题出高分不行,不出高分更不行,调通了我一定会送你分的,在这方面你的确是个人才,给你送分,一个字:值~~~~~~~)
回复
qqchen79 2002-01-23
如果要处理script的话,为什么不用put_URL而要用IStream呢?我觉得使用Stream主要是从File或者内存中直接生成HTML并解析。如果担心put_URL会导致多余的下载的话,可以通过实现IOleClientSite,IDispatch::Invoke,接管DISPID_AMBIENT_DLCONTROL来改变这种行为,这在WalkAll中也是由例子的(只要加上IDispatch/IOleClientSite的实现,并且注意Invoke函数的内容)。
回复
qqchen79 2002-01-23
1. MSHTML确实需要消息循环,看来它内部还是靠消息机制运行的。
2. IPersistStreamInit ->Load是异步方法,与要实现IPropertyNotifySink ->OnChange来监视Load是否完成。

下面是一个140行的程序,应该够小了:)。从WalkAll变来的。
#include "stdafx.h"
#include <comdef.h>
#include <Atlbase.h>
#include <urlmon.h>
#include <mshtml.h>
#include <iostream>

using namespace std;

#define WM_USER_LOADCOMPLETE ((WM_USER) + 1)

struct MyEventSink : public IPropertyNotifySink
{
CComPtr<IHTMLDocument2> m_pMSHTML;
DWORD m_dwRef;

MyEventSink() :m_pMSHTML(NULL), m_dwRef(0)
{}

HRESULT Init() {
HRESULT hr;
LPCONNECTIONPOINTCONTAINER pCPC = NULL;
hr = m_pMSHTML->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pCPC);

LPCONNECTIONPOINT pCP;
hr = pCPC->FindConnectionPoint(IID_IPropertyNotifySink, &pCP);

DWORD dwCookie;
return pCP->Advise((LPUNKNOWN)(IPropertyNotifySink*)this, &dwCookie);
}

STDMETHODIMP QueryInterface(REFIID riid, LPVOID* ppv)
{
*ppv = NULL;
if (IID_IUnknown == riid || IID_IPropertyNotifySink == riid)
{
*ppv = (LPUNKNOWN)(IPropertyNotifySink*)this;
AddRef();
return NOERROR;
} else {
return E_NOTIMPL;
}
}

STDMETHODIMP_(ULONG) Release()
{
if (--m_dwRef == 0)
{
delete this;
return 0;
}
return m_dwRef;
}

STDMETHODIMP_(ULONG) AddRef()
{
return ++m_dwRef;
}

STDMETHODIMP OnChanged(DISPID dispID)
{

HRESULT hr;

if (DISPID_READYSTATE == dispID)
{
VARIANT vResult = {0};
EXCEPINFO excepInfo;
UINT uArgErr;

DISPPARAMS dp = {NULL, NULL, 0, 0};
if (SUCCEEDED(hr = m_pMSHTML->Invoke(DISPID_READYSTATE, IID_NULL, LOCALE_SYSTEM_DEFAULT,
DISPATCH_PROPERTYGET, &dp, &vResult, &excepInfo, &uArgErr)))
{
READYSTATE lReadyState = (READYSTATE)V_I4(&vResult);
if (lReadyState == READYSTATE_COMPLETE)
{
BOOL fRet = PostThreadMessage(GetCurrentThreadId(),
WM_USER_LOADCOMPLETE,
(WPARAM)0,
(LPARAM)0);
}
VariantClear(&vResult);
}
}
return NOERROR;
}

STDMETHODIMP OnRequestEdit(DISPID dispID)
{
return NOERROR;
}
};

void main()
{
HRESULT hr;
CoInitialize(NULL);
{

CComPtr<IHTMLDocument2> pdoc;
CoCreateInstance(CLSID_HTMLDocument, NULL, CLSCTX_ALL, IID_IHTMLDocument2, (void **)&pdoc);

MyEventSink evtsink;
evtsink.m_pMSHTML = pdoc;
evtsink.Init();
{
CComPtr<IPersistStreamInit> pstr;
hr = pdoc->QueryInterface(IID_IPersistStreamInit, (void **)&pstr);
if(!SUCCEEDED(hr)) cout << "error 2!" << endl;

CComPtr<IStream> pstream;
hr = URLOpenBlockingStream(0, "http://www.msn.com", &pstream, 0, 0);
if(!SUCCEEDED(hr)) cout << "error 1!" << endl;

hr = pstr ->Load(pstream);
if(!SUCCEEDED(hr)) cout << "error 3!" << endl;
}

MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
if (WM_USER_LOADCOMPLETE == msg.message && NULL == msg.hwnd)
{
CComPtr<IHTMLElement> pele;
hr = pdoc->get_body((IHTMLElement **)&pele);
if(!SUCCEEDED(hr)) cout << "error 4!" << endl;

BSTR b;
hr = pele ->get_outerHTML(&b);
if(!SUCCEEDED(hr)) cout << "error 5!" << endl;

_bstr_t bt(b, true);
cout << (char *)bt << endl;
PostQuitMessage(0);
}
else
{
DispatchMessage(&msg);
}
}
}
CoUninitialize();
}
回复
superrg 2002-01-23
http://www.csdn.net/Expert/topic/494/494363.shtm
知秋一叶,请你到上面的地址领分~~~~~
回复
qqchen79 2002-01-23
有点线索了,你不妨用Spy++看看Host MSHTML的程序,它会包含一个窗口叫IEHide什么的。
看来虽然只是Host了一个COM组件MSHTML,但还是要用消息循环,否则它没法正常工作。
我回写个例子出来试试的。:)
回复
相关推荐
发帖
非技术类
创建于2007-09-28

1621

社区成员

VC/MFC 非技术类
申请成为版主
帖子事件
创建了帖子
2002-01-23 12:24
社区公告
暂无公告