如鹏网 大学生计算机学习社区

CowNew开源团队

http://www.cownew.com 邮件请联系 about521 at 163.com

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  363 随笔 :: 2 文章 :: 808 评论 :: 0 Trackbacks
SWT中调用Automation的方式 这篇文章中我们介绍了SWT中通过Automation访问IE的方式,但是只是简单的URL导航,没有自动填表单、自动提交等功能。我们对其进行了升级,采用了新的操作方式,充分利用了SWT对OLE的支持,裁减掉大量代码。现在可以实现自动填表单、自动提交等功能。不过暂时还无法响应IE的事件。
核心代码如下:

package test;

import org.eclipse.swt.SWTException;
import org.eclipse.swt.internal.ole.win32.COM;
import org.eclipse.swt.internal.ole.win32.GUID;
import org.eclipse.swt.internal.ole.win32.IUnknown;
import org.eclipse.swt.ole.win32.OLE;
import org.eclipse.swt.ole.win32.OleClientSite;
import org.eclipse.swt.widgets.Composite;

/**
 *
 * @author 杨中科
 *
 */
public class AutomationClientSite extends OleClientSite
{
 public AutomationClientSite(Composite parent, int style, String progId)
 {
  super(parent, style);
  try
  {
   appClsid = getClassID(progId);
   if (appClsid == null)
    OLE.error(OLE.ERROR_INVALID_CLASSID);

   //使用CoCreateInstance创建一个进程外Automation服务器
   int[] address = new int[1];
   int result = COM.CoCreateInstance(getClassID(progId), 0,
     COM.CLSCTX_INPROC_SERVER | COM.CLSCTX_LOCAL_SERVER,
     COM.IIDIUnknown, address);
   if (result != COM.S_OK)
    OLE.error(OLE.ERROR_CANNOT_CREATE_OBJECT, result);

   objIUnknown = new IUnknown(address[0]);

  } catch (SWTException e)
  {
   dispose();
   disposeCOMInterfaces();
   throw e;
  }
 }

 protected GUID getClassID(String progId)
 {
  GUID guid = new GUID();
  // create a null terminated array of char
  char[] buffer = null;
  if (progId != null)
  {
   int count = progId.length();
   buffer = new char[count + 1];
   progId.getChars(0, count, buffer, 0);
  }
  if (COM.CLSIDFromProgID(buffer, guid) != COM.S_OK)
  {
   int result = COM.CLSIDFromString(buffer, guid);
   if (result != COM.S_OK)
    OLE.error(result);
  }
  return guid;
 }

}
public class OleUtils
{
 public static int getIdOfName(OleAutomation auto, String name)
 {
  int[] ret = auto.getIDsOfNames(new String[]{name});
  return ret[0];
 }
 
 public static void setProperty(OleAutomation auto, String name,Variant value)
 {
  int id = getIdOfName(auto, name);
  auto.setProperty(id, new Variant[]{value});
 }
 
 public static Variant getProperty(OleAutomation auto, String name)
 {
  int id = getIdOfName(auto, name);
  return auto.getProperty(id);
 }
 
 public static Variant invoke(OleAutomation auto, String name)
 {
  return invoke(auto,name,new Variant[0]);
 }
 
 public static Variant invoke(OleAutomation auto, String name,Variant... params)
 {
  int id = getIdOfName(auto, name);
  return auto.invoke(id,params);
 }
}



package test;

import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.Variant;

/**
 *
 * @author 杨中科
 *
 */
public class HtmlElement
{
 private OleAutomation auto;

 public HtmlElement(OleAutomation auto)
 {
  this.auto = auto;
 }

 protected OleAutomation getOleAutomation()
 {
  return auto;
 }

 public void setProperty(String name, Variant value)
 {
  OleUtils.setProperty(auto, name, value);
 }

 public Variant getPropertyAsVariant(String name)
 {
  Variant value = OleUtils.getProperty(auto, name);
  return value;
 }

 public void setProperty(String name, int value)
 {
  OleUtils.setProperty(auto, name, new Variant(value));
 }

 public int getPropertyAsInt(String name)
 {
  Variant value = OleUtils.getProperty(auto, name);
  return value.getInt();
 }

 public void setProperty(String name, boolean value)
 {
  OleUtils.setProperty(auto, name, new Variant(value));
 }

 public boolean getPropertyAsBool(String name)
 {
  Variant value = OleUtils.getProperty(auto, name);
  return value.getBoolean();
 }

 public void setProperty(String name, String value)
 {
  OleUtils.setProperty(auto, name, new Variant(value));
 }

 public String getPropertyAsString(String name)
 {
  Variant value = OleUtils.getProperty(auto, name);
  return value.getString();
 }

 public HtmlElement getPropertyAsHtmlElement(String name)
 {
  Variant value = OleUtils.getProperty(auto, name);
  return new HtmlElement(value.getAutomation());
 }

 public Variant invoke(String name,Variant... params)
 {
  return OleUtils.invoke(auto, name,params);
 }

 public int invoke_Int(String name,Variant... params)
 {
  return invoke(name,params).getInt();
 }

 public boolean invoke_Bool(String name,Variant... params)
 {
  return invoke(name,params).getBoolean();
 }

 public String invoke_String(String name,Variant... params)
 {
  return invoke(name,params).getString();
 }

 public HtmlElement invoke_HtmlElement(String name,Variant... params)
 {
  return new HtmlElement(invoke(name,params).getAutomation());
 }
}




package test;

import org.eclipse.swt.ole.win32.OleAutomation;
import org.eclipse.swt.ole.win32.OleClientSite;
import org.eclipse.swt.ole.win32.Variant;

/**
 * 更多方法参考MSDN“InternetExplorer Object”文档
 *
 * @author 杨中科
 *
 */
public class IEAutomation extends HtmlElement
{

 public IEAutomation(OleClientSite clientSite)
 {
  super(new OleAutomation(clientSite));
 }

 public void setVisible(boolean value)
 {
  setProperty("Visible", value);
 }

 public boolean isVisible()
 {
  return getPropertyAsBool("Visible");
 }

 public void setMenuBar(boolean value)
 {
  setProperty("MenuBar", value);
 }

 public boolean isMenuBar()
 {
  return getPropertyAsBool("MenuBar");
 }

 public void setStatusBar(boolean value)
 {
  setProperty("StatusBar", value);
 }

 public boolean isStatusBar()
 {
  return getPropertyAsBool("StatusBar");
 }
 
 public void setToolBar(boolean value)
 {
  setProperty("ToolBar", value);
 }

 public boolean isToolBar()
 {
  return getPropertyAsBool("ToolBar");
 }
 
 public int getHWND()
 {
  return getPropertyAsInt("HWND");
 }
 
 public String getReadyState()
 {
  return getPropertyAsString("ReadyState");
 }
 
 public String getLocationURL()
 {
  return getPropertyAsString("LocationURL");
 }
 
 public boolean getBusy()
 {
  return getPropertyAsBool("Busy");
 }

 public void navigate(String url)
 {
  invoke("Navigate", new Variant(url));
 }

 public HtmlElement getDocument()
 {
  return getPropertyAsHtmlElement("Document");
 }

 public String getInnerHtml()
 {
  HtmlElement document = getPropertyAsHtmlElement("Document");
  HtmlElement body = document.getPropertyAsHtmlElement("body");
  return body.getPropertyAsString("innerHtml");
 }

 public HtmlElement getElementById(String id)
 {
  HtmlElement document = getDocument();
  return document.invoke_HtmlElement("getElementById", new Variant(id));
 }

 public void quit()
 {
  invoke("Quit");
 }
}




使用范例:

 protected void 自动填表()
 {
  //"kw"为关键字输入框
  HtmlElement txtKW = ie.getElementById("kw");
  //自动填表
  txtKW.setProperty("value", "杨中科");
  HtmlElement btnSB = ie.getElementById("sb");
  //自动点击【百度一下】按钮自动提交查询
  btnSB.invoke("click");
 }
 private void automation() throws Exception
 {
  OleFrame frame = new OleFrame(composite, SWT.NONE);
  AutomationClientSite client =
   new AutomationClientSite(frame,SWT.NONE,"InternetExplorer.Application");   
 
  ie = new IEAutomation(client);
  ie.setVisible(true);
  ie.setMenuBar(false);
  ie.setToolBar(false);
  ie.setStatusBar(false);
  
  int hwnd = ie.getHWND();
  OS.SetParent(hwnd, composite.handle);
  // 窗口最大化
  OS.SendMessage(hwnd, OS.WM_SYSCOMMAND, OS.SC_MAXIMIZE, 0);
  OS.SendMessage(hwnd, OS.WM_ACTIVATE, 0, 0);
  
  ie.navigate("http://www.baidu.com");
  //等待加载完毕,正确的方式应该是在网页onComplete的时候继续执行,但是没弄明白OLE 的EventSink机制怎么搞到SWT中来
  //所以先凑合着Sleep循环检测getBusy()的值,当不busy的时候再进行后续处理
  while(ie.getBusy())
  {
   Thread.sleep(10);
  }
  msgBox(ie.getInnerHtml());
  //"sb"为【百度一下】这个按钮的id
  HtmlElement btnSB = ie.getElementById("sb");
  //取value属性
  String txt = btnSB.getPropertyAsString("value");
  msgBox("按钮上的文字:"+txt);
  msgBox("网址:"+ie.getLocationURL());
  
  composite.addDisposeListener(new DisposeListener() {
   public void widgetDisposed(DisposeEvent e)
   {
    //必须手动指定退出,否则会报异常
    ie.quit();
   }
  });
 }

posted on 2008-06-30 21:08 CowNew开源团队 阅读(1385) 评论(2)  编辑  收藏

评论

# re: SWT中通过Automatioin的方式访问IE(升级版) 2010-10-19 17:01 apple
写得很好,不过我调试了,怎么有些问题,楼主能否把 源码发一份给我,
调试看看效果。 非常感谢 gongyg at gmail.com.  回复  更多评论
  

# re: SWT中通过Automatioin的方式访问IE(升级版) 2011-09-10 15:25 科哥
科哥, 你的例子很好,但是请问一下怎样知道一个IE平时发出哪些事件,在哪里有得查,
client.addListener(new Listener()
{
public void handleEvent(Event event)
{

System.out.println(event.type);
System.out.println();
}
});


发出来的Type,有没有手册可以查

我的邮箱414149609@qq.com  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: