none
DispEventAdvise 引起的硬件问题 RRS feed

  • 问题

  • 在使用DispEventAdvise挂接IE事件之后,发现部分硬件设备工作不正常,例如二维码扫描,POS机等,具体表现为,在挂接的IE页面使用以上设备时,扫描或者读取的字符时,偶尔会丢失几个字符,并且是无规律的。

    但是如果直接使用浏览器控件创建的自定义浏览器则没有此问题。

    PS:挂接事件后没有做任务操作,任何IE事件都没重新实现的。

    2016年5月10日 5:58

全部回复

  • >>偶尔会丢失几个字符,并且是无规律的

    有时候是可以正常读的,我觉得应该是程序的bug导致的。DispEventAdvise这个函数有没有正常的返回(在正常读取数据,和不正常读取数据时).可以提供更多的信息,来解决问题吗?


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    2016年5月10日 7:44
    版主
  • 感谢回复。DispEventAdvise是正常返回的S_OK,而且就一次挂接动作,后期任务IE的操作都没进我程序的断点了,扫描时也不进程序的消息队列,程序没其它处理,就是

    class CEventSink : 
    public IDispEventImpl<0, CEventSink, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>

    {

    .....

    .....

    ....

    };

    之后是一个按钮事件:

    CEventSink * m_EventSink = new CEventSink();
    HRESULT hr = m_EventSink->DispEventAdvise(pWebBrowser2);

    我尝试过用winform代码实现,丢失字符的现象更严重


    2016年5月10日 9:11
  • 附上主要代码:

    // EventSink.h
    
    
    class CEventSink : 
    	public IDispEventImpl<0, CEventSink, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>
    {
    
    public:
    	CEventSink();  
    
    	virtual ~CEventSink();
    };
    
    
    // REDTestDlg.h
    
    HWND mMainHwnd = NULL;
    
    static UINT WM_SHELLHOOKMESSAGE;
    
    static BOOL CALLBACK EnumChildProc(HWND hwnd, LPARAM lParam)
    {
    	char szStr[256];
    
    	GetClassName( hwnd, (LPSTR)&szStr, 256 );
    
    	CString str;
    
    	str.Format("%s", szStr);
    
    	if ( str == "Internet Explorer_Server"  )
    	{
    		SendMessage(mMainHwnd, WM_MY_BIND, 0, (LPARAM)hwnd);
    		//*(HWND*)lParam = hwnd;
    		//return FALSE;
    	}
    
    	return TRUE;
    }
    
    static BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) 
    { 
    	DWORD dwCurProcessId = *((DWORD*)lParam); 
    	DWORD dwProcessId = 0; 
    
    	GetWindowThreadProcessId(hwnd, &dwProcessId); 
    	if(dwProcessId == dwCurProcessId && GetParent(hwnd) == NULL && IsWindowVisible(hwnd)
    		&& IsWindow(hwnd))
    	{ 
    		*((HWND *)lParam) = hwnd;
    		return FALSE; 
    	} 
    	return TRUE; 
    } 
    
    static void GetWindowHandleByPID(DWORD dwProcessID)
    {
    	DWORD dwPID,dwThreadID;
    
    	HWND pWnd = FindWindow( NULL, NULL);
    
    	while( NULL != pWnd )
    	{
    		dwThreadID = GetWindowThreadProcessId( pWnd, &dwPID );
    
    		char szStr[256];
    
    		GetClassName( pWnd, (LPSTR)&szStr, 256 );
    
    		CString str;  
    
    		str.Format("%s", szStr);
    
    		if( (0 != dwThreadID && dwProcessID == dwPID) || str == "Internet Explorer_TridentDlgFrame")
    		{
    			if (IsWindow(pWnd))
    			{
    				EnumChildWindows(pWnd, EnumChildProc, NULL);
    			}
    		}
    		pWnd = GetNextWindow(pWnd, GW_HWNDNEXT);
    	}
    }
    
    BEGIN_MESSAGE_MAP(CREDTestDlg, CDialog)
    	ON_WM_PAINT()
    	ON_WM_QUERYDRAGICON()
    	//}}AFX_MSG_MAP
    	ON_BN_CLICKED(IDOK, &CREDTestDlg::OnBnClickedOk)
    	ON_BN_CLICKED(IDCANCEL, &CREDTestDlg::OnBnClickedCancel)
    
    	ON_MESSAGE(WM_MY_BIND, &CREDTestDlg::OnBind)
    END_MESSAGE_MAP()
    
    // CREDTestDlg 消息处理程序
    
    BOOL CREDTestDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
    	//  执行此操作
    	SetIcon(m_hIcon, TRUE);
    	// 设置大图标
    	SetIcon(m_hIcon, FALSE);
    	// 设置小图标
    
    	// TODO: 在此添加额外的初始化代码
    
    	mMainHwnd = this->GetSafeHwnd();
    
    	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
    }
    
    
    LRESULT CREDTestDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
    {
    	// TODO: 在此添加专用代码和/或调用基类
    
    	if(message == WM_SHELLHOOKMESSAGE)
    	{
    		if(wParam == HSHELL_WINDOWCREATED)
    		{
    			Sleep(800);
    			HWND hwnd = (HWND)lParam;
    			HWND childHwnd = NULL;
    			EnumChildWindows(hwnd, EnumChildProc, (LPARAM)&childHwnd);
    		}
    
    		if(wParam == HSHELL_WINDOWACTIVATED)
    		{
    			Sleep(100);
    
    			HWND hwnd = (HWND)lParam;
    			DWORD dwProcessId; 
    
    			GetWindowThreadProcessId(hwnd, &dwProcessId);
    			GetWindowHandleByPID(dwProcessId);
    		}
    	}
    
    	return CDialog::WindowProc(message, wParam, lParam);
    
    }
    
    void CREDTestDlg::OnBnClickedOk()
    {
    	// TODO: 在此添加控件通知处理程序代码
    
    	WM_SHELLHOOKMESSAGE = RegisterWindowMessage("SHELLHOOK");
    
    	RegisterShellHookWindow(mMainHwnd);
    }
    
    void CREDTestDlg::OnBnClickedCancel()
    {
    	DeregisterShellHookWindow(mMainHwnd);
    
    	OnCancel();
    }
    
    LRESULT CREDTestDlg::OnBind(WPARAM wParam, LPARAM lParam)
    {
    
    	HWND hwnd = (HWND)lParam;
    
    	if(hwnd)
    	{
    		GetDocInterface(hwnd);
    	}
    
    	return 0;
    }
    
    void CREDTestDlg::GetDocInterface(HWND hwnd)
    {
    	CoInitialize(NULL);
    
    	if(hwnd)
    	{
    		HWND hWndChild = hwnd;
    
    		if(hWndChild)
    		{
    			LRESULT lRes;
    			LRESULT lResult;
    
    			UINT m_nMsg = ::RegisterWindowMessage(TEXT("WM_HTML_GETOBJECT"));
    			lResult = ::SendMessageTimeout(hWndChild, m_nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes);
    
    			if(lResult)
    			{
    				HINSTANCE m_hInst = ::LoadLibrary(TEXT("OLEACC.DLL"));
    
    				if(m_hInst != NULL)
    				{
    
    					LPFNOBJECTFROMLRESULT m_pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress(m_hInst, "ObjectFromLresult");
    
    					if (m_pfObjectFromLresult != NULL)
    					{
    						HRESULT hr;
    						CComQIPtr<IHTMLDocument2> spDoc;
    						hr = (*m_pfObjectFromLresult)( lRes, IID_IHTMLDocument2, 0, (void**)&spDoc);
    
    						if (SUCCEEDED(hr) && spDoc)
    						{
    							CComQIPtr<IHTMLWindow2> spWnd2;
    							CComQIPtr<IServiceProvider> spServiceProv;
    
    							hr = spDoc->get_parentWindow(&spWnd2);
    
    							if(SUCCEEDED(hr) && spWnd2)
    							{
    
    								hr=spWnd2->QueryInterface(IID_IServiceProvider,(void**)&spServiceProv);
    
    								spWnd2.Release();
    
    								if(SUCCEEDED(hr) && spServiceProv)
    								{
    
    									CComQIPtr<IWebBrowser2> pWebBrowser2;
    
    									hr = spServiceProv->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, (void**)&pWebBrowser2);
    
    									spServiceProv.Release();
    
    									if(SUCCEEDED(hr) && pWebBrowser2)
    									{
    
    										CEventSink * m_EventSink = new CEventSink();
    										m_EventSink->DispEventAdvise(pWebBrowser2);
    									}
    								}
    							}
    						}
    
    						::FreeLibrary(m_hInst);
    					}
    				}
    
    			}
    		}
    	}
    
    	CoUninitialize();
    
    }
    
    


    2016年5月11日 1:12
  • 感谢回复。DispEventAdvise是正常返回的S_OK,而且就一次挂接动作,后期任务IE的操作都没进我程序的断点了,扫描时也不进程序的消息队列,程序没其它处理,

    挂接之后,程序都没有进入你的程序断点?你确定你挂接是成功的吗?程序都没有走到,那获取错误的值,我觉得没什么奇怪的。

    应该检查一下,挂接有没有成功?如果可能你最好能提供一份demo 给我们,为了测试这个问题.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    2016年5月11日 2:59
    版主
  • 好的,那请问怎么发给你呢?
    2016年5月11日 4:48
  • 你好,请问这个问题有好解决办法了么
    2016年5月30日 9:17
  • 好的,那请问怎么发给你呢?


    你好,可以把代码发送到https://onedrive.live.com/ 


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    2016年5月30日 9:21
    版主