none
VC与网页交互的问题 RRS feed

  • 问题

  • 对这块不熟,花了很长时间在网上找资料,理解不清楚,请教大家。

    我想写个程序实现以下功能:在后台打开某网页,自动填写表单并提交。提交后的网页在前台显示。

    搜索到的资料大部分使用到了IHTMLDocument,但是不太明白。是如何打开某网页的,又是如何取得IHTMLDocument对象的等。

    2010年1月4日 18:55

答案

  • pDoc2->get_title(&buf);
    改成:
    HRESULT hr = pDoc2->get_title(&buf);
    看看hr 是不是等于S_OK 呢? 检查一下错误代码。
    • 已标记为答案 Nancy Shao 2010年1月25日 7:20
    2010年1月6日 12:25
    版主

全部回复

  • 什么是后台?你说的方法在服务和工作线程内不支持。

    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP
    2010年1月4日 19:54
    版主
  • 如果你想在用户看不见的情况下,提交数据,并显示最后结果,可以这么做:


    1) 与Web页面开发人员商定一个接口,比如通过查询串的方式向页面传递数据。对于敏感数据,还可以商定数据加密方式

    2) 组装一个请求字符串,包括 域名?查询串,比如: http://cn.bing.com/?srf=&fdr=lc 数据通过查询串传递

    3)  通过WebBrowser 的IWebBrowser2 接口的Navigate 方法访问这个查询串

    4)  Web 页面收到数据后,进行处理,处理结束后,将请求重定向至结果页面

    5)  此时用户只会看到处理结果


    数据可以通过POST 方式放入请求的Header中,也可以使用查询串的方式。 暂时用不着IHTMLElement 接口

    2010年1月5日 3:11
    版主
  • 实际上我想实现的功能就是自动填写网页表单并提交。

    2010年1月5日 5:06
  • 能否仅使用函数中调用API的方式实现呢?不使用类。
    2010年1月5日 5:10
  • 简单的办法是,通过HttpAnalyzer 或者WireShark 截包,看看HTTP Header 里面POST 的数据。 按照样子自己组装HTTP Header,然后用WebBrowser 把数据POST到Web服务器上。
    2010年1月5日 5:12
    版主
  • 还要继续学习。

    #include <mshtml.h>
    #include <atlbase.h>
    #include <oleacc.h>
    #include <comutil.h>
    
    BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
    {
    	TCHAR	buf[100];
    
    	::GetClassName( hwnd, (LPTSTR)&buf, 100 );
    	if ( _tcscmp( buf, _T("Internet Explorer_Server") ) == 0 )
    	{
    		*(HWND*)lParam = hwnd;
    		return FALSE;
    	}
    	else
    		return TRUE;
    };
    
    //You can store the interface pointer in a member variable 
    //for easier access
    IHTMLDocument2* OnGetDocInterface(HWND hWnd)//hWnd为IE窗口句柄
    {
    	CoInitialize( NULL );
    
    	// Explicitly load MSAA so we know if it's installed
    	HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") );
    	IHTMLDocument2* pDoc2 = NULL;
    	if ( hInst != NULL )
    	{
    		if ( hWnd != NULL )
    		{
    			HWND hWndChild=NULL;
    			// Get 1st document window
    			::EnumChildWindows( hWnd, EnumChildProc, (LPARAM)&hWndChild );	//根据父窗口hWnd调用EnumChildProc枚举子窗口。
    																			//将子窗口hWndChild地址作为参数传给EnumChildProc。
    			if ( hWndChild )
    			{
    				CComPtr<IHTMLDocument2> spDoc;//CComPtr智能指针,确保COM接口指针严格并且正确的执行AddRef和Release。
    				LRESULT lRes;
    			
    				//由于WM_HTML_GETOBJECT非Windows标准消息,所以需要RegisterWindowMessage。
    				UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
    				::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes );//?
    
    				LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, _T("ObjectFromLresult") );
    				if ( pfObjectFromLresult != NULL )
    				{
    					HRESULT hr;
    					hr = (*pfObjectFromLresult)( lRes, IID_IHTMLDocument, 0, (void**)&spDoc );//通过函数指针调用函数
    					if ( SUCCEEDED(hr) )
    					{
    						// Change background color to red
    						//spDoc->put_bgColor( CComVariant("red") );
    						//pDoc2 = spDoc;
    						CComPtr<IDispatch> spDisp;   
    						CComQIPtr<IHTMLWindow2> spWin;   
    						spDoc->get_Script(&spDisp);   
    						spWin = spDisp;
    						spWin->get_document(&pDoc2);
    					}
    				}
    			} // else document not ready
    			else
    			{
    				MessageBox(NULL, _T("Not Found Doc Error"), _T("Error"), MB_OK);
    			}
    		} // else Internet Explorer is not running
    		else
    		{
    			MessageBox(NULL, _T("Not Found IE Error"), _T("Error"), MB_OK);
    		}
    		::FreeLibrary( hInst );
    	} // else Active Accessibility is not installed
    	else
    	{
    		MessageBox(NULL, _T("MSAA Error"), _T("Error"), MB_OK);
    	}
    	CoUninitialize();
    	return pDoc2;
    }
    
    int _tmain(int argc, char* argv[])
    {
    	IHTMLDocument2* pDoc2 = OnGetDocInterface(FindWindow(_T("IEFrame"), NULL));
    	if(pDoc2 == NULL)
    	{
    		MessageBox(NULL, _T("Doc NULL Error"), _T("Error"), MB_OK);
    	}
    	else
    	{
    		BSTR buf = SysAllocStringLen(NULL, 1000);
    		ZeroMemory(buf, sizeof(buf));
    		pDoc2->get_title(&buf);
    		MessageBox(NULL, _com_util::ConvertBSTRToString(buf), _T("Error"), MB_OK);
    	}
    	return 0;
    }
    请教这段代码,调试发现pDoc2应该是取得了IE的Document对象了的,只是_tmain中那个else块,发现MessageBox是空。pDoc2->get_title(&buf);怎么会没拿到title呢?
    2010年1月5日 8:46
  • pDoc2->get_title(&buf);
    改成:
    HRESULT hr = pDoc2->get_title(&buf);
    看看hr 是不是等于S_OK 呢? 检查一下错误代码。
    • 已标记为答案 Nancy Shao 2010年1月25日 7:20
    2010年1月6日 12:25
    版主
  • 建意你用 webBrowser
    BOOL CWebBrowserView::InPutString(TCHAR* String)
    {
     IHTMLDocument2*pHTMLDocument2=(IHTMLDocument2*)GetHtmlDocument();
     IHTMLElementCollection* pColl = NULL;
     HRESULT hr;
     hr = pHTMLDocument2->get_all(&pColl);
     if(hr == S_OK)
     {
      LONG celem;
      hr = pColl->get_length(&celem);
      if(hr==S_OK)
      {
       VARIANT varIndex,var2;
       for(int i=0;i<celem;i++)
       {
        varIndex.vt=VT_UINT;
        varIndex.lVal=i;
        VariantInit(&var2);
        IDispatch* pDisp;
        hr=pColl->item(varIndex,var2,&pDisp);
        if(hr==S_OK)
        {
         IHTMLElement*pElem;
         hr=pDisp->QueryInterface(IID_IHTMLElement,(void**)&pElem);
         if(hr==S_OK)
         {
          MSHTML::IHTMLInputElementPtr pInput(pDisp);
          if(pInput) 
          { 
           BSTR bstrtype; 
           pInput->get_type(&bstrtype);//获取input type 值 <input type="text"  name="u" id="input" class="urlinput" size="40">
           if(StrCmpW(bstrtype,L"text")==0) //比较 type
           {
            MSHTML::IHTMLElementPtr e(pInput);
            _variant_t val;
            val=e->getAttribute(_bstr_t(L"id"),0);//获取id值
            if (wcscmp(val.bstrVal,L"input")==0)//比较id
            {
             pInput->put_value(_bstr_t(String));//输入值
            }
           }
           SysFreeString(bstrtype);
          }
         }
        }
       }
      }
     }
     return TRUE;
    }
    
    2010年2月10日 3:17