程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 浏覽器的定制與擴展

浏覽器的定制與擴展

編輯:關於VC++

前言

由於本人在開發中經常要在程序中嵌入浏覽器,為了符合自己的 需求經常要對浏覽器進行擴展和定制,解決這些問題需在網上找資料和學習的過 程,我想可能很多開發者或許會遇到同樣的問題,特寫此文,以供大家參考。

在MFC中使用浏覽器

在MFC中微軟為我們提供了CHtmlView、 CDHtmlDialog類讓我們的程序很方便的嵌入浏覽器和進行浏覽器的二次開發,這 比直 接使用WebBrowser控件要方便很多,所以本文中討論的浏覽器的問題都是 針對CHtmlView來討論的。文中將提到一個類CLhpHtmlView, 它是CHtmlView的派 生類,文中提及的擴展或定制都將在CLhpHtmlView類(或派生類)上實現。

怎樣擴展或定制浏覽器

浏覽器定義了一些擴展接口(如 IDocHostUIHandler可以定制浏覽器界面有關的行為),以便開發者進行定制和 擴展。浏覽 器會在需要的時候向他的控制站點查詢這些接口,在控制站點裡實 現相應的接口就可以進行相應的擴展。在MFC7.01類 庫中,CHtmlView使用的控 制站點是CHtmlControlSite的,在CHtmlControlSite類中 只實現了接口 IDocHostUIHandler,而要實現更多的擴展接口,必須用自定義的控制站類來取 代CHtmlControlSite,在下文中提及的類CDocHostSite即為自定義 的控制站類 。

關於接口的介紹請參考: http://dev.csdn.net/develop/article/48/48483.shtm

如何 使自定義的控制站點來替換默認的控制站點呢?在MFC7.0中只需重載CHtmlView 的虛函數CreateControlSite即可:

BOOL CLhpHtmlView::CreateControlSite(COleControlContainer * pContainer,
COleControlSite ** ppSite, UINT /*nID*/, REFCLSID /*clsid*/)
{
  *ppSite = new CDocHostSite(pContainer, this);// 創建自己的 控制站點實例
  return (*ppSite) ? TRUE : FALSE;
}
VC6.0要替換控制站要復雜的多,這裡就不討論了,如需要6.0版本的請 給我發郵件到[email protected]

定制鼠標右鍵彈出出菜單

要 定制浏覽器的鼠標右鍵彈出菜單,必須在自定義的控制站點類中實現 IDocHostUIHandler2接口,並且IE的 版本是5.5或以上。在接口 IDocHostUIHandler2的ShowContextMenu方法中調用浏覽器類的 OnShowContextMenu虛函數,我們 在浏覽器類的派生類重載此虛函數即可實現右 鍵菜單的定制,參見代碼

HRESULT CDocHostSite::XDocHostUIHandler::ShowContextMenu(DWORD dwID,
                              POINT * ppt,
                             IUnknown * pcmdtReserved,
                              IDispatch * pdispReserved)
{
  METHOD_PROLOGUE (CDocHostSite, DocHostUIHandler);
  return pThis->m_pView- >OnShowContextMenu( dwID, ppt, pcmdtReserved,pdispReserved );
}
HRESULT CLhpHtmlView::OnShowContextMenu(DWORD dwID,
                     LPPOINT ppt,
                     LPUNKNOWN pcmdtReserved,
                     LPDISPATCH pdispReserved)
{
   HRESULT result = S_FALSE;
  switch(m_ContextMenuMode)
   {
  case NoContextMenu:      // 無菜單
     result=S_OK;
    break;
  case DefaultMenu:         // 默認菜單
    break;
  case TextSelectionOnly:       // 僅文本選擇菜單
    if(!(dwID == CONTEXT_MENU_TEXTSELECT || dwID == CONTEXT_MENU_CONTROL))
       result=S_OK;
    break;
  case CustomMenu:         // 自定義菜單
    if(dwID! =CONTEXT_MENU_TEXTSELECT)
       result=OnShowCustomContextMenu(ppt,pcmdtReserved,pdispReserved);
    break;
  }
  return result;
}

在 CLhpHtmlView中定義的枚舉類型CONTEXT_MENU_MODE舉出了定制右鍵彈出菜單的 四種類型

enum CONTEXT_MENU_MODE    // 上下文菜單
{
  NoContextMenu,    // 無菜單
  DefaultMenu,     // 默認菜單
  TextSelectionOnly,    // 僅文本選擇菜單
  CustomMenu    // 自定義菜單
};

通過 CLhpHtmlView的函數SetContextMenuMode來設置右鍵菜單的類型。如果設定的右 鍵彈出菜單是“自定義菜單”類型,我們只要在CLhpHtmlView的派生 類中重載OnShowCustomContextMenu虛函數即可,如下代碼 CDemoView是 CLhpHtmlView的派生類 HRESULT CDemoView::OnShowCustomContextMenu (LPPOINT ppt, LPUNKNOWN pcmdtReserved,LPDISPATCH pdispReserved)
{
  if ((ppt==NULL)||(pcmdtReserved==NULL)|| (pcmdtReserved==NULL))
    return S_OK;
  HRESULT hr=0;
  IOleWindow *oleWnd=NULL;
    hr=pcmdtReserved ->QueryInterface(IID_IOleWindow, (void**)&oleWnd);
  if ((hr != S_OK)||(oleWnd == NULL))
    return S_OK;
   HWND hwnd=NULL;
  hr=oleWnd->GetWindow(&hwnd);
   if((hr!=S_OK)||(hwnd==NULL))
  {
    oleWnd- >Release();
    return S_OK;
  }
   IHTMLElementPtr  pElem=NULL;
  hr = pdispReserved- >QueryInterface(IID_IHTMLElement, (void**)&pElem);
  if (hr != S_OK)
  {
    oleWnd->Release();
     return S_OK;
  }
  IHTMLElementPtr   pParentElem=NULL;
  _bstr_t  tagID;
  BOOL go=TRUE;
  pElem->get_id(&tagID.GetBSTR());
  
   while(go && tagID.length()==0)
  {
     hr=pElem->get_parentElement(&pParentElem);
    if (hr==S_OK && pParentElem!=NULL)
    {
       pElem->Release();
      pElem=pParentElem;
       pElem->get_id(&tagID.GetBSTR());
    }
     else
      go=FALSE;
  };
  if (tagID.length()==0)
    tagID="no id";
   CMenu Menu,SubMenu;
  Menu.CreatePopupMenu();
  
   CString strTagID = ToStr(tagID);
  if(strTagID == "red")
    Menu.AppendMenu(MF_BYPOSITION, ID_RED, "您點擊的是紅色");
  else if(strTagID == "green")
    Menu.AppendMenu(MF_BYPOSITION, ID_GREEN, "您點擊的是綠色");
  else if(strTagID == "blue")
    Menu.AppendMenu(MF_BYPOSITION, ID_BLUE, "您點擊的是藍色");
  else
     Menu.AppendMenu(MF_BYPOSITION, ID_NONE, "你點了也白點,請在指定的 地方點擊");
    
  int MenuID=Menu.TrackPopupMenu (TPM_RETURNCMD|TPM_LEFTALIGN|TPM_RIGHTBUTTON,ppt->x, ppt->y, this);
  switch(MenuID)
  {
  case ID_RED:
    MessageBox("紅色");
    break;
   case ID_GREEN:
    MessageBox("紅色");
     break;
  case ID_BLUE:
    MessageBox("紅色 ");
    break;
  case ID_NONE:
     MessageBox("haha");
    break;
  }
   oleWnd->Release();
  pElem->Release();
  return S_OK;
}

實現腳本擴展(很重要的external接口)

在 你嵌入了浏覽器的工程中,如果網頁的腳本中能調用C++代碼,那將是一件很惬 意的事情,要實現這種交互,就必須實現腳本擴展。實現腳本擴展就是在程序中 實現一個IDispatch接口,通過CHtmlView類的OnGetExternal虛函數返回此接口 指針,這樣就可以在腳本中通過window.external.XXX(關鍵字window可以省略)來 引用接口暴露的方法或屬性(XXX為方法或屬性名)。在MFC中從CCmdTarget派生的 類都可以實現自動化,而不必在MFC工程中引入繁雜的ATL。從CCmdTarget派生的 類實現自動化接口的時候不要忘了在構造函數中調用EnableAutomation函數。

要使虛函數OnGetExternal發揮作用必須在 自定義的控制站點類中實現 IDocHostUIHandler,在接口IDocHostUIHandler的GetExternal方法中調用浏覽 器類的OnGetExternal虛函數,我們在浏覽器類的派生類重載OnGetExternal虛函 數,通過參數lppDispatch返回一個IDispatch指針,這樣腳本中引用 window.external時就是引用的返回的接口,參見代碼 HRESULT CDocHostSite::XDocHostUIHandler::GetExternal(IDispatch ** ppDispatch)
{
  METHOD_PROLOGUE(CDocHostSite, DocHostUIHandler);
  return pThis->m_pView->OnGetExternal( ppDispatch );
}
CLhpHtmlView::CLhpHtmlView(BOOL isview)
{
   ......
  EnableAutomation();// 允許自動化
}
HRESULT CLhpHtmlView::OnGetExternal(LPDISPATCH *lppDispatch)
{
   *lppDispatch = GetIDispatch(TRUE);// 返回自身的IDispatch接口
   return S_OK;
}
請注意上面代碼中,在OnGetExternal返回的是自 身IDispatch接口,這樣就不比為腳本擴展而另外寫一個從CCmdTarget派生的新 類,CLhpHtmlView本身就是從CCmdTarget派生,直接在上面實現接口就是。

下用具體示例來說明怎樣實現腳本擴展

示例會在網頁上點擊一個 按鈕而使整個窗口發生抖動

從CLhpHtmlView派生一個類CDemoView,在類 中實現IDispatch, 並通過IDispatch暴露方法WobbleWnd ------------- --------------------------------------------------------------
文 件 DemoView.h
-------------------------------------------------- -------------------------
.......
class CDemoView : public CLhpHtmlView
{
  ......
  DECLARE_DISPATCH_MAP() // 構建dispatch映射表以暴露方法或屬性
  ......
  void WobbleWnd();// 抖動窗口
};
-------------------------------- -------------------------------------------
文件 DemoView.cpp
------------------------------------------------------------------- --------
......
// 把成員函數映射到Dispatch映射表中,暴露方法 給腳本
BEGIN_DISPATCH_MAP(CDemoView, CLhpHtmlView)
   DISP_FUNCTION(CDemoView, "WobbleWnd", WobbleWnd, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()
......
void CDemoView::WobbleWnd()
{
  // 在這裡實現抖動窗口
   ......
}
-------------------------------------------------- -------------------------
文件 Demo.htm
------------------- --------------------------------------------------------
...... onclick="external.WobbleWnd()" ......    
這裡我要 介紹一下DISP_FUNCTION宏,它的作用是將一個函數映射到Dispatch映射表中, 我們看DISP_FUNCTION(CDemoView, "WobbleWnd", WobbleWnd, VT_EMPTY, VTS_NONE)

CDemoView是宿主類名, "WobbleWnd"是暴露給外面的名字(腳本調用時使用的名字), VT_EMPTY是返回值得類型為空,VTS_NONE說明此方法沒有參數,如果要映射的函 數有返回值和參數該 如何映射,通過下面舉例來說明

DISP_FUNCTION (CCalendarView,"TestFunc",TestFunc,VT_BOOL,VTS_BSTR VTS_I4 VTS_I4)
BOOL TestFunc(LPCSTR param1, int param2, int param3)
{
  .....
}

參數表VTS_BSTR VTS_I4 VTS_I4是用空 格分隔,他們的類型映射請參考MSDN,這要提醒的是不要把VTS_BSTR與CString 對應,而應與LPCSTR對應。

C++代碼中如何調用網頁腳本中的函數

IHTMLDocument2::scripts屬性表示HTML文檔中所有腳本對象。使用腳本 對象的IDispatch接口的GetIDsOfNames方法可以得到腳本函數的 DispID,得到 DispID後,使用IDispatch的Invoke函數可以調用對應的腳本函數。 CLhpHtmlView提供了方便的調用JavaScript的函數,請參考CLhpHtmlView中有關 鍵字“JScript”的代碼。

定制消息框的標題

我們在 腳本中調用alert彈出消息框時,消息框的標題是微軟預定義的 “Microsoft Internet Explorer”,如下圖:

在自 定義的控制站點類中實現IDocHostShowUI接口,在接口的ShowMessage方法中調 用浏覽器的OnShowMessage,我們重載 OnShowMessage虛函數即可定制消息框的標 題,實現代碼如下:

// 窗口標題"Microsoft Internet Explorer"的資源標識
#define IDS_MESSAGE_BOX_TITLE 2213
HRESULT CLhpHtmlView::OnShowMessage(HWND hwnd,
                   LPOLESTR lpstrText,
                   LPOLESTR lpstrCaption,
                   DWORD dwType,
                  LPOLESTR lpstrHelpFile,
                  DWORD dwHelpContext,
                  LRESULT * plResult)
{
  //載入Shdoclc.dll 和IE消息框標題字符串
  HINSTANCE hinstSHDOCLC = LoadLibrary(TEXT ("SHDOCLC.DLL"));
  if (hinstSHDOCLC == NULL)
     return S_FALSE;
  CString strBuf,strCaption (lpstrCaption);
  strBuf.LoadString(hinstSHDOCLC, IDS_MESSAGE_BOX_TITLE);
  // 比較IE消息框標題字符串和 lpstrCaption
  // 如果相同,用自定義標題替換
  if (strBuf==lpstrCaption)
    strCaption = m_DefaultMsgBoxTitle;
  // 創建自己的消息框並且顯示
   *plResult = MessageBox(CString(lpstrText), strCaption, dwType);
  //卸載Shdoclc.dll並且返回
  FreeLibrary(hinstSHDOCLC);
  return S_OK;
}

從代碼中可以看到通過設定 m_DefaultMsgBoxTitle的值來改變消息寬的標題,修改此值是同過 SetDefaultMsgBoxTitle來實現 void CLhpHtmlView::SetDefaultMsgBoxTitle(CString strTitle)
{
   m_DefaultMsgBoxTitle=strTitle;
}

怎樣定制、修改浏覽 器向Web服務器發送的HTTP請求頭

在集成了WebBrowser控件的應用中, Web服務器有時可能希望客戶端(浏覽器)發送的HTTP請求中附帶一些額外的信息 或自定義的 HTTP頭字段,這樣就必須在浏覽器中控制向Web服務器發送的HTTP請 求。下面是捕獲的一個普通的用浏覽器發送的HTTP請求頭:GET /text7.htm HTTP/1.0
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, \
application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Referer: http://localhost
Accept- Language: en-us
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Poco 0.31; LHP Browser 1.01; \
.NET CLR 1.1.4322)
Host: localhost
Connection: Keep-Alive
CHtmlView的
void Navigate2(
  LPCTSTR lpszURL,
  DWORD dwFlags = 0,
  LPCTSTR lpszTargetFrameName = NULL,
  LPCTSTR lpszHeaders = NULL,
  LPVOID lpvPostData = NULL,
  DWORD dwPostDataLen = 0
);

函數參數lpszHeaders可以指定 HTTP請求頭,示例如下:

Navigate2(_T ("http://localhost"),NULL,NULL, "MyDefineField: TestValue");我們捕獲的HTTP頭如下:

怎樣修改浏覽器標識

在HTTP請求頭中User-Agent字段表明了浏覽器的版本以 及操作系統的版本等信息。WEB服務器經常需要知道用戶請求頁面時是來自IE還 是來自自己的客戶端中的WebBrowser控件,以便分開處理,而WebBrowser控件向 WEB服務器發送的浏覽器標識(User-Agent字段)跟用IE發送的是一樣的,怎樣區 分自己的浏覽器和IE呢? 微軟沒有提供現成的方法,要自己想法解決。前面討 論的定制HTTP請求頭就是為這一節准備的。思路是這樣的:在自己的浏覽器裡處 理每一個U頁面請求,把請求頭User-Agent改成自己想要的。在CHtmlView的 OnBeforeNavigate2虛函數裡來修改HTTP請求是再好不過了,#define WM_NVTO    (WM_USER+1000)
class NvToParam
{
public:
  CString URL;
  DWORD Flags;
  CString TargetFrameName;
  CByteArray PostedData;
  CString Headers;
};
void CDemoView::OnBeforeNavigate2(LPCTSTR lpszURL,
                 DWORD nFlags,
                  LPCTSTR lpszTargetFrameName,
                  CByteArray& baPostedData,
                  LPCTSTR lpszHeaders,
                  BOOL* pbCancel)
{
  CString strHeaders(lpszHeaders);
  if(strHeaders.Find("User- Agent:LHPBrowser 1.0") < 0)// 檢查頭裡有沒有自定義的User-Agent 串
  {
    *pbCancel = TRUE;// 沒有,取消這次導航
    if(!strHeaders.IsEmpty())
      strHeaders += "\r\n";
    strHeaders += "User- Agent:LHPBrowser 1.0";// 加上自定義的User-Agent串
     NvToParam* pNvTo = new NvToParam;
    pNvTo->URL = lpszURL;
    pNvTo->Flags = nFlags;
    pNvTo- >TargetFrameName = lpszTargetFrameName;
     baPostedData.Copy(pNvTo->PostedData);
    pNvTo- >Headers = strHeaders;
    // 發送一個自定義的導航消息,並 把參數發過去
    PostMessage(WM_NVTO,(WPARAM)pNvTo);
     return;
  }
  CHtmlView::OnBeforeNavigate2 (lpszURL,
                 nFlags,
                  lpszTargetFrameName,
                  baPostedData,
                 lpszHeaders,
                 pbCancel);
}
LRESULT CDemoView::OnNvTo(WPARAM wParam, LPARAM lParam)
{
  NvToParam* pNvTo = (NvToParam*)wParam;
  Navigate2 ((LPCTSTR)pNvTo->URL,
        pNvTo->Flags,
         pNvTo->PostedData,
        (LPCTSTR)pNvTo ->TargetFrameName,
        (LPCTSTR)pNvTo- >Headers);
  delete pNvTo;
  return 1;
}

在OnBeforeNavigate2中如果發現沒有自定義的User-Agent串,就加 上這個串,並取消本次導航,再Post一個消息(一定要POST,讓 OnBeforeNavigate2跳出以後再進行導航 ),在消息中再次導航,再次導航時請 求頭已經有了自己的標識,所以能正常的導航。

去掉討厭的異常警告

在程序中使用了CHtmlView以後,我們在調整窗口大小的時候經常會看到 輸出窗口輸出的異常警告:ReusingBrowser.exe 中的 0x77e53887 處最可能的 異常: Microsoft C++ exception: COleException @ 0x0012e348 。 Warning: constructing COleException, scode = DISP_E_MEMBERNOTFOUND($80020003).

這是由於CHtmlView在處理 WM_SIZE消息時的一點小問題引起的,采用如下代碼處理WM_SIZE消息就不會有此 警告了

void CLhpHtmlView::OnSize(UINT nType, int cx, int cy)
{
  CFormView::OnSize(nType, cx, cy);
  if (::IsWindow(m_wndBrowser.m_hWnd))
  {
    CRect rect;
    GetClientRect(rect);
    // 就這一句與 CHtmlView的不同
    ::AdjustWindowRectEx(rect, GetStyle(), FALSE, WS_EX_CLIENTEDGE);
    m_wndBrowser.SetWindowPos (NULL,
                 rect.left,
                  rect.top,
                  rect.Width(),
                  rect.Height(),
                 SWP_NOACTIVATE | SWP_NOZORDER);
  }
}

怎樣處理浏覽器內的拖放

有時可能有這樣的需求,我們希望在資源管理器裡托一個文件到浏覽器 而做出相應的處理,甚至是將文件拖到某一個網頁元素上來做出相應的處理,而 浏覽器默認的處理拖放文件操作是將文件打開,但WebBrowser控件給了我們一個 自己處理拖放的機會。那就是在自定義的控制站點類中實現IDocHostUIHandler ,在接口IDocHostUIHandler的GetDropTarget方法中調用 浏覽器類的 OnGetDropTarget虛函數。要處理網頁內的拖放,必需在OnGetDropTarget函數中 返回一個自己定義的IDropTarget接口指針,所以我們自己寫一個類 CMyOleDropTarget從COleDropTarget類派生,並且在實現IDropTarget接口,此 類的代碼在這就不列出了,請下載演示 程序,參考文件MyOleDropTarget.h和 MyOleDropTarget.cpp。我們看CLhpHtmlView中OnGetDropTarget的代碼

