使用Eclipse RCP進(jìn)行桌面程序開發(fā)(四):在Windows中使用Active X控件
Posted on 2006-11-28 12:24 京山游俠 閱讀(16802) 評(píng)論(7) 編輯 收藏 所屬分類: 擁抱Eclipse RCP
使用Eclipse RCP進(jìn)行桌面程序開發(fā)(一):快速起步
使用Eclipse RCP進(jìn)行桌面程序開發(fā)(二):菜單、工具欄和對(duì)話框
使用Eclipse RCP進(jìn)行桌面程序開發(fā)(三):視圖和透視圖
看完這篇文章,可以開發(fā)如下的界面:
沒有嵌入Active X控件的視圖:

嵌入瀏覽器控件,并顯示www.aygfsteel.com的主頁:

在Windows系統(tǒng)下,OLE和Active X控件是兩個(gè)非常吸引人的技術(shù),它們的基礎(chǔ)都是COM。OLE的體驗(yàn),就是平時(shí)我們可以把Excel表格嵌入Word文檔,或者把PDF嵌入瀏覽器顯示一樣,而Active X控件更是無處不在,做VB開發(fā)和網(wǎng)頁開發(fā)的人都應(yīng)該很熟悉。使用Windows系統(tǒng)中豐富的Active X控件資源,我們可以實(shí)現(xiàn)功能非常強(qiáng)大的程序。
在Windows平臺(tái)下,SWT圖形工具包提供了對(duì)OLE的支持,Active X控件和OLE文檔都可以被很方便地嵌入SWT窗口部件或者JFace部件,在這里,我只討論將Active X控件插入視圖。
在一個(gè)視圖中包含一個(gè)Active X控件需要兩個(gè)對(duì)象的支持,即一個(gè)OleFrame和一個(gè)OleClientSite對(duì)象。如果需要?jiǎng)?chuàng)建一個(gè)OLE應(yīng)用,需要先后創(chuàng)建他們。創(chuàng)建OleFrame對(duì)象比較簡單,OleFrame類定義在org.eclipse.swt.ole.win32中,創(chuàng)建OleFrame對(duì)象只需要簡單的new就可以,如下:
在OleFrame的基礎(chǔ)上就可以創(chuàng)建OleClientSite對(duì)象,創(chuàng)建該對(duì)象需要知道控件的programID,這個(gè)ID的信息存放在windows的注冊(cè)表中。在我們這篇文章的例子中,我們使用的是一個(gè)瀏覽器控件,那么我們?cè)趺粗罏g覽器控件的ProgID呢?我使用的是Visual Studio 2003自帶的OleView工具,如下圖:

可以看到,Microsoft Web 瀏覽器的ProgID為Shell.Explorer.2,我們可以這樣創(chuàng)建OleClientSite對(duì)象:
創(chuàng)建對(duì)象后,還需要激活,才能夠在RCP程序中對(duì)這些OLE對(duì)象進(jìn)行操作。如下:
client.doVerb(OLE.OLEIVERB_SHOW);
然后,我們需要操作這個(gè)Active X控件,調(diào)用它的方法,或者設(shè)置它的屬性。比如在此例中,我們需要調(diào)用瀏覽器控件的navigate方法,以便我們的瀏覽器控件顯示www.aygfsteel.com的主頁。對(duì)Active X控件的操作通過OleAutomation對(duì)象來實(shí)現(xiàn),創(chuàng)建OleAutomation對(duì)象的方法如下:
OleAutomation?automation?=?new?OleAutomation(client);再通過automation.invoke()來調(diào)用Active X控件的方法,其中invoke方法有幾種重載形式,有只帶一個(gè)int參數(shù)的,也有帶int和Variant[]兩個(gè)參數(shù)的,其中的int參數(shù)表示要調(diào)用的Active X控件的方法的ID,Variant[]參數(shù)就是要傳遞給Active X控件的方法的參數(shù)。
這里我們要說一說Variant類,這個(gè)類提供了多個(gè)構(gòu)造函數(shù),可以方便的將int,float,long,double,string等等基本數(shù)據(jù)類型封裝為Variant,比如我們要傳遞給瀏覽器控件的navigate方法的地址參數(shù):
Variant?url?=?new?Variant("http://www.aygfsteel.com");
那么我們?cè)趺床拍艿玫紸ctive X控件的方法的ID,還有它需要哪些參數(shù)呢?還是要借助前面提到的OleView.exe工具,如下圖:


可以看到,Navigate方法的id為0x00000068,轉(zhuǎn)化為十進(jìn)制就是104,而它需要的參數(shù)第一個(gè)是一個(gè)字符串,其它的都是可選的,因此,我們可以這樣調(diào)用它的方法:
Variant?url?=?new?Variant("http://www.aygfsteel.com/");

automation.invoke(104,?new?Variant[]
{url});
下面,貼出本文例子中的視圖的代碼和菜單Action的代碼,在寫這篇文章之前,我一直在探索怎樣從菜單控制視圖,后來發(fā)現(xiàn)是這樣:
?window.getActivePage.getViewReferences();
雖然我不知道Eclipse中Page的概念究竟是什么,但是只要能找到我要操作的視圖就可以了。視圖的代碼如下:
OleView.java
在這個(gè)視圖中,我創(chuàng)建了OleFrame對(duì)象,并讓它是public的,至于OleClientSite和OleAutomation對(duì)象,我們?cè)邳c(diǎn)擊菜單項(xiàng)后創(chuàng)建。菜單動(dòng)作的代碼如下:
OpenFileAction.java
根據(jù)前面幾節(jié)將的內(nèi)容配置plugin.xml和修改Perspective.java的代碼,就可以看到文章開頭的效果了。
使用Eclipse RCP進(jìn)行桌面程序開發(fā)(二):菜單、工具欄和對(duì)話框
使用Eclipse RCP進(jìn)行桌面程序開發(fā)(三):視圖和透視圖
看完這篇文章,可以開發(fā)如下的界面:
沒有嵌入Active X控件的視圖:
嵌入瀏覽器控件,并顯示www.aygfsteel.com的主頁:
在Windows系統(tǒng)下,OLE和Active X控件是兩個(gè)非常吸引人的技術(shù),它們的基礎(chǔ)都是COM。OLE的體驗(yàn),就是平時(shí)我們可以把Excel表格嵌入Word文檔,或者把PDF嵌入瀏覽器顯示一樣,而Active X控件更是無處不在,做VB開發(fā)和網(wǎng)頁開發(fā)的人都應(yīng)該很熟悉。使用Windows系統(tǒng)中豐富的Active X控件資源,我們可以實(shí)現(xiàn)功能非常強(qiáng)大的程序。
在Windows平臺(tái)下,SWT圖形工具包提供了對(duì)OLE的支持,Active X控件和OLE文檔都可以被很方便地嵌入SWT窗口部件或者JFace部件,在這里,我只討論將Active X控件插入視圖。
在一個(gè)視圖中包含一個(gè)Active X控件需要兩個(gè)對(duì)象的支持,即一個(gè)OleFrame和一個(gè)OleClientSite對(duì)象。如果需要?jiǎng)?chuàng)建一個(gè)OLE應(yīng)用,需要先后創(chuàng)建他們。創(chuàng)建OleFrame對(duì)象比較簡單,OleFrame類定義在org.eclipse.swt.ole.win32中,創(chuàng)建OleFrame對(duì)象只需要簡單的new就可以,如下:
1
OleFrame?frame?=?new?OleFrame(parent,?SWT.NONE);
在這個(gè)構(gòu)造函數(shù)中,第一個(gè)參數(shù)指的是該OleFrame的母窗口部件,即Active X控件將要被嵌入的窗口部件。
在OleFrame的基礎(chǔ)上就可以創(chuàng)建OleClientSite對(duì)象,創(chuàng)建該對(duì)象需要知道控件的programID,這個(gè)ID的信息存放在windows的注冊(cè)表中。在我們這篇文章的例子中,我們使用的是一個(gè)瀏覽器控件,那么我們?cè)趺粗罏g覽器控件的ProgID呢?我使用的是Visual Studio 2003自帶的OleView工具,如下圖:
可以看到,Microsoft Web 瀏覽器的ProgID為Shell.Explorer.2,我們可以這樣創(chuàng)建OleClientSite對(duì)象:
1
OleClientSite?client?=?new?OleClientSite(frame,SWT.NONE,"Shell.Explorer.2");

創(chuàng)建對(duì)象后,還需要激活,才能夠在RCP程序中對(duì)這些OLE對(duì)象進(jìn)行操作。如下:

然后,我們需要操作這個(gè)Active X控件,調(diào)用它的方法,或者設(shè)置它的屬性。比如在此例中,我們需要調(diào)用瀏覽器控件的navigate方法,以便我們的瀏覽器控件顯示www.aygfsteel.com的主頁。對(duì)Active X控件的操作通過OleAutomation對(duì)象來實(shí)現(xiàn),創(chuàng)建OleAutomation對(duì)象的方法如下:

這里我們要說一說Variant類,這個(gè)類提供了多個(gè)構(gòu)造函數(shù),可以方便的將int,float,long,double,string等等基本數(shù)據(jù)類型封裝為Variant,比如我們要傳遞給瀏覽器控件的navigate方法的地址參數(shù):

那么我們?cè)趺床拍艿玫紸ctive X控件的方法的ID,還有它需要哪些參數(shù)呢?還是要借助前面提到的OleView.exe工具,如下圖:
可以看到,Navigate方法的id為0x00000068,轉(zhuǎn)化為十進(jìn)制就是104,而它需要的參數(shù)第一個(gè)是一個(gè)字符串,其它的都是可選的,因此,我們可以這樣調(diào)用它的方法:




下面,貼出本文例子中的視圖的代碼和菜單Action的代碼,在寫這篇文章之前,我一直在探索怎樣從菜單控制視圖,后來發(fā)現(xiàn)是這樣:
?window.getActivePage.getViewReferences();
雖然我不知道Eclipse中Page的概念究竟是什么,但是只要能找到我要操作的視圖就可以了。視圖的代碼如下:
OleView.java
?1
package?cn.blogjava.youxia.views;
?2
?3
import?org.eclipse.jface.action.IMenuManager;
?4
import?org.eclipse.jface.action.IToolBarManager;
?5
import?org.eclipse.swt.SWT;
?6
import?org.eclipse.swt.widgets.Composite;
?7
import?org.eclipse.ui.part.ViewPart;
?8
import?org.eclipse.swt.ole.win32.OleFrame;
?9
10
public?class?OleView?extends?ViewPart?
{
11
????public?OleFrame?frame;
12
13
????public?static?final?String?ID?=?"cn.blogjava.youxia.views.OleView";?//$NON-NLS-1$
14
15
????/**?*//**
16
?????*?Create?contents?of?the?view?part
17
?????*?@param?parent
18
?????*/
19
????@Override
20
????public?void?createPartControl(Composite?parent)?
{
21
????????frame?=?new?OleFrame(parent,?SWT.NONE);
22
????????
23
????????//
24
????????createActions();
25
????????initializeToolBar();
26
????????initializeMenu();
27
????}
28
29
????/**?*//**
30
?????*?Create?the?actions
31
?????*/
32
????private?void?createActions()?
{
33
????????//?Create?the?actions
34
????}
35
36
????/**?*//**
37
?????*?Initialize?the?toolbar
38
?????*/
39
????private?void?initializeToolBar()?
{
40
????????IToolBarManager?toolbarManager?=?getViewSite().getActionBars()
41
????????????????.getToolBarManager();
42
????}
43
44
????/**?*//**
45
?????*?Initialize?the?menu
46
?????*/
47
????private?void?initializeMenu()?
{
48
????????IMenuManager?menuManager?=?getViewSite().getActionBars()
49
????????????????.getMenuManager();
50
????}
51
52
????@Override
53
????public?void?setFocus()?
{
54
????????//?Set?the?focus
55
????}
56
57
}
58

?2

?3

?4

?5

?6

?7

?8

?9

10



11

12

13

14

15


16

17

18

19

20



21

22

23

24

25

26

27

28

29


30

31

32



33

34

35

36


37

38

39



40

41

42

43

44


45

46

47



48

49

50

51

52

53



54

55

56

57

58

在這個(gè)視圖中,我創(chuàng)建了OleFrame對(duì)象,并讓它是public的,至于OleClientSite和OleAutomation對(duì)象,我們?cè)邳c(diǎn)擊菜單項(xiàng)后創(chuàng)建。菜單動(dòng)作的代碼如下:
OpenFileAction.java
?1
package?cn.blogjava.youxia.actions;
?2
?3
?4
import?org.eclipse.jface.action.IAction;
?5
import?org.eclipse.jface.viewers.ISelection;
?6
import?org.eclipse.swt.SWT;
?7
import?org.eclipse.swt.ole.win32.OLE;
?8
import?org.eclipse.swt.ole.win32.OleClientSite;
?9
import?org.eclipse.ui.IWorkbenchWindow;
10
import?org.eclipse.ui.IWorkbenchWindowActionDelegate;
11
import?org.eclipse.ui.*;
12
import?cn.blogjava.youxia.views.*;
13
import?org.eclipse.swt.ole.win32.OleAutomation;
14
import?org.eclipse.swt.ole.win32.Variant;
15
16
public?class?OpenFileAction?implements?IWorkbenchWindowActionDelegate?
{
17
18
????IWorkbenchWindow?window;
19
????
20
????public?void?dispose()?
{
21
????????//?TODO?自動(dòng)生成方法存根
22
23
????}
24
25
????public?void?init(IWorkbenchWindow?window)?
{
26
????????//?TODO?自動(dòng)生成方法存根
27
????????this.window?=?window;
28
29
????}
30
31
????public?void?run(IAction?action)?
{
32
????????//?TODO?自動(dòng)生成方法存根
33
????????
34
????????IViewReference[]?vfs?=?window.getActivePage().getViewReferences();
35
????????IViewPart?vw;
36
????????for(int?i=0;?i<vfs.length;?i++)
{
37
?????????????vw?=?vfs[i].getView(false);
38
?????????????if(vw.getTitle().equals("使用Active?X控件"))
{
39
????????????????????OleClientSite?client?=?new?OleClientSite(((OleView)vw).frame,SWT.NONE,"Shell.Explorer.2");
40
????????????????????client.doVerb(OLE.OLEIVERB_SHOW);
41
????????????????????OleAutomation?oa?=?new?OleAutomation(client);
42
????????????????????Variant?str?=?new?Variant("http://www.aygfsteel.com/");
43
????????????????????oa.invoke(104,?new?Variant[]
{str});
44
????????
45
?????????????}
46
????????}
47
????????
48
????}
49
50
????public?void?selectionChanged(IAction?action,?ISelection?selection)?
{
51
????????//?TODO?自動(dòng)生成方法存根
52
53
????}
54
55
}
56

?2

?3

?4

?5

?6

?7

?8

?9

10

11

12

13

14

15

16



17

18

19

20



21

22

23

24

25



26

27

28

29

30

31



32

33

34

35

36



37

38



39

40

41

42

43



44

45

46

47

48

49

50



51

52

53

54

55

56

根據(jù)前面幾節(jié)將的內(nèi)容配置plugin.xml和修改Perspective.java的代碼,就可以看到文章開頭的效果了。