zoukankan      html  css  js  c++  java
  • VC7 HTML Dialog开发实例讲解

    开发环境:VS7,Windows XP,Windows 2K 

      在VS7中添加了一种新的对话框类:CDHtmlDialog,顾名思义就是能够显示DHTML内容的对话框,但不同与以前的CHTMLView不同的是添加了对DHTML的支持,能够响应各种DHTML的事件,而且能够方便的得到网页上的各种内容和输入。在这以前要完成这些功能必须通过复杂的COM接口来完成,而现在MS MFC已经为我们做好了这一切。 
       在下面我会按照下面的顺序讲解CDHtmlDialog的用法。但本文也只能对DHTML对话框的功能进行部分的讲解,更多更全的说明需要大家自己摸索和查找资料。本文的目的是在于讲解如何得到和设置网页上的各种元素的值,如何处理事件。 
       此外在阅读本文前你必须对HTML和DHTML有所了解。

    类成员函数介绍 

       构造函数 

       CDHtmlDialog( ); 
       CDHtmlDialog( 
       LPCTSTR lpszTemplateName, 
       LPCTSTR szHtmlResID, 
       CWnd *pParentWnd = NULL 
       ); 
       CDHtmlDialog( 
       UINT nIDTemplate, 
       UINT nHtmlResID = 0, 
       CWnd *pParentWnd = NULL 
       ); 

       你可以看到和CDialog不同的就在于第二个参数,表示在对话框创建时是否自动加载HTML,这里必须说明的是HTML必须以资源的形式存放,这个参数指明的是资源的ID或名称。

      

       或者你可以利用 

       BOOL LoadFromResource( 
       LPCTSTR lpszResource 
       ); 
       BOOL LoadFromResource( 
       UINT nRes 
       ); 
       将HTML内容在后期进行装载。

      页面浏览 

       此外一些函数如:OnNavigateComplete,OnBeforeNavigate,Navigate等用于页面转换的函数,在以前的CHtmlView中就有这里就不再作讲解。 

    得到当前URL 

       void GetCurrentUrl( 
       CString& szUrl 
       ); 

    得到网页中的DHTML元素的指定接口 

       HRESULT GetElementInterface( 
       LPCTSTR szElementId, 
       REFIID riid, 
       void** ppvObj 
       ); 

       第一个参数指定,第二个参数指定接口ID,第三个参数返回接口指针。 

    得到网页中的DHTML元素的IHTMLElement接口 

       HRESULT GetElement( 
       LPCTSTR szElementId, 
       IHTMLElement **pphtmlElement 
       ); 
       相当于调用 GetElementInterface(szElementId,IHTMLElement,pphtmlElement); 

       这个函数非常的重要,因为如果要得到DHTML的内容就必须通过页面上的各个元素的属性来得到,例如:对于Input type=text的属性value就是输入的值,对于p的属性innerText就是段落中的内容。 

       函数的第二个参数就是元素的名称。 

       函数的第二个参数,是一个指向指针的指针,通过它得到IHTMLElement的接口。函数返回值是HRESULT其值的定义符合COM中对返回值的定义。(如果你不了解,可以简单的检测返回值是否等于S_OK) 

    得到元素的innerText和innerHTML的属性 

       innerHTML属性: 
       BSTR GetElementHtml( 
       LPCTSTR szElementId 
       ); 
       innerText属性: 
       BSTR GetElementText( 
       LPCTSTR szElementId 
       ); 
       相当于调用IHTMLElement接口的gett_innerHTML和get_innerText方法 

       与之对应的是设置元素的innerText和InnerHTML属性: 
       innerHTML属性: 
       void SetElementHtml( 
       LPCTSTR szElementId, 
       BSTR bstrText 
       ); 
       innerText属性: 
       void SetElementText( 
       LPCTSTR szElementId, 
       BSTR bstrText 
       ); 
       相当于调用IHTMLElement接口的put_innerHTML和put_innerText方法 

    示范代码 

       假设页面上的代码为:<p id=p2>test</p>,执行下面代码可以显示原来的内容和将新内容设置为:abcdefg 

       CComPtr<IHTMLElement> spP1; 
       HRESULT hr = S_OK; 

       // Use the template overload 
       hr = GetElementInterface("p2", &spP1); 
       // 或者 hr = GetElement("p2", &spP1); 
       // 或者 hr = GetElementInterface("p2", IID_IHTMLElement, reinterpret_cast<void**>(&spP1)); 
       if(S_OK == hr) 
       { 
       BSTR bStr; 
       spP1->get_innerHTML(&bStr); 
       CString szTemp; 
       szTemp = bStr; 
       AfxMessageBox(szTemp); 

       CString strTable="abcdefg"; 
       BSTR bstrTable = strTable.AllocSysString(); 
       spP1->put_innerHTML(bstrTable); 
       } 
       或者利用SetElementHtml和SetElementText来进行设置: 
       BSTR bStr; 
       bStr = GetElementHtml("p2"); 
       CString szTemp; 
       szTemp = bStr; 
       AfxMessageBox(szTemp); 
       CString strTable="ABCDEFG"; 
       BSTR bstrTable = strTable.AllocSysString(); 
       //spP1->put_innerHTML(bstrTable); 
       SetElementHtml("p2",bstrTable); 
    事件处理映射宏 

    基本格式 

    BEGIN_DHTML_EVENT_MAP(className ) 
       DHTML_EVENT_ONCLICK(elemName, memberFxn ) //处理onclick事件 
       DHTML_EVENT_ONFOCUS(elemName, memberFxn ) //处理onfocus事件 
       DHTML_EVENT_ONKEYDOWN(elemName, memberFxn ) //处理onkeydown事件 
       DHTML_EVENT_ONMOUSEMOVE(elemName, memberFxn ) //处理mousemove事件 
       DHTML_EVENT_ONMOUSEOUT(elemName, memberFxn ) //处理mousemoveout事件 
       等等……… 
       END_DHTML_EVENT_MAP() 

       更详细的说明可以查阅MSDN中DHTML Event Map Macros部分。MSDN中对可以处理的事件进行了详细的说明。DHTML中的事件与Windows中消息不是同一个概念,虽然映射宏的形式很相同。 

    添加映射处理代码 

       我在VC7中没有发现自动添加各种事件映射的方法,只能通过手工添加代码的方式。 

       定义事件处理函数: 
       函数原型为:HRESULT urClass::OnXXXXX(IHTMLElement* /*pElement*/) 
       添加消息映射: 
       BEGIN_DHTML_EVENT_MAP(urClass) 
       DHTML_EVENT_ONCLICK(_T("id name"), OnXXXXX) 
       END_DHTML_EVENT_MAP() 

       下面是一段示范代码: 
       // mydlg.h 
       class CmydhtmlDlg : public CDHtmlDialog 
       { 
       // 构造 
       public: 
       CmydhtmlDlg(CWnd* pParent = NULL); // 标准构造函数 

       // 对话框数据 
       enum { IDD = IDD_MYDHTML_DIALOG, IDH = IDR_HTML_MYDHTML_DIALOG }; 

       protected: 
       virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 
       HRESULT OnButtonOK(IHTMLElement *pElement); 
       HRESULT OnButtonCancel(IHTMLElement *pElement); 
       HRESULT OnButtonTest1(IHTMLElement *pElement); 
       HRESULT OnButtonTest2(IHTMLElement *pElement); 
       HRESULT OnButtonTest3(IHTMLElement *pElement); 
       HRESULT OnSelectTest1(IHTMLElement *pElement); 
       HRESULT OnDivMouseMove1(IHTMLElement *pElement); 
       HRESULT OnDivMouseOut1(IHTMLElement *pElement); 

       //mydlg.cpp 
       BEGIN_DHTML_EVENT_MAP(CmydhtmlDlg) 
       DHTML_EVENT_ONCLICK(_T("ButtonOK"), OnButtonOK) 
       DHTML_EVENT_ONCLICK(_T("ButtonCancel"), OnButtonCancel) 
       DHTML_EVENT_ONCLICK(_T("Test1"), OnButtonTest1) 
       DHTML_EVENT_ONCLICK(_T("Test2"), OnButtonTest2) 
       DHTML_EVENT_ONCLICK(_T("Test3"), OnButtonTest3) 
       DHTML_EVENT_ONCHANGE(_T("s1"), OnSelectTest1) 
       DHTML_EVENT_ONMOUSEMOVE(_T("d1"), OnDivMouseMove1 ) 
       DHTML_EVENT_ONMOUSEOUT(_T("d1"), OnDivMouseOut1 ) 
       END_DHTML_EVENT_MAP() 

       HRESULT CmydhtmlDlg::OnButtonOK(IHTMLElement* /*pElement*/) 
       { 
       OnOK(); 
       return S_OK; 
       } 

       HRESULT CmydhtmlDlg::OnButtonCancel(IHTMLElement* /*pElement*/) 
       { 
       OnCancel(); 
       return S_OK; 
       } 

       HRESULT CmydhtmlDlg::OnButtonTest1(IHTMLElement* /*pElement*/) 
       { 
       AfxMessageBox("test1 button clicked"); 
       return S_OK; 
       } 

       HRESULT CmydhtmlDlg::OnSelectTest1(IHTMLElement* /*pElement*/) 
       { 
       TRACE("select1 changed "); 
       return S_OK; 
       } 

       HRESULT CmydhtmlDlg::OnDivMouseMove1(IHTMLElement* /*pElement*/) 
       { 
       TRACE("div1 mouse move "); 
       return S_OK; 
       } 

       HRESULT CmydhtmlDlg::OnDivMouseOut1(IHTMLElement* /*pElement*/) 
       { 
       TRACE("div1 mouse out "); 
       return S_OK; 
       } 

    各种DDX帮助宏 

    DDX宏介绍 

    如同CDialog类一样,CHtmlDialog也提供各种DDX帮助宏来与HTML页面上的控件交换数据。

      遗憾的是VS7中无法为CDHTMLDialog 的子类自动添加DDX变量,必须通过手工添加。

       设置innerText和innerHTML属性 

       DDX_DHtml_ElementInnerText( 
       CDataExchange* dx, 
       LPCTSTR name, 
       CString& var 
       ) 
       和 
        DDX_DHtml_ElementInnerHtml( 
       CDataExchange* dx, 
       LPCTSTR name, 
       CString& var 
       ) 
       相当与前面提到的设置和获取innerText,innerHTML属性。 

       获取和设置控件中的值

      在DHTML中利用“对象名程.value”可以得到控件中输入的值,利用DDX也同样可以得到。 

       DDX_DHtml_ElementValue( 
       CDataExchange* dx, 
       LPCTSTR name, 
       var 
       ) 
       用于在控件和对象之间交换数据。 

       使用方法

      假设HTML文件中代码如下 

       <p id="p4"><b>p4 for ddx</b></p> 
       <input type="text" ID="input1" size="20" value="input1 for ddx" NAME="input1"> 
       <input type="text" ID="input2" size="20" value="101" NAME="input2"> 

       在H文件中添加变量定义: 
       public: //DDX 
       CString m_szP4,m_szInput1; 
       int m_iInput2; 

       在类的构造函数中赋初值: 
       CmydhtmlDlg::CmydhtmlDlg(CWnd* pParent /*=NULL*/) 
       : CDHtmlDialog(CmydhtmlDlg::IDD, CmydhtmlDlg::IDH, pParent) 
       { 
       m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); 
       m_szP4 = "test for p4"; 
       m_szInput1= "test for input1"; 
       m_iInput2 = 101; 
       } 

       在CPP文件中的void CmydhtmlDlg::DoDataExchange(CDataExchange* pDX)函数中添加代码: 
       void CmydhtmlDlg::DoDataExchange(CDataExchange* pDX) 
       { 
       CDHtmlDialog::DoDataExchange(pDX); 
       //// for html ddx 
       DDX_DHtml_ElementInnerHtml(pDX,"p4",m_szP4); //对应 p4 
       DDX_DHtml_ElementValue(pDX,"input1",m_szInput1); //对应 input1 
       DDX_DHtml_ElementValue(pDX,"input2",m_iInput2); //对应 input2 
       } 
       使用是与CDialog一样利用UpdateData。 
       HRESULT CmydhtmlDlg::OnButtonTest4(IHTMLElement* /*pElement*/) 
       { 
       UpdateData(); 
       TRACE("p4=%s ",m_szP4); 
       CString szTemp=m_szP4; 
       m_szP4 =m_szInput1; 
       m_szInput1=szTemp; //对换p4和input1中内容 
       m_iInput2 ++; //将input2中数字加一 
       UpdateData(FALSE); 
       return S_OK; 
       } 

    一个简单的例子 

       最后介绍一下如何利用VC7创建一个利用CDHtmlDialog的工程。

      首先创建工程,进行如下设置: 

      


       在资源管理中修改HTML文件: 

       


       最后添加自己的代码。我提供的例子中所使用的函数在上面都已经提到。

  • 相关阅读:
    18软工实践-第三次作业-结对项目1
    结对作业之代码规范
    ALPHA(7)
    ALPHA(6)
    ALPHA(五)
    404 Note Found 现场编程
    ALPHA(四)
    ALPHA冲刺(三)
    ALpha冲刺(二)
    ALPHA 冲刺(一)
  • 原文地址:https://www.cnblogs.com/MrYuan/p/5019401.html
Copyright © 2011-2022 走看看