HRESULT CLhpHtmlView::OnGetDropTarget(LPDROPTARGET pDropTarget, LPDROPTARGET* ppDropTarget )
{
   m_DropTarget.SetIEDropTarget(pDropTarget);
  LPDROPTARGET pMyDropTarget;
  pMyDropTarget = (LPDROPTARGET) m_DropTarget.GetInterface(&IID_IDropTarget);
  if (pMyDropTarget)
  {
    *ppDropTarget = pMyDropTarget;
    pMyDropTarget->AddRef();
     return S_OK;
  }
  return S_FALSE;
}
   m_DropTarget即為自定義的處理拖放的對象。這樣就能通過在從CLhpHtmlView派 生的類中重載OnDragEnter、OnDragOver、 OnDrop、OnDragLeave虛函數來處理 拖放了。在這裡順帶講一下視圖是怎樣處理拖放的。要使視圖處理拖放,首先在 視圖裡添加一個COleDropTarget(或派生類)成員變量,如CLhpHtmlView中的 “CMyOleDropTarget m_DropTarget;”,再在 視圖創建時調用 COleDropTarget對象的Register,即把視圖與COleDropTarget對象關聯起來,如 CLhpHtmlView中的“m_DropTarget.Register(this);”,再對拖放 觸發的事件進行相應的處理,OnDragEnter 把某對象拖入到視圖時觸發,在此檢 測拖入的對象是不是視圖想接受的對象,如是返回 “DROPEFFECT_MOVE”表示接受此對象,如

if (pDataObject->IsDataAvailable(CF_HDROP))// 被拖對象是文件嗎?
  return DROPEFFECT_MOVE;

OnDragOver 被拖對象在視圖上移動, 同OnDragEnter一樣檢測拖入對象,如果要接受此對象返回 “DROPEFFECT_MOVE”。OnDrop 拖著被拖對象在視圖上放開鼠標,在 這裡對拖入對象做出處理; OnDragLeave 拖著被拖對象離開視圖。C++的代碼寫 好了,但事情還沒完,還必須在網頁裡用腳本對拖放事件進行處理,即頁面裡哪 個元素要接受拖放對象哪個元素就要處理ondragenter、ondragover、ondrop, 代碼其實很簡單,讓事件的返回值為false即可,這樣 C++的代碼才有機會處理 拖放事件,代碼如下:......
<td ondragenter="event.returnValue = false" ondragover="event.returnValue = false" \
ondrop="event.returnValue = false">
......

如果要使整個視圖都接受拖放,則在Body元素中處理此三個 事件。注意:別忘了讓工程對OLE的支持即在初始化應用程序時調用AfxOleInit ()。

怎樣禁止網頁元素的選取

用網頁做界面時多數情況下是不希 望網頁上的元素是能夠被鼠標選中的,要使網頁元素不能被選中做法是:給浏覽 器的“宿主信息標記”加上DOCHOSTUIFLAG_DIALOG標記。

“宿主信息標記”用N個標記位來控制浏覽器的許多性質,如 :

禁用浏覽器的3D的邊緣;

禁止滾動條;

禁用腳本;

定義雙擊處理的方式;

禁用浏覽器的自動完成功能;

...... 更多詳情請參考MSDN的DOCHOSTUIFLAG幫助。

怎樣修改 “宿主信息標記”?

在CDocHostSite中實現 IDocHostUIHandler,在GetHostInfo方法中調用浏覽器的OnGetHostInfo虛函數 ,在虛函數OnGetHostInfo中便可指定“宿主信息標記”,如:

HRESULT CLhpHtmlView::OnGetHostInfo(DOCHOSTUIINFO * pInfo)
{
  pInfo->cbSize = sizeof(DOCHOSTUIINFO);
   pInfo->dwFlags = DOCHOSTUIFLAG_DIALOG |
             DOCHOSTUIFLAG_THEME |
             DOCHOSTUIFLAG_NO3DBORDER |
             DOCHOSTUIFLAG_SCROLL_NO;
  pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
  return S_OK;
}

用腳本也可 實現:在Head中加入腳本:

document.onselectstart=new Function (''return false'');

或者

<body onselectstart="return false">。

其它

在CLhpHtmlView中還提供了幾個函數,修改網頁元素的內容:BOOL PutElementHtml(CString ElemID,CString Html);

取表單元素的值:

BOOL GetElementValue(CString ElemID,CString& Value); 設置表單元素的值:BOOL PutElementValue(CString ElemID,CString Value);給表單元素設置焦點:void ElementSetFocus(CString EleName);

本文配套源碼

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved