1. 程式人生 > >使用MFC開發網頁提取程式的經驗總結

使用MFC開發網頁提取程式的經驗總結

          最近開發了一個在網頁內提取頁面資訊併發往後臺進行處理的資料庫,在開發的過程中遇到了一些問題,獲得了一些經驗,在此先感謝下CSDN上的大神的無私分享。

          在專案之初,想在一個程式的基礎上修改,由於原來的程式碼是在vc6.0下寫成的,而我的開發環境是vs2008,關於vc6.0下的專案轉換成vs2008專案可能產生的問題以及解決方案如下:

          在將vs轉換之後,發現IHTMLDocument4無法找到,查詢原因為sdk版本過低,vc6.0自帶的sdk不支援IHTMLDocument3其以後的物件,因此需要升級sdk;下載並配置sdk的方法如下:http://blog.csdn.net/alvetjook/article/details/1444529

         配置完之後,可以調整各路徑與原有路徑的前後次序,因為編譯和連線的時候是按照順序尋找相應的include和lib。為了保證用上最新的,你可以把路徑放在原來的配置中vc6自帶的sdk路徑前面。如果把新加入的標頭檔案.h和庫檔案.lib放到第一位置,這時候會抱一個錯誤,具體的錯誤提示沒記錄下來,網上找的解決方案如下:fatal error LNK1103: debugging information corrupt; recompile module的解決方案:

 把lib檔案的位置下移,但這會引起另一個錯誤,原因在於他用的是新版sdk的標頭檔案,但是首先使用的還是舊版sdk的cpp檔案,導致錯誤,正確的解決方案的地址忘了,解決方法:
在網上找了很久,大夥都是講的除錯VC6工程時出現這個錯誤的情況。是要把Tool -> Options -> Directories(VC6是這個,VS的是Tools -> Options -> Projects and Solutions -> VC++ Directories),將Include files和Library files中SDK的順序放到最下邊或者直接刪掉較新的SDK。此方法對我遇到的錯誤無效。
在微軟網站找到這個

http://support.microsoft.com/kb/974193/。說錯誤的原因是連結器(linker)的bug導致了這個錯誤的產生。要解決這個問題只要關閉工程的程式資料庫(program database,PDB)檔案的生成即可。操作如下:
在Solutions Explorer中選中工程,點右鍵選Properties -> Linker -> Debugging,把Generate Debug Info選項改為No.這樣就OK了。http://blog.csdn.net/duanjingneuq/article/details/5588050

       由於轉換的專案存在一些因為轉換和相容性導致的煩人問題,決定改用vs2008重寫。

      1,如何在建立托盤程式

      在OnInitDialog()函式中新增如下程式碼

//新增系統托盤wenzi2013 0705

CString title;
 title.Format("頁面資訊提取比對系統");

char lpszTip[256];
 strcpy_s(lpszTip,255,(char *)(LPCTSTR)title);
 NOTIFYICONDATA data;
 data.cbSize = sizeof(NOTIFYICONDATA);
 data.hWnd   = m_hWnd;
 strcpy(data.szTip,lpszTip);
 data.uCallbackMessage = WM_ONTRAY;
 data.uFlags           = NIF_MESSAGE | NIF_ICON | NIF_TIP;
 m_hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
 data.hIcon            = m_hIcon;
 data.uID              = IDI_ICON1;
 Shell_NotifyIcon(NIM_ADD,&data);

     2,CString轉換到陣列

      新增上述托盤之後,會發現托盤的標題後面給了很多亂碼,這主要是由於編碼的不同導致的,解決方法如下:

    3,如何在選單中加入圖示

    //對選單項加入圖示 wenzi20130707
CBitmap *pMenuBitmap/*,*pMenuBitmapun*/;
 pMenuBitmap = new CBitmap;
  pMenuBitmap->LoadBitmap(IDB_BITMAP1);//需要載入的圖示資源
 CMenu *pchildMenu; 
 pchildMenu = m_Menu.GetSubMenu(0);//子選單,0代表主選單的第一個子選單 
 pchildMenu->SetMenuItemBitmaps(0,MF_BYPOSITION| MF_STRING| MF_ENABLED,pMenuBitmap, pMenuBitmap);

    4,托盤處理函式OnTray

OnTray(WPARAM wParam, LPARAM lParam)//托盤處理函式 wenzi20130705
{
 UINT uMouseMsg = (UINT) lParam;
 if(uMouseMsg == WM_RBUTTONDOWN)
 {
  CMenu* pPopup = m_Menu.GetSubMenu(0);
  CPoint point;
  GetCursorPos(&point);
  pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_VERTICAL,
   point.x,point.y,AfxGetApp()->m_pMainWnd,TPM_LEFTALIGN);   
 }
 if(uMouseMsg == WM_LBUTTONDBLCLK)     //雙擊滑鼠
 {
  if(m_bFlag)
  {
   ShowWindow(SW_HIDE); //隱藏視窗的顯示 wenzi20130718 
   m_bFlag=!m_bFlag;
   m_Menu.GetSubMenu(0)->CheckMenuItem(ID_HideWindow,MF_CHECKED|MF_BYCOMMAND);
   
   //修改選單項的標題

  }
  else
  {
   ShowWindow(SW_SHOWNOACTIVATE);    //恢復視窗的顯示 
   m_bFlag=!m_bFlag;
   m_Menu.GetSubMenu(0)->CheckMenuItem(ID_HideWindow,MF_UNCHECKED|MF_BYCOMMAND );

  }
  
 }
 return NULL ;//wenzi 20130704
}

 5,托盤系統的關閉函式OnClose

void CIEInputMonitor_vcDlg::OnClose()
{
 // TODO: Add your message handler code here and/or call default

 // wenzi 20130705
 if(MessageBox(_T("確認要退出稽核校驗系統嗎?"),_T("系統提示"),MB_OKCANCEL|MB_ICONQUESTION)!=IDOK)
  return;
 //刪除系統托盤
 NOTIFYICONDATA data;
 data.cbSize = sizeof(NOTIFYICONDATA);
 data.hWnd   = m_hWnd;
 Shell_NotifyIcon(NIM_DELETE,&data);
 CDialog::OnClose();
}

在此請教一個問題,當我在OnExit()中直接呼叫OnClose無法關閉視窗,我大概知道是訊息的傳送和處理機制導致的,想知道詳情,有知道的大神望不吝賜教。

 6,如何拖動無標題欄的對話方塊

不過這種方式比較麻煩;

另一種方式是:在PreTranslateMessage(MSG* pMsg)函式中,加入以下程式碼:

PreTranslateMessage(MSG* pMsg)
{
 // TODO: Add your specialized code here and/or call the base class
 CPoint point;
 GetCursorPos(&point);
 if(pMsg->message == WM_LBUTTONDOWN && pMsg->hwnd == m_hWnd)
 {
  PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));//保證無邊框時能被滑鼠拖動 wenzi20130717
 }
 return CDialog::PreTranslateMessage(pMsg);
}

或者在OnLbuttondown中加入

 PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(point.x,point.y));

7 ,Tab Control控制元件的使用

    8,如何修改視窗的背景

    新增OnEraseBkgnd(CDC* pDC)函式;

OnEraseBkgnd(CDC* pDC)
{
 // TODO: Add your message handler code here and/or call default
 CDialog::OnEraseBkgnd(pDC);
 CRect RDlg;
 GetClientRect(&RDlg);
   //CDC* pDC = GetDC();
 pDC->SetBkMode(TRANSPARENT);
 CBitmap DlgBK;
 DlgBK.LoadBitmap(IDB_BACKGROUND);//採用點陣圖拉昇平鋪的方法設定背景 wenzi20130717
 BITMAP Size;
 DlgBK.GetBitmap(&Size);
 CDC memdc;
 memdc.CreateCompatibleDC(pDC);
 memdc.SelectObject(&DlgBK);
 pDC->StretchBlt(RDlg.left,RDlg.top,RDlg.right,RDlg.bottom,&memdc,0,0,Size.bmWidth,Size.bmHeight,SRCCOPY);
 DlgBK.DeleteObject();


 return TRUE;
}

  在此處採用了雙快取來載入背景,防止視窗可能出現的閃爍,關於閃爍和雙快取。

   在此處個人覺得把程式碼放在OnPaint中也可以,不過要放在CDialog::OnPaint()之前;不然會出現背景遮蓋控制元件的情況。

9 如何設定控制元件背景為透明

 上述方法還是會存在一些重影的問題,如果要求不高,可以接受。

  10,如何更改Tab空間的背景和標題

這種方法我用了不太成功,我想設定一個位圖背景,在切換選項卡時會出現背景遮蓋了控制元件上的標題。調整的方法是:

派生自己的tabcontrol類,過載

BOOL CMyTabCtrl::OnEraseBkgnd(CDC* pDC)
{
 // TODO: Add your message handler code here and/or call default
 CTabCtrl::OnEraseBkgnd(pDC);
 
 CRect RDlg;
 GetClientRect(&RDlg);
 RDlg.InflateRect(2,0);
 
  //CBitmap DlgBK;//採用點陣圖拉昇平鋪的方法設定背景 wenzi20130717
  CDC memdc;
  memdc.CreateCompatibleDC(pDC);
  HBITMAP holdBMP=(HBITMAP)memdc.SelectObject(&m_hBK);
  pDC->SetBkMode(TRANSPARENT);

  BITMAP Size;
  m_hBK.GetBitmap(&Size);
  pDC->StretchBlt(RDlg.left,RDlg.top,RDlg.right,RDlg.bottom,&memdc,0,0,Size.bmWidth,Size.bmHeight,SRCCOPY);
  memdc.SelectObject(holdBMP);


 return TRUE;
}

通過該函式設定tab控制元件的背景,

再過載

void CMyTabCtrl::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct)//主要用來設定tab控制元件的標籤標題。
{
 ;
  TC_ITEM     tci;
  CString     szTabText;

  switch (lpDrawItemStruct->itemID)
  {
  case 0:
   szTabText=_T("發票驗舊");
   //DrawTabItem(lpDrawItemStruct);
   break;
  case 1:
   szTabText=__T("資料稽核");
   //DrawTabItem(lpDrawItemStruct);
   break;
  case 2:
   szTabText=__T("發票銷售");
   //DrawTabItem(lpDrawItemStruct);
   break;
  }

  CDC *dc = CDC::FromHandle(lpDrawItemStruct->hDC);
  //dc->SetBkColor(RGB(233,136,220));
  dc->SetBkMode(TRANSPARENT);//設定dc的背景為透明 wenzi20130718
  dc->SetTextColor(RGB(255,0,0));
 
  tci.mask        = TCIF_TEXT;
  tci.pszText     = szTabText.GetBuffer();
  tci.cchTextMax  = sizeof(szTabText)-1;
  GetItem(lpDrawItemStruct->itemID, &tci);
  //TextOut(lpDrawItemStruct->hDC,lpDrawItemStruct->rcItem.left,lpDrawItemStruct->rcItem.top,tci.pszText,lstrlen(tci.pszText));
  dc->DrawText(tci.pszText,&(lpDrawItemStruct->rcItem),DT_SINGLELINE|DT_VCENTER|DT_CENTER);
 
}實現tab控制元件的標題。

 11 如何在程式初次啟動時隱藏視窗

給人覺的下面方法比較好用,載入OnNcPaint,

OnNcPaint()//初始隱藏視窗
{
 // TODO: Add your message handler code here
 // Do not call CDialog::OnNcPaint() for painting messages
 static int i = 2;
 if(i > 0)
 {
  i --;
  ShowWindow(SW_HIDE);
 }
}

    12,按回車時直接關閉應用程式的問題

載入OnGetDefID函式

LRESULT CIEInputMonitor_vcDlg::OnGetDefID(WPARAM wp, LPARAM lp)
{
 return MAKELONG(0,DC_HASDEFID);
}

    13,解決VC提示 syntax error : identifier 'LONG_PTR'錯誤的方法

    14 ,如何獲取瀏覽器物件

   需要包含一下標頭檔案或者動態庫

#pragma comment(lib,"Wininet.lib")

#import <shdocvw.dll>

#include <afxinet.h>

#include <Wininet.h>

#include<mshtml.h>

CoInitialize(NULL);  
 //SHDocVw::IShellWindowsPtr m_spSHWinds; //將此處變數改為類的成員變數 wenzi 20130724
 if (m_spSHWinds == NULL)
    {    
  if(m_spSHWinds.CreateInstance(__uuidof(SHDocVw::ShellWindows)) != S_OK) 
  {       //  MessageBox(L"Failed");  
   CoUninitialize(); 
   return FALSE ;//nRelNum;    
  } 
 }  
 long nCount = m_spSHWinds->GetCount();
    IDispatchPtr spDisp;
 IHTMLDocument2* pIHTMLDocument2Result=NULL;
 for (long i = 0; i < nCount; i++)  
 { 
  if(NULL!=pIHTMLDocument2Result)
   break;
  _variant_t va(i, VT_I4);
  spDisp = m_spSHWinds->Item(va);  
  SHDocVw::IWebBrowser2Ptr spBrowser(spDisp);  
  if (spBrowser != NULL)  //查詢目標程式wenzi20130708
  {       
   IDispatchPtr spDisp;
   if(spBrowser->get_Document(&spDisp) == S_OK && spDisp != 0 ) 
   {                
    CComQIPtr<IHTMLDocument2> pDoc;      
    spDisp->QueryInterface(IID_IHTMLDocument2,(void**)&pDoc);
    if(pDoc==NULL)      
    {                    
     continue;      
    }
           return TRUE;

   }
  } 

 }
 CoUninitialize();  
    return FALSE ;

   15 如何判斷也頁面是否開啟

BOOL HTMLProcess::IsReady(IHTMLDocument2* sDoc)   // 檢查網頁狀態是否為 complete
{
  BSTR bstrUrl=NULL;
 HRESULT hr = sDoc->get_readyState(&bstrUrl);
 LPTSTR  psz3 ;
 USES_CONVERSION;
 psz3 =OLE2T(bstrUrl);
 LPTSTR   psz4 =_T("complete");
 if ( *psz3 == *psz4) 
 {
  return True;
 }
 return false ;
}

16 如何判斷頁面是否有焦點

 VARIANT_BOOL  HTMLProcess::DocHasFocus(IHTMLDocument2* sDoc)
{
 CComPtr<IHTMLDocument4>spDocEvent=NULL;
 VARIANT_BOOL  presult=VARIANT_FALSE;
 HRESULT hr  = sDoc->QueryInterface(IID_IHTMLDocument4,(void**)&spDocEvent);
 HRESULT hr1 =  spDocEvent->hasFocus(&presult);
 if(FAILED(hr1)) return VARIANT_FALSE;
 return presult;
}

   通過此方式判斷頁面是否有焦點只能判斷主頁面是否有焦點,但不能判斷主頁面某個子頁面是否有焦點。

17   如何查詢目標URL

bool HTMLProcess::IsFind(IHTMLDocument2* pIHTMLDocument2, CString& cTarget)
{
 if(pIHTMLDocument2==NULL) return false;
 BSTR ctaisbstrUrl= NULL ;//獲取URL wenzi20130710
 CString cCurFrame="";//當前視窗URL
 LRESULT hr = pIHTMLDocument2->get_URL(&ctaisbstrUrl);//判斷是否為目標程式地址 wenzi20130708
 if ( FAILED( hr ) )   return FALSE;
 cCurFrame=ctaisbstrUrl;
 int iPage=cCurFrame.Find(cTarget);
 if(-1!=iPage)
  return true;
 return false;
}

 18 如何遍歷頁面元素

    HRESULT hr;//獲取視窗中的表單元素
    long i=0;
     CComQIPtr<IHTMLElementCollection> pElementCollection;
     //CComQIPtr<IDispatch> pEnumElement;
     //CComQIPtr<IHTMLElement> pElement;
     BSTR EmName=NULL;
     /*BSTR EMId;*/
     VARIANT EMAttribute;
    BSTR strAttribute;
      CString Ctemp="";
       CString ctargetbtn="btn_cancle";
     strAttribute=SysAllocString(L"name");
     hr=ctaisfrspDoc2->get_all(&pElementCollection);
     if(FAILED(hr))return false;
     if(pElementCollection)
     {
     pElementCollection->get_length(&i);
     for(;i>0;i--)
     {
     _variant_t vb(VT_EMPTY);
       _variant_t va(i,VT_I4);
       CComQIPtr<IDispatch> pEnumElement;
      CComQIPtr<IHTMLElement> pElement;
      hr=pElementCollection->item(va,vb,&pEnumElement);
       if(FAILED(hr)) continue;
       if(pEnumElement)
      {
       pEnumElement->QueryInterface(IID_IHTMLElement,(void**)&pElement);
       if(pElement)
       {
        pElement->get_id(&EMId);
        Ctemp=EMId;
         if(-1!=Ctemp.Find(ctargetbtn))
          
//         MessageBox(NULL,Ctemp,NULL,MB_OKCANCEL);
       pElement->get_tagName(&EmName);
         //Ctemp=EmName;
        //MessageBox(NULL,Ctemp,NULL,MB_OKCANCEL);
        //pElement->getAttribute(strAttribute,0,&EMAttribute);
        //Ctemp=EMAttribute.bstrVal;
         //MessageBox(NULL,Ctemp,NULL,MB_OKCANCEL)

       }
       }
     }
 
    }

    19 如何在MFC中通過msscript 呼叫java script

在標頭檔案stdafx.h中新增

#import "msscript.ocx" /*raw_interfaces_only, raw_native_types,*/ no_namespace, named_guids \
 rename("Error", "ScriptError")

Script 的呼叫介面

CString HTMLProcess::ScriptCtrFunc(IHTMLDocument2 *  pIHTMLDocument2, _bstr_t ScriptCode)
{
 IScriptControlPtr pScriptControl(__uuidof(ScriptControl));

 // Create a VARIANT array of VARIANTs which hold BSTRs
 LPSAFEARRAY psa;
 SAFEARRAYBOUND rgsabound[]  = { 3, 0 }; // 3 elements, 0-based
 int i;

 psa = SafeArrayCreate(VT_VARIANT, 1, rgsabound);
 if (!psa)
 {
  //return E_OUTOFMEMORY;
 }

 VARIANT vFlavors[3];
 for (i = 0; i < 3; i++)
 {
  VariantInit(&vFlavors[i]);
  V_VT(&vFlavors[i]) = VT_BSTR;
 }

 V_BSTR(&vFlavors[0]) = SysAllocString(OLESTR("Vanilla"));
 V_BSTR(&vFlavors[1]) = SysAllocString(OLESTR("Chocolate"));
 V_BSTR(&vFlavors[2]) = SysAllocString(OLESTR("Espresso Chip"));

 long lZero = 0;
 long lOne = 1;
 long lTwo = 2;

 // Put Elements to the SafeArray:
 SafeArrayPutElement(psa, &lZero,&vFlavors[0]);
 SafeArrayPutElement(psa, &lOne,&vFlavors[1]);
 SafeArrayPutElement(psa, &lTwo,&vFlavors[2]);

 // Free Elements from the SafeArray:
 for(i=0;i<3;i++)
 {
  SysFreeString(vFlavors[i].bstrVal);
 }
 if(pIHTMLDocument2==NULL)return CString();

 // Set up Script control properties
 CComQIPtr<IHTMLWindow2>  pWin;
 //CComQIPtr<IHTMLDocument2> pIHTMLParent;
 pIHTMLDocument2->get_parentWindow(&pWin);
//  pWin->get_document(&pIHTMLParent);
//  pIHTMLParent->get_parentWindow(&pWin);

 //pScriptControl->Language="JScript";
 pScriptControl->Language = "JScript";
 pScriptControl->AllowUI = TRUE;
 pScriptControl->AddCode(ScriptCode);
 pScriptControl->AddObject("document", pWin, VARIANT_TRUE);
 pScriptControl->AddObject("window", pWin, VARIANT_TRUE);
 //BSTR URL1 = NULL;
 //pIHTMLDocument2->get_URL(&URL1);
 //  Call MyStringFunction with the two args:
 _variant_t outpar = pScriptControl->Run("MyStringFunction", &psa);
//  if(NULL==outpar)
//   return CString();

 // Convert VARIANT to C string:
 _bstr_t bstrReturn = (_bstr_t)outpar;
 char *pResult = (char *)bstrReturn;
 CString strResult;
 strResult.Format("%s",pResult);
 return strResult;

 return CString();
}

因為本人有點懶,所以進沒太改動了,藉口可以根據自己需要改動。對藉口的呼叫格式如下

CSting GetValue_fwskrzprint="";

GetValue_fwskrzprint  = ScriptCtrFunc(ctaisfrspDoc2,"function MyStringFunction(Argu1,Argu2,Argu3){var s='test',return s ; }");

20 ,如何獲取頁面表單的物件

        在script中,需要獲取頁面表單中的元素物件,可採用如下方式:

       var target=document.tab_fp.all.frm_yj.contentWindow.document.getElementById('dw_yj');

       通常的頁面物件的層次為視窗(window),文件(document),元素(elements),因此通過視窗來獲取文字,通過文字來獲得元素物件,元素物件在通過contentWindow來與起視窗連線起來。

21 ,如何查詢瀏覽中的提示視窗

  CString HTMLProcess::SeachTipIEFrame(void)//查詢彈出的提示視窗
{
 CString textvalue="";
 HWND hParent=NULL,hChild=NULL;
 hParent=FindWindow("Internet Explorer_TridentDlgFrame",NULL);
 if(NULL==hParent)
  return CString();
 hChild=FindWindowEx(hParent,NULL,"Internet Explorer_Server",NULL);
 textvalue=GetFrameContent(hChild);
 //MessageBox(NULL,textvalue,NULL,MB_OKCANCEL);
 return textvalue;
}

   該函式存在概率問題,有時候可能會失敗,可以通過迴圈解決。

  22,如何獲取Internet Explorer_Server中的內容

CString HTMLProcess::GetFrameContent(HWND hwnd)//獲取彈出網頁對話方塊中的內容  wenzi20130724
{
 if (hwnd == NULL)
 {
  //MessageBox(NULL,_T("視窗控制代碼為空"),0,0);
  return CString();
 }
 LRESULT ctaisdwRes;
 HRESULT ctaisforhr;
 IHTMLElement *ctaispHtmlElement;
 CString URL;
 HINSTANCE ctaishInst = ::LoadLibrary( _T("OLEACC.DLL") );

 UINT SBfwskcbnMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") );
 ::SendMessageTimeout(hwnd, SBfwskcbnMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&ctaisdwRes);
 LPFNOBJECTFROMLRESULT ctaispfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( ctaishInst,"ObjectFromLresult");
 if ( ctaispfObjectFromLresult != NULL )
 {    
  //MessageBox(0,"find the ObjectFrom",0,0);
  HRESULT ctaishr;
  CComPtr<IHTMLDocument2> ctaisspDoc=NULL;
  ctaishr=ctaispfObjectFromLresult(ctaisdwRes,IID_IHTMLDocument2,0,(void**)&ctaisspDoc);
  if ( SUCCEEDED(ctaishr) )
  {
   //MessageBox(0,"success",0,0);
   ctaisforhr=ctaisspDoc->get_body(&ctaispHtmlElement); //列印原始檔
   BSTR ctaisbstrUrl;
   CString ctaisstrurl= "";
   ctaispHtmlElement->get_innerText(&ctaisbstrUrl);
   URL = (CString)ctaisbstrUrl;
   //MessageBox(0,URL.Mid(1086,8),0,0);
  }
  //else MessageBox(0,_T("craishr is failed"),0,0);
 }
 //else MessageBox(0,_T("ctaispfObjectFromLresult is NULL"),0,0);
 ::FreeLibrary(ctaishInst);
 return URL;
 return CString();
}

  23,MFC實現傳送訊息到伺服器

bool HTMLProcess::UploadFromServer(CString Url,CString& ObjectRecv,CString& ObjectSend)
{
 bool ret=false;
 CInternetSession Sess(_T("session"));    
 Sess.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT     , 500); //2秒的連線超時    
 Sess.SetOption(INTERNET_OPTION_SEND_TIMEOUT        , 500); //2秒的傳送超時    
 Sess.SetOption(INTERNET_OPTION_RECEIVE_TIMEOUT     , 500); //2秒的接收超時    
 Sess.SetOption(INTERNET_OPTION_DATA_SEND_TIMEOUT   , 500); //2秒的傳送超時    
 Sess.SetOption(INTERNET_OPTION_DATA_RECEIVE_TIMEOUT, 500); //2秒的接收超時

// DWORD dwFlag = INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_DONT_CACHE|INTERNET_FLAG_RELOAD ;      
 CHttpFile* pFile   = NULL;
 CString Host="";
 CString CPort="";
 CString CTargetObject="";
 int iLocationHostlength=0;
 iLocationHostlength=8+m_host.GetLength()+m_CPort.GetLength();
 CTargetObject=Url.Right(Url.GetLength()-iLocationHostlength);//若URL地址的格式有所變化,可能需要對此處的資料進行修改  wenzi20130722
 Host=Url.Left(iLocationHostlength);
 CPort=Host.Right(m_CPort.GetLength());
 Host=Url.Left(iLocationHostlength-m_CPort.GetLength()-1);
 Host=Host.Right(iLocationHostlength-m_CPort.GetLength()-8);
 CHttpConnection*   pServer   =   NULL;
 CString LengthStr="";
 INTERNET_PORT   nPort;
 nPort=atoi(CPort.GetBuffer());
 int     nBufLen = 0   ;
 BOOL bConnect=FALSE;
 do {        
  try    
  {
   pServer   =   Sess.GetHttpConnection(Host,nPort);
   //cFile = (CHttpFile*)Sess.OpenURL(Url,1,dwFlag); //含特殊字元導致執行失敗。wenzi20130716
   pFile=pServer->OpenRequest(CHttpConnection::HTTP_VERB_POST,CTargetObject,NULL,1,NULL,NULL,INTERNET_FLAG_EXISTING_CONNECT);
   
   //向請求中新增引數 wenzi30130722

   Flag=itoa(m_bdelFlag,Flag.GetBufferSetLength(4),10);

   LengthStr = "dx="+ObjectSend+"&sfscbz="+Flag;///需要傳到伺服器的引數寫入此字串 wenzi 20130724


   pFile->AddRequestHeaders(_T("POST"+CTargetObject+"HTTP/1.1"));
   pFile->AddRequestHeaders(_T("Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/x-ms-application, application/x-ms-xbap, application/vnd.ms-xpsdocument, application/xaml+xml, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*"));
   pFile->AddRequestHeaders(_T("Referer:"+Url));//http://91.16.17.195:8802/Test111/GetFpyjdysbServlet?nsrsbh=330323196603190312&tjyf=201201
   pFile->AddRequestHeaders(_T("Accept-Language: zh-cn"));
   pFile->AddRequestHeaders(_T("Content-Type: application/x-www-form-urlencoded"));//charset=UTF-8
   pFile->AddRequestHeaders(_T("Accept-Encoding: gzip, deflate"));
   pFile->AddRequestHeaders(_T("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"));
   pFile->AddRequestHeaders(_T("Host: "+Host+":"+CPort));
   //pFile->AddRequestHeaders(_T("Content-Length:" /*+ payload.Length*/));
   pFile->AddRequestHeaders(_T("Connection: Keep-Alive"));//Keep-Alive或者close;
   pFile->AddRequestHeaders(_T("Cache-Control: no-cache"));
   
   
   bConnect=pFile->SendRequest(NULL,0,(LPVOID)(LPCSTR)LengthStr,LengthStr.GetLength());
   if(!bConnect)//連線是否成功
   {
    MessageBox(NULL,"網路連線失敗,請檢查網路!","友情提示",MB_OK);
   }

   DWORD dwStatusCode;
   CString strLine;
   pFile->QueryInfoStatusCode(dwStatusCode);            
   if (dwStatusCode == HTTP_STATUS_OK)
   {                 //查詢檔案長度               
    int nLen=0;
    while ((nLen = pFile->ReadString(strLine))>0)
    {
     ObjectRecv+=strLine;
    }
    ret = true;            
   }
   pFile->Close();
   pServer->Close();
   Sess.Close();

   //MessageBox(NULL,"網路連線失敗,請檢查網路!","友情提示",MB_OK);
  }
  catch(...)
  {            
   break;//        
  }    
 } while(0);
 if(bConnect&(!ret))//資料是否正確
 {
  MessageBox(NULL,"資料錯誤,請檢查資料!","友情提示",MB_OK);
 }
 return ret;  

}

cFile = (CHttpFile*)Sess.OpenURL(Url,1,dwFlag); //含特殊字元導致執行失敗。wenzi20130716

pFile->Close();
   pServer->Close();
   Sess.Close();必須寫明,否則會導致請求過慢的現象,大概要十幾秒才能完成一次請求操作。

24 ,HttpWebRequest傳送post請求時有多個引數如何處理?

       在此主要注意引數的格式,在23中已經實現了對多個引數的傳送。

25   解決VC提示 syntax error : identifier 'LONG_PTR'錯誤的方法

26   error C2471: cannot update program database vc90.pdb

27 關於報錯“\crl”的處理方法

    按上面的方法改有時會出現一些告警,通常選擇選擇(/clr)就行。

 最後,程式在使用中會出現退出現象,原因是對出現的異常未加處理,可在可能出現異常的程式碼新增try{可能產生異常的程式碼段}catch(...){此處新增處理程式碼;}