標籤:des style blog color 使用 os
現在大部分瀏覽器都已經實現了網頁的功能,我要說的與這種情況稍有不同,瀏覽器是從內部擷取,而因為我是ActiveX外掛程式,需要從外部擷取網頁的document。但是,實現的思路基本一致,就是將Webbrowser放大到足夠大,使捲軸不出現,然後調用IViewObject介面的Draw方法實現整頁的。下面先給出代碼實現,再對代碼進行分析。
1 POINT pnt; 2 3 RECT rc; 4 5 HWND DeskHwnd = ::GetDesktopWindow(); //取得案頭控制代碼 6 7 HDC DeskDC = ::GetWindowDC(DeskHwnd); //取得電腦裝置情境dc 8 9 int oldRop2 = SetROP2(DeskDC, R2_NOTXORPEN); 10 11 ::GetCursorPos(&pnt);//取得滑鼠座標 12 13 HWND UnHwnd = ::WindowFromPoint(pnt) ; //取得滑鼠指標處視窗控制代碼,這裡擷取到的是Webbrowser控制項的視窗控制代碼 14 15 m_ptWnd=UnHwnd; 16 17 HDC pdc=::GetWindowDC(m_ptWnd);//擷取目標視窗DC用於 18 19 //----------------以下擷取IWebBrowser2介面------------------------- 20 21 CComPtr<IOleClientSite> spClientSite; 22 23 HRESULT hr; 24 25 long iHeight,iWidth; 26 27 hr=GetSite(IID_IUnknown,(void**)&spClientSite); 28 29 CComPtr<IServiceProvider> isp, isp2; 30 31 IViewObject* spIViewObject; 32 33 hr = spClientSite->QueryInterface(IID_IServiceProvider, (void**)(&isp)); 34 35 if (SUCCEEDED(hr)) 36 37 { 38 39 hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, (void**)(&isp2)); 40 41 if (SUCCEEDED(hr)) 42 43 { 44 45 CComPtr<IWebBrowser2> spBrowser; 46 47 hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, (void**)(&spBrowser)); 48 49 if (SUCCEEDED(hr)) 50 51 { 52 53 //------------------------從擷取到的IWebBrowser2介面中擷取IHTMLDocument2介面------------------ 54 55 IHTMLDocument2* pHtmlDocument2; 56 57 CComPtr<IDispatch> spDisp; 58 59 spBrowser->get_Document(&spDisp); 60 61 spDisp->QueryInterface(IID_IHTMLDocument2,(void**)&pHtmlDocument2);//擷取IHTMLDocument2介面文檔 62 63 IHTMLElement* pElement; 64 65 pHtmlDocument2->get_body(&pElement);//擷取IHTMLElement介面文檔 66 67 IHTMLElement2* pElement2; 68 69 pElement->QueryInterface(IID_IHTMLElement2, (void**)&pElement2);//擷取IHTMLElement2介面文檔 70 71 pElement2->get_scrollHeight(&iHeight); //擷取網頁實際高度 72 73 pElement2->get_scrollWidth(&iWidth); //擷取網頁實際寬度 74 75 //------------------以下準備合適大小的圖片------------------------ 76 77 //HDC pdc2=::GetWindowDC(m_ptWnd); 78 79 HDC hIEMenDC2=::CreateCompatibleDC(DeskDC); 80 81 HBITMAP hIEBitmap2=::CreateCompatibleBitmap(DeskDC,iWidth,iHeight); 82 83 ::SelectObject(hIEMenDC2,hIEBitmap2); 84 85 //------------------以下調整Webbrowser大小以截取全頁--------------- 86 87 long oldHeight,oldWidth; 88 89 CRect oldrect; 90 91 ::GetWindowRect(m_ptWnd,&oldrect);//調整前先記錄下原來的大小,以便最後還原 92 93 oldHeight=oldrect.Height(); 94 95 oldWidth=oldrect.Width(); 96 97 HWND m_parentWnd=::GetParent(m_ptWnd);//**************想要改變webbrowser的大小必須擷取宿主視窗的控制代碼,改變宿主視窗的大小,這裡被坑了好久,要注意!************* 98 99 BOOL flag=::MoveWindow(m_parentWnd,0,0,iWidth,iHeight,TRUE);//改變宿主視窗的大小到合適的大小100 101 flag=::MoveWindow(m_ptWnd,0,0,iWidth,iHeight,TRUE);//改變webbrowser視窗的大小到合適的大小102 103 //------------------以下對網頁進行-----------------------------104 105 //------------------方法一:擷取IViewObject介面,調用Draw方法--106 107 IViewObject* pViewObject;108 109 //------------------------從擷取到的IWebBrowser2介面中擷取IHTMLDocument2介面------------------110 111 pHtmlDocument2->QueryInterface(IID_IViewObject,(void**)&pViewObject);112 113 pHtmlDocument2->get_body(&pElement);//擷取IHTMLElement介面文檔114 115 // pElement->QueryInterface(IID_IHTMLElementRender, (void **) &pRender);116 117 IHTMLBodyElement* pBodyElement;118 119 pElement->QueryInterface(IID_IHTMLBodyElement,(void**)&pBodyElement);120 121 BSTR oldscrolltype;122 123 pBodyElement->get_scroll(&oldscrolltype);124 125 pBodyElement->put_scroll(_T("no"));//去掉捲軸126 127 RECTL rectl;128 129 rectl.left=0;rectl.top=0;rectl.right=iWidth;rectl.bottom=iHeight;130 131 pViewObject->Draw(DVASPECT_CONTENT,1,NULL,NULL,NULL,hIEMenDC2,&rectl,NULL,NULL,NULL);132 133 //------------以下還原瀏覽器位置和捲軸,並儲存圖片134 135 pBodyElement->put_scroll(oldscrolltype);136 137 flag=::MoveWindow(m_ptWnd,0,0,oldWidth,oldHeight,TRUE);138 139 flag=::MoveWindow(m_parentWnd,0,0,oldWidth,oldHeight,TRUE);140 141 SaveToFile(_T(""),hIEBitmap2);142 143 }144 145 }146 147 }
首先,要想操作Webbrowser就要擷取IWebBrowser2介面,如果是瀏覽器實現該功能可以直接擷取,而在ActiveX中就要用別的方法從外部擷取,擷取的方法很多,這裡只介紹我使用的方法:
1、使用GetSite函數擷取IOleClientSite介面。
2、通過IOleClientSite介面擷取IServiceProvider介面。
3、使用QueryService擷取頂層WebBrowser,hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, (void**)(&isp2));
4、使用QueryService擷取IWebBrowser2介面。
這裡不探討為什麼要這麼擷取,我也不是很清楚,只知道通過這種方法可以從外部擷取頂層WebBrowser的IWebBrowser2介面。
然後,在擷取了IWebBrowser2介面後,我們就可以開始通過它操作WebBrowser了。要想截全圖,當然需要知道網頁的實際大小,可以通過下面的順序來擷取IHTMLElement2介面:
IWebBrowser2-->IHTMLDocument2-->IHTMLElement-->IHTMLElement2
擷取了IHTMLElement2介面後就可以通過get_scrollHeight和get_scrollWidth擷取網頁的高和寬了。得到網頁實際大小後就可以用MoveWindow改變WebBrowser的大小了,但這裡需要注意的是,如果只是改變WebBrowser的大小並不一定能夠將網頁放大,還需要將它的宿主視窗也一起放大才可以~本人之前一直無法把WebBrowser放大,最後發現是這個原因,切記,切記!
最後,前面的準備工作做完之後,就可以通過IHTMLDocument2介面擷取IViewObject介面了,然後調用Draw方法就可以把整個網頁的內容儲存到記憶體DC中了。這樣截取到的圖片中還是會有不能滾動的捲軸圖案在,如果覺得礙眼想要把它去掉的話也是有辦法的,那就是修改body元素了,通過前面擷取的IHTMLDocument2介面,可以通過get_body方法擷取body的IHTMLElement然後擷取IHTMLBodyElement然後通過put_scroll方法修改捲軸。截完圖後記得把原來的屬性設定回去!