yehao's Blog

如何对webbrowser和IE编程(六)

使用VC++和COM API

尽管使用VC不像Vb中那么容易自动化IE,但是也不太难,尤其是你理解了CON和COM API。无论你使用MFC, ATL, 或者标准 C++自动化IE,方法都是一样—你使用COM API来实现.

VC++中创建一个Internet Explorer实例包括要调用COM API CoCreateInstance ,指定第一个参数为 CLSID_InternetExplorer 。创建IE自动化实例不像创建包含webbrowser的Activex控件困难。你不需要实现容器或者site对象的必要接口。

来看看如何容易的使用CoCreateInstance 创建IE实例吧。启动Visual C++, 新建MFC AppWizard (exe) 应用程序命名为 MfcAutoIE.选择dialog-based option, 认可其他缺省选项.

现在加入如VbAutoIE中的控件到表单.对话框看起来如 6-21. 分派ID到对话框的各个控件。 确信控件TAB次序如 Figure 6-22. (tab 次序影响到radio按钮的工作)

Figure 6-21. MfcAutoIE dialog. 

Figure 6-22. MfcAutoIE dialog tab order.

现在用右键菜单设置每一个隐藏radio按钮的Group ,属性设置如表 6-9.

Table 6-9. Member Variables for MfcAutoIE Dialog Controls

Control

 

 

 

 

Type

 

 

 

 

Member Variable

 

 

 

 

Hide radio button for AddressBar

 

 

 

 

int

 

 

 

 

m_nAddressBar

 

 

 

 

Edit box

 

 

 

 

CString

 

 

 

 

m_strStatusText

 

 

 

 

Hide radio button for MenuBar

 

 

 

 

int

 

 

 

 

m_nMenuBar

 

 

 

 

Hide radio button for StatusBar

 

 

 

 

int

 

 

 

 

m_nStatusBar

 

 

 

 

Hide radio button for ToolBar

 

 

 

 

int

 

 

 

 

m_nToolBar

 

 

 

 

我们使用ClassWizard 为表 6-9 中的控件建立变量时,他们自动加入到 CMfcAutoIEDlg. 成员变量设置为-1.

编译MfcAutoIE Example之前我们设置编译的Directory次序 属性

编译之前,你需要处理一些重要任务:

1.    确信你已经从MSDN中下载IE5的头文件和库文件。

2. Tools/Options 菜单的Directories确信lib路径中包含Internet Explorer 5 Windows 2000库文件.载列表中。

3. 配置Include 

 

现在我们加入代码使之工作。 首先你应当包含ExDisp.h到你的对话框头文件—MfcAutoIEDlg.h. ExDisp.h 是包含了WebBrowser接口和类ID的头文件.确信你已经从MSDN下载了最新的版本。

建立一个private 或者protected 的数据类型,指向IWebBrowser2  的指针,  命名为m_pInetExplorer. 如下

protected:
   IWebBrowser2* m_pInetExplorer;

现在在构造函数中初始化m_pInetExplorer 为 NULL 。你必须也初始化COM. 放置一个CoInitialize 的COM API调用在构造函数。构造函数看起来应当如下:

CMfcAutoIEDlg::CMfcAutoIEDlg(CWnd* pParent /*=NULL*/)
   : CDialog(CMfcAutoIEDlg::IDD, pParent),
     m_pInetExplorer(NULL)
{
   //{{AFX_DATA_INIT(CMfcAutoIEDlg)
   m_strStatusText = _T("");
   m_nAddressBar = -1;
   m_nMenuBar = -1;
   m_nStatusBar = -1;
   m_nToolBar = -1;
   //}}AFX_DATA_INIT
   //Note that LoadIcon does not require a subsequent DestroyIcon
   //in Win32.
   m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
 

 

   // Initialize COM
   CoInitialize(NULL);
}

建立一个析构函数,以便调用CoUninitialize API 函数用以反初始化 COM. 此处的析构函数:

CMfcAutoIEDlg::~CMfcAutoIEDlg()
{
   // Uninitialize COM.
   //
   CoUninitialize();
}

在预备工作之后, 让我们开始实现具体的控制。首先为Start IE5 按钮建立一个消息循环. 通常,你可以使用ClassWizard建立消息循环处理句柄在此消息句柄, 采用 CoCreateInstance API 建立一个IE实例。 此处初建的Internet Explorer实例初始化为隐藏, 所以你必须使用Visible属性使他可见。为了导航到用户的主页,使用GoHome 方法。此处为消息处理句柄代码:

void CMfcAutoIEDlg::OnStartIE5() 
{
   // If an instance of Internet Explorer has
   // not already been created, create one.
   // This instance will initially be hidden,
   // so make it visible by using the Visible
   // property. Also, navigate to the user's
   // home page by using the GoHome method.
   //
   if (m_pInetExplorer)
      MessageBox
         (_T("Only one instance of Internet Explorer is allowed."));
   else
   {
      HRESULT hr;
      hr = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_SERVER,
                           IID_IWebBrowser2, (LPVOID*)&m_pInetExplorer);
 

 

      if (SUCCEEDED(hr))
      {
         // Set the radio buttons to their correct values.
         SetRadioButtons();
 

 

         m_pInetExplorer->put_Visible(VARIANT_TRUE);
         m_pInetExplorer->GoHome();
      }
   }
}

在此代码中,我们首先检查是否IE的上一个实例已经建立。如果已经建立,将会显示一个错误消息框。(你仅仅能够启动一个IE的实例,随后你将可以看到如何检测IE窗口被关闭以便重置IE的数据成员。)如果一个IE的实例还未创建, CoCreateInstance 将 CLSID_InternetExplorer 作为第一个参数被调用. (此类 ID 定义于ExDisp.h ,为Internet Explorer的唯一标示符.)

第二个参数我们设定为NULL ,因为我们不希望此COM对象被聚合(be aggregated). 我们希望IE运行在一个单独的进程空间,所以我们指定第三个参数为特殊值 CLSCTX_SERVER .我们利用第四个参数指示哪一个接口我们将通过CoCreateInstance 调用创建一个COM对象后被创建。在此例中,我们将一直希望获得IWebBrowser2, 所以我们指定IID_IWebBrowser2 为第四个参数值。最后我们传送存储接口指针的变量. 对于此参数,你必须采用void类型传递一个指针的地址 (确信你传送的指针指向一个接口类型。)

如果一个IE实例成功创建,名为SetRadioButtons 的成员变量被创建。这是一个protected 成员函数,检查当前地址栏、菜单条、工具条和状态条等的状态 ,用来设置radio 按钮组的状态。.为检查每一个的状态我们简单的获取属性关联的当前值 。

C++ 应用中使用COM 没有包装类, 属性被引用为使用 get_ and put_ 方法.为检取每一个用户问题的状态,我们简单的调用每一个关联的(UI)项目的get_ 方法 .除了 get_ToolBar外其他get_方法返回指向VARIANT_BOOL 数据类型,返回值指示用户接口是否可见或者隐藏。如果用户接口元素可见,将返回VARIANT_TRUE 。如果该项目是隐藏的,将返回VARIANT_FALSE 。这些值区别于TRUE和 FALSE 的用法.

提醒


当在Visual C++涉及 VARIANT_BOOL , 你必须使用VARIANT_TRUE 或者VARIANT_FALSE 代替 TRUE or FALSEVARIANT_TRUE定义值 0xffff TRUE 定义为1如果你比较 VARIANT_TRUE  TRUE你将发现在Vb中不匹配,你可以在涉及到VARIANT_BOOL使用truefalse是由于VB替你实现了转换。

get_ToolBar 方法不同于其他属性,因为它指向一个整型指针,所以我们如果发现返回非0,工具条可见。如果整型值是0,工具条将隐藏:

 

提醒


如果一个属性只读put_ 将不会出现。同样,如果一个属性只写,将不会出现get_ 方法。

此处为 SetRadioButtons 方法的代码:

void CMfcAutoIEDlg::SetRadioButtons()
{
   VARIANT_BOOL vtBool = VARIANT_TRUE;
 

 

   // Get the current state of the AddressBar.
   //
   m_pInetExplorer->get_AddressBar(&vtBool);
   m_nAddressBar = (vtBool == VARIANT_TRUE) ? 1 : 0;
 

 

   // Get the current state of the MenuBar.
   //
   m_pInetExplorer->get_MenuBar(&vtBool);
   m_nMenuBar = (vtBool == VARIANT_TRUE) ? 1 : 0;
 

 

   // Get the current state of the StatusBar.
   //
   m_pInetExplorer->get_StatusBar(&vtBool);
   m_nStatusBar = (vtBool == VARIANT_TRUE) ? 1 : 0;
 

 

   // Get the current state of the ToolBar.
   // Unlike the other get methods, get_ToolBar
   // takes a pointer to an integer.
   //
   m_pInetExplorer->get_ToolBar(&m_nToolBar);
 

 

   UpdateData(FALSE);  // Initializes dialog box with changed values.
}

:

void CMfcAutoIEDlg::OnAddrBarShowHide() 
{
   UpdateData(TRUE);
 

 

   if (m_pInetExplorer)
   {
      VARIANT_BOOL vtShow = 
         m_nAddressBar ? VARIANT_TRUE : VARIANT_FALSE;
 

 

      m_pInetExplorer->put_AddressBar(vtShow);
   }
}
 

 

void CMfcAutoIEDlg::OnMenuBarShowHide() 
{
   UpdateData(TRUE);
 

 

   if (m_pInetExplorer)
   {
      VARIANT_BOOL vtShow = 
         m_nMenuBar ? VARIANT_TRUE : VARIANT_FALSE;
 

 

      m_pInetExplorer->put_MenuBar(vtShow);
   }
}
 

 

void CMfcAutoIEDlg::OnStatusBarShowHide() 
{
   UpdateData(TRUE);
 

 

   if (m_pInetExplorer)
   {
      VARIANT_BOOL vtShow = 
         m_nStatusBar ? VARIANT_TRUE : VARIANT_FALSE;
 

 

      m_pInetExplorer->put_StatusBar(vtShow);
   }
}
 

 

void CMfcAutoIEDlg::OnToolBarShowHide() 
{
   UpdateData(TRUE);
 

 

   if (m_pInetExplorer)
      m_pInetExplorer->put_ToolBar(m_nToolBar);
}

注意到OnToolBarShowHide 方法中我们将m_nToolBar 数据成员传递给put_ToolBar 方法替代了VARIANT_BOOL. 我们暂时不解释为什么,就像get_ToolBarput_ToolBar 传递一个整型而不是VARIANT_BOOL.

现在利用ClassWizard 建立一个Change 按钮的消息循环处理句柄 。此消息的句柄将在任何时候设定set Internet Explorer 的状态条为edit 输入框内容。 代码看起来如下:

void CMfcAutoIEDlg::OnChangeStatusText() 
{
   UpdateData(TRUE);
 

 

   if (m_pInetExplorer)
   {
      _bstr_t bstrStatusText = m_strStatusText.AllocSysString();
      m_pInetExplorer->put_StatusText(bstrStatusText);
   }
}

确信你在第一个任务就是调用传递TRUE的 UpdateData and .这样的目的是更新对阿框中所有相关的控件, 包括 m_strStatusText. 如果m_pInetExplorer 不是NULL—那意味着 Internet Explorer一个实例已经被创建— StatusText 被设定为用户输入的文字。 StatusText 同样事采用put_ 设定Visible 属性。 该函数需要一个BSTR的入口参数,所以调用 AllocSysString 方法使得m_strStatusText 数据成员变量分派为BSTR 可以传递给put_StatusTextAllocSysString 是CString 的方法,返回一个Cstring对象中值的 BSTR 类型。BSTR 返回自 AllocSysString 存储于_bstr_t类型的变量, 一个 COM 编译器支持的Visual C++类。为了使用此类,你必须包含comdef.h 头文件,置于对话框实现文件CMfcAutoIEDlg—MfcAutoIEDlg.cpp. 该类将小心处理BSTR离开当前范围的状况,所以你不需要调用SysFreeString Win32 API 以释放调用put_StatusText.之后的BSTR.

至此,我们基本上完成了。为了使用户输入Enter时不关闭对话框,重写基类对话框的OnOK方法。在此方法中,简单的不做任何事。确信你没有调用基类的CDialog::OnOK 方法,否则,对话框会关闭。

现在来重写OnCancel 的基类方法, 该方法调用于用户按下ESC或者点击对话框的右键菜单的关闭或者对话框的X按钮。在 OnCancel中,如果一个Internet Explorer 实例已经被创建, 在调用Quit 方法时关闭InternetExplorer 对象。 Quit 甚至可以在用户默认关掉Internet Explorer. 如果出现此情形, Quit 方法将返回 RPC_S_SERVER_UNAVAILABLE, 标示Internet Explorer 不再可用.你可以简单忽略此错误消息。以下为OnCancel的代码:

void CMfcAutoIEDlg::OnCancel()
{
   if (m_pInetExplorer)
      m_pInetExplorer->Quit();
 

 

   CDialog::OnCancel();
}

最后, 你必须释放掉指向IE的IWebBrowser2 接口指针。你可以在对话框的析构函数中处理。此处为更型后的析构函数:

 

CMfcAutoIEDlg::~CMfcAutoIEDlg()
{
   // Release the WebBrowser interface pointer
   //
   if (m_pInetExplorer)
   {
      m_pInetExplorer->Release();
      m_pInetExplorer = NULL;
   }
 

 

   // Uninitialize COM
   //
   CoUninitialize();
}
现在,通常我们可以编译运行对话框应用程序。启动IE实例,测试。

posted on 2012-09-22 21:45 厚积薄发 阅读(704) 评论(0)  编辑 收藏 引用 所属分类: Windows编程


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

统计

常用链接

留言簿

随笔分类

文章分类

文章档案

搜索

最新评论