There can be no Triumph without Loss,No Victory without Suffering,No Freedom without Sacrifice.
All you have to decide is what to do with the time that is given to you.
Get busy Living, or Get busy Dying?
  首页 | 留言给我 | 订阅 Rss | CLI | 黄白之恋 Posts:158   Hits: 2066518    Comments: 170    
 日历归档
<<  <  2020 - 04  >  >>
SuMoTuWeThFrSa
   1234
567891011
12131415161718
19202122232425
2627282930
 About Me
 Name: ZhangSichu
 Sex: Male
 Age: 32
 Email: ZhangSichu@gmail.com
 MSN: ZhangSichu@hotmail.com
 Home: ZhangSichu.com
 WeiBo: weibo.com/zhangsichu
 个人推荐
 分类归档
  ·C++/C(5)  RSS
  ·软件工程(1)  RSS
  ·杂事/随感(26)  RSS
  ·.Net/Java(30)  RSS
  ·面向对象程序设计(5)  RSS
  ·汇编/破解(0)  RSS
  ·平面设计(3)  RSS
  ·SQL(5)  RSS
  ·COM/COM+(2)  RSS
  ·Web开发(81)  RSS
 My Friends
Back Forward Refresh Home 2020年4月5日 星期日 RSS CLI Mine Sweeper. In Javascript.

  HTML对话框的实现[转载]
字体大小 [ ]

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

在VS7中添加了一种新的对话框类:CDHtmlDialog,顾名思义就是能够显示DHTML内容的对话框,但不同与以前的CHTMLView不同的是添加了对DHTML的支持,能够响应各种DHTML的事件,而且能够方便的得到网页上的各种内容和输入。在这以前要完成这些功能必须通过复杂的COM接口来完成,而现在MS MFC已经为我们做好了这一切。

在下面我会按照下面的顺序讲解CDHtmlDialog的用法。但本文也只能对DHTML对话框的功能进行部分的讲解,更多更全的说明需要大家自己摸索和查找资料。本文的目的是在于讲解如何得到和设置网页上的各种元素的值,如何处理事件。

此外在阅读本文前你必须对HTML和DHTML有所了解。

CDHtmlDialog类的成员函数
CDHtmlDialog事件处理映射宏
CDHtmlDialog类的各种DDX帮助宏
一个简单的例子
类成员函数介绍

构造函数

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

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

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\n");
  return S_OK;
}

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

HRESULT CmydhtmlDlg::OnDivMouseOut1(IHTMLElement* /*pElement*/)
{
  TRACE("div1 mouse out\n");
  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\n",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的工程。

首先创建工程,进行如下设置:
Click to Open in New Window
在资源管理中修改HTML文件:
Click to Open in New Window
最后添加自己的代码。我提供的例子中所使用的函数在上面都已经提到。大家可以下载这份例子去进行一定的参考
  Posted @ 2/8/2005 12:31:56 AM | Hits (40554) | Comment (0

  Post Comment
标题 *
作者 *
密码 记住我
评论 *
    


Stable in Firefox 1.5 2.0Stable in IE6 IE7Stable in MozillaStable in Netscape
ZhangSichu.com V0.1.7507
Powered By ZhangSichu
Copyright © ZhangSichu
Download ZhangSichu.com source code. Download source code