比方说我sink了DOCUMENTCOMPLETE,在页面加载完成后就产生下列错误。
错误:0xC0000005: Access violation reading location 0x00000024.HRESULT Lock() throw()
{
EnterCriticalSection(&m_sec); // 这里产生的
return S_OK;
}应该是临界区域未初始化造成的。但是调用这个应该是ATL内部的事情。如果是BeforeNavigate2事件,那就会在页面加载之前就产生上面的错误。原代码环境是,我只是单创建了一个sink类来响应DISPID_DOCUMENTCOMPLETE事件,
参考http://support.microsoft.com/kb/194179/en-usIWebBrowser2接口创建成功,
DispEventAdvise连接返回成功,
单就是对应事件产生后就报错了。很是想不通……
错误:0xC0000005: Access violation reading location 0x00000024.HRESULT Lock() throw()
{
EnterCriticalSection(&m_sec); // 这里产生的
return S_OK;
}应该是临界区域未初始化造成的。但是调用这个应该是ATL内部的事情。如果是BeforeNavigate2事件,那就会在页面加载之前就产生上面的错误。原代码环境是,我只是单创建了一个sink类来响应DISPID_DOCUMENTCOMPLETE事件,
参考http://support.microsoft.com/kb/194179/en-usIWebBrowser2接口创建成功,
DispEventAdvise连接返回成功,
单就是对应事件产生后就报错了。很是想不通……
解决方案 »
- VC下如何设置Tuxedo多线程调用(客户端)
- 我要模拟鼠标点击5秒才放请问该怎么实现呢?
- 鼠标拖动
- 要捕获控件的滚动条事件,影响响应哪个消息?
- 基于SNMP的在线主机性能监测与性能分析与基于PRTI的计算机网络通讯仿真
- vc程序中直接再运行某些程序?
- vc中如何在excel文档中设定颜色?
- 金山毒霸装完之后,它的目录和回收站目录图标都被改变了,怎么实现的?
- 关于PF使用率不断增加的问题
- 菜鸟求救:如何改变对话框各种控件的字体大小呢?各位帮帮忙吧!
- 注册ocx失败,提示说invalid access to memory location
- WM_LBUTTONDOWN和WM_NCLBUTTONDOWNE有什么区别
#include <windows.h>
#include <atlbase.h>
#include <atlwin.h>
#include <ExDispID.h>const UINT ID_WEBBROWSER = 100;//
//
//
class CMainWindow : public CWindowImpl<CMainWindow>,
public IDispEventImpl< ID_WEBBROWSER, CMainWindow >
{
public:
CMainWindow()
{
CWndClassInfo &wci = GetWndClassInfo(); if( !wci.m_atom )
{
// 使用系统光标
wci.m_bSystemCursor = TRUE;
} // 初始化
m_AxWindow = NULL;
m_pWebBrowser2 = NULL;
} virtual ~CMainWindow(){}
// 消息映射
BEGIN_MSG_MAP(CMainWindow)
MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
MESSAGE_HANDLER(WM_CREATE, OnCreate)
END_MSG_MAP() BEGIN_SINK_MAP(CMainWindow)
//Make sure the Event Handlers have __stdcall calling convention
SINK_ENTRY( ID_WEBBROWSER, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete )
END_SINK_MAP() // Event handler
void __stdcall OnDocumentComplete( IDispatch *, VARIANT* )
{
}private:
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
RECT rect;
GetClientRect(&rect);
// 创建宿主窗口
HWND hWndContainer = m_AxWindow.Create( m_hWnd, rect, NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL, 0, ID_WEBBROWSER ); if( !hWndContainer )
return -1; // 创建控件,初始化它,并且依附到宿主窗口
HRESULT hr;
hr = m_AxWindow.CreateControl( L"http://www.microsoft.com" ); if( FAILED( hr ) )
return -1; // 得到IWebBrowser2接口
hr = m_AxWindow.QueryControl( IID_IWebBrowser2, (void**)&m_pWebBrowser2 ); if( SUCCEEDED(hr) )
{
// 确保COM对象对应的pUnk实现IProvideClassInfo2或是IPersist*
// 当IDispEventImpl以两个参数形式被继承时,调用这个方法提取关于源类型库的信息
hr = AtlGetObjectSourceInterface( m_pWebBrowser2, &m_libid,
&m_iid, &m_wMajorVerNum, &m_wMinorVerNum ); if( FAILED(hr) )
return -1; // 连接接收器和来源,m_pWebBrowser2是源COM对象
hr = DispEventAdvise(m_pWebBrowser2, &m_iid);
if( FAILED(hr) )
return -1; CComBSTR url = L"http://www.microsoft.com"; hr = m_pWebBrowser2->Navigate( url,0,0,0,0 ); if( FAILED(hr) )
return -1;
} return 0;
} LRESULT OnDestroy(UINT , WPARAM , LPARAM , BOOL&)
{
// disconnect from source if connected
if( m_dwEventCookie != 0xFEFEFEFE )
DispEventUnadvise(m_pWebBrowser2, &m_iid); // 释放缓存的COM
m_pWebBrowser2.Release(); PostQuitMessage(0);
return 0;
}private:
//
CAxWindow m_AxWindow;
CComPtr<IWebBrowser2> m_pWebBrowser2; // 用于缓存COM接口
};//
//
//
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
CMainWindow wnd; wnd.Create( NULL, NULL, NULL, WS_OVERLAPPEDWINDOW ); if( !wnd )
return FALSE; wnd.CenterWindow();
wnd.ShowWindow( nCmdShow );
wnd.UpdateWindow(); MSG msg; // Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} return (int) msg.wParam;
}
“使用ATL”设置成“动态链接到ATL”。以上代码是可以直接编译,我所描述的问题就会出现了。
#include <atlbase.h>
CComModule _Module;#include <atlcom.h>
#include <atlwin.h>
#include <ExDisp.h>
#include <ExDispId.h>const UINT ID_WEBBROWSER = 100;//
//
//
class CMainWindow : public CWindowImpl<CMainWindow>,
public IDispEventImpl< ID_WEBBROWSER, CMainWindow >
{
public:
CMainWindow()
{
CWndClassInfo &wci = GetWndClassInfo(); if( !wci.m_atom )
{
// 使用系统光标
wci.m_bSystemCursor = TRUE;
} // 初始化
m_AxWindow = NULL;
m_pWebBrowser2 = NULL;
} virtual ~CMainWindow(){}
// 消息映射
BEGIN_MSG_MAP(CMainWindow)
MESSAGE_HANDLER( WM_DESTROY, OnDestroy )
MESSAGE_HANDLER(WM_CREATE, OnCreate)
END_MSG_MAP() BEGIN_SINK_MAP(CMainWindow)
//Make sure the Event Handlers have __stdcall calling convention
SINK_ENTRY( ID_WEBBROWSER, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete )
END_SINK_MAP() // Event handler
void __stdcall OnDocumentComplete( IDispatch *, VARIANT* )
{
MessageBox(TEXT("OnDocumentComplete"),TEXT("Message"),MB_ICONINFORMATION);
}private:
LRESULT OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
RECT rect;
GetClientRect(&rect);
AtlAxWinInit();
// 创建宿主窗口
HWND hWndContainer = m_AxWindow.Create( m_hWnd, rect, NULL, WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL, 0, ID_WEBBROWSER ); if( !hWndContainer )
return -1; // 创建控件,初始化它,并且依附到宿主窗口
HRESULT hr;
hr = m_AxWindow.CreateControl( L"http://www.sohu.com" ); if( FAILED( hr ) )
return -1; // 得到IWebBrowser2接口
hr = m_AxWindow.QueryControl( IID_IWebBrowser2, (void**)&m_pWebBrowser2 ); if( SUCCEEDED(hr) )
{
// 确保COM对象对应的pUnk实现IProvideClassInfo2或是IPersist*
// 当IDispEventImpl以两个参数形式被继承时,调用这个方法提取关于源类型库的信息
hr = AtlGetObjectSourceInterface( m_pWebBrowser2, &m_libid,
&m_iid, &m_wMajorVerNum, &m_wMinorVerNum ); if( FAILED(hr) )
return -1; // 连接接收器和来源,m_pWebBrowser2是源COM对象
hr = DispEventAdvise(m_pWebBrowser2, &m_iid);
if( FAILED(hr) )
return -1; if( FAILED(hr) )
return -1;
} return 0;
} LRESULT OnDestroy(UINT , WPARAM , LPARAM , BOOL&)
{
// disconnect from source if connected
if( m_dwEventCookie != 0xFEFEFEFE )
DispEventUnadvise(m_pWebBrowser2, &m_iid); // 释放缓存的COM
m_pWebBrowser2.Release(); PostQuitMessage(0);
return 0;
}private:
//
CAxWindow m_AxWindow;
CComPtr<IWebBrowser2> m_pWebBrowser2; // 用于缓存COM接口
};//
//
//
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
_Module.cbSize = sizeof(_Module);
AtlModuleInit(&_Module,NULL,hInstance); CMainWindow wnd; RECT rect = {0,0,480,320};
wnd.Create( NULL, rect, NULL, WS_OVERLAPPEDWINDOW ); if( !wnd )
return FALSE; wnd.CenterWindow();
wnd.ShowWindow( nCmdShow );
wnd.UpdateWindow(); MSG msg; // Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} return (int) msg.wParam;
}