65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 C++ 操作 HTML 文件中的控件

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.80/5 (17投票s)

2002年12月27日

4分钟阅读

viewsIcon

134054

downloadIcon

1853

一个类可以重用 Web 浏览器来操作 HTML。

引言

Microsoft 提供了带有 COM 接口的 mshtml.dll。我们可以使用它来根据需要操作 HTML 文件中的所有信息。这是一系列出色的接口。在 Visual Studio .NET 中,有一个名为 CDhtmlDialog 的类,它方便我们使用 HTML 作为对话框接口。在这个类中,有很多对 HTML 文件进行的基本操作。在我的一款应用程序中,所有对话框都使用了 HTML 对话框。我发现我们需要更多的工具来操作 HTML 文件中的元素。所以我写了这个类,并在此提交。

HTML 信息

在 MSDN 中,有关于如何操作文件中每种 HTML 元素的详细信息。其中一个类是 IHTMLDocument2。使用此接口,我们可以根据我们的需求动态地收集 HTML 的所有信息,添加、删除或修改 HTML 文件信息。特别是,使用 HTML 作为接口,检索文件中控件的所有信息也非常重要。这个包装类主要用于获取或收集这些控件的信息。

HTML 的元素由以下部分组成:标签名、内部文本、属性等。例如:

<select name=”select1” value=”200”>
  <Option value =”4” name=”text1”>text</Option>
  <Option value =”5” name=”text12”></Option>
</select>

在此代码段中,“select”、“option”是标签名。“name”、“value”是属性名。“select1”、““200”是属性值。操作 HTML 就是操作这些值。

在 HTML 中,许多控件使用不同类型的 INPUT 标签。以下内容来自 MSDN:

<INPUT
ACCESSKEY=key
CLASS=classname
DISABLED
ID=value
MAXLENGTH=n
READONLY
STYLE=css1-properties
TYPE=BUTTON | CHECKBOX | FILE | HIDDEN | IMAGE | 
     PASSWORD | RADIO | RESET | SUBMIT | TEXT
VALUE=value
VOICEFILE=url
GRAMMAR=url | strings
LANGUAGE=JAVASCRIPT | JSCRIPT | VBSCRIPT | VBS
event = script
>

从这个定义中,我们发现 input 标签包括 BUTTONCHECKBOXFILEHIDDENIMAGEPASSWORDRADIORESETSUBMITTEXT 类型。从命令窗口 UI 的角度来看,BUTTONSUBMITIMAGERESET 是按钮。FILEHIDDENPASSWORDTEXT 是编辑控件。CHECKBOXRADIO 与 Windows 中同名的控件类似。列表中没有组合框和列表框!这些控件在 HTML 中表示为 SELECT

在标准的 Windows UI 中,有一个控件用于处理日历或时间。但在 HTML 中,没有时间和日历控件。我们需要通过组合多个控件来完成这项任务。在 HTML 中,我们可以为指定的 HTML 标签分配自定义属性名,以指示一组控件代表日期/时间或日历。

这个类做什么?

在这个类中,我们实现了以下功能:

  1. 从现有的 HTML 文件中提取所有控件。
  2. 确定当前 HTML 元素的控件类型。
  3. 为现有的选择(ComboBox)设置新的字典。
  4. 清除选择中的所有选项。
  5. 查找 HTML 标签集,这些标签带有自定义属性“mydate”或“mytime”,用于指定的日期/时间控件。
  6. 通过在 name 属性中定义相同的名称规则,查找一组单选按钮。

如何向 select(Combobox)插入一组选项

在 HTML 中,组合框和列表框具有相同的标签名-----Select。它们之间的区别在于列表框具有非零的“size”属性。列表框中的项目列表是 HTML 中 OPTION 标签的集合。例如:

<select id="i_now_rule_hastwo" name="i_now_rule_hastwo" class="bot_border">
   <option>strong</option>
   <ption>mid</option>
   <option selected>weak</option>
</select>

OPTION 标签是列表控件中的选择。在示例代码中,有 3 个项目:strong、mid 和 weak 列在组合框中。要向 select 元素添加新项目,您必须创建 IHTMLOptionElement 并将其添加到给定的 select 中。根据 MSDN,“在将元素添加到集合之前,您必须首先使用 IHTMLDocument2::createElement 方法创建它。”实际上,这并不奏效。

为了将一系列 OPTIONs 插入到 select 中,您需要按以下步骤操作 HTML:

  1. 清空 select 对象中的所有 options。
  2. 从字典列表中获取指定名称的字典。
  3. 从字典列表中获取的字典中的字典项数量。
  4. 为字典中的每个项目构造一个新的 OPTION
  5. 将项目添加到组合框。

根据之前的注释,我们不能使用 IHTMLSelectElement 的 add 方法,那么我该如何创建元素呢?

您不能使用 IHTMLDocumentCreateElement 来创建 IHTMLOptionElement 来替换 SELECT 选项。此对象可以使用特殊接口 IHTMLOptionElementFactory 创建。令人难过的是,没有直接的方法可以从 IHTMLDocumentIHTMLElementIHTMLElementCollection 进入该接口。它必须从 IHTMLWindow2 获取!IHTMLWindow2 在哪里?嘿嘿,您应该使用 IHTMLDocument2get_Script。该死的文件!(请参阅文档:知识库文章 Q249232 HOWTO:从 HWND 获取 IHTMLDocument2。)

有关完整代码,请参见源文件。它的主要部分如下所示:

        ..................
    CComQIPtr<IHTMLWindow2> pWindow;
    CComPtr<IDispatch> pMyDisp;
    if ( FAILED(m_pDoc->get_Script (&pMyDisp)))
    {
        m_strErr = EHT_CANT_GET_SCRIPT;
        dictNode->Release();
        return FALSE;
    }
    pWindow = pMyDisp;


    IHTMLOptionElementFactory *pOptionFactory= NULL;
    if ( FAILED(pWindow->get_Option (&pOptionFactory)))
    {
        m_strErr = EHT_CANT_GET_OPTION_FACTORY;
        dictNode->Release ();
        return FALSE;
    }

    // Add each items to selection
    for (long l = 0 ; l < lNumItem ; l++ )
    {
        CString strItem ;
        long code = 0;

        // Get current item in the dictionary
        if ( !pDict->GetDictItem (dictNode,l,code,strItem))
        {
            dictNode->Release ();
            m_strErr.Format(EHT_DICT_ITEM, dictName,l);
            return FALSE;
        }

        IHTMLOptionElement *pOption=NULL;
        VARIANT_BOOL vt_b =VARIANT_FALSE;
        if (ldefCode == code || strDef == strItem )
            vt_b = VARIANT_TRUE;
        pOptionFactory->create (CComVariant(strItem), CComVariant(code), 
                             CComVariant(vt_b),CComVariant(vt_b),&pOption);

        // Add to selection tag
        if ( FAILED ( pSel->add ((IHTMLElement*)pOption,CComVariant(l))))
        {
            dictNode->Release ();
            m_strErr = EHT_ADD_OPTION_ITEM;
            return FALSE;
        }

如何使用这个类

使用这个类非常简单。

步骤 1:创建一个 ChtmlDocment 变量。

ChtmlDocument doc;

步骤 2:将当前的 IHTMLDocument2 接口指针设置为文档。

doc.SetDocument(m_spDoc);

步骤 3:调用 CDhtmlDocument 类提供的方法。

………………………
doc.AddDictElement( pElement ,_T(“MyDict”),m_pDict);
………………………

这个类将使用我之前写的 CXMLFile。接下来,我将发布一个 CDhtmlControlGroup 作为标准 Windows UI 管理器 CControlGroup 的最后一篇文章。这是细节的一部分。下一篇文章很快就会出来。

© . All rights reserved.