为了实现办公的自动化,需要实现文档的自动流转。开发出的WORD和WPS插件的功能包括显示批注、隐藏批注、引入文件、附加对象、保存文档、退出应用。
开发语言的选择,可以选择C++和C#。
Visual Studio 2010提供了各个版本Office的插件开发,新建工程-按照的模板-Visual C#-Office-2010,运行程序时其会调用本地安装的Office;文件-选项-加载项-COM加载项,在此可以选择COM加载项。
(1) Word开发引用的文件有Microsoft.Office.Interop.Word及Office
(2) 使用的命名空间
using Word = Microsoft.Office.Interop.Word;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Word;
Visual Studio提供了本地WORD插件开发的示例,所在路径
Visual Studio2010-Help-Samples-local Samples folder。
1.2.0.1 官方API
根据官方提供的API,可以实现对word的操作。
1.2.0.2 调用对话框(属于API范畴)
通过word提供的对话框方法调用Word.WdWordDialog.wdDialogInsertObject,打开“附加对象“对话框。
this.Application.Dialogs[Word.WdWordDialog.wdDialogInsertObject].Execute();
1.2.0.3 word控件
获取其控件,然后执行Excute,打开“附加对象”对话框
this.Application.ActiveDocument.CommandBars["Menu Bar"].Controls[4]).CommandBar.Controls[16].Execute();
Word.Application app = new Word.Application(); Word.Document dd = app.Documents.Open("C:\\hi12.docx");
微软在word使用了Ribbon Interface,通过该接口可以获取所有的菜单和工具栏的命令。具体见:
http://office.microsoft.com/en-us/outlook-help/learn-where-menu-and-toolbar-commands-are-in-office-2010-and-related-products-HA101794130.aspx#_Toc268688374
1.3.2.1 两层节点访问方式
word一般是通过CommandBar/CommandBars和Control/Controls访问控件。只有两层的访问方式:第一层,直接访问CommandBar/CommandBars,通过CommandBar/CommandBars访问其下的Control/Controls。
如:
获取Show Markup命令条下几个Controls:
Globals.IRHelperBar.Application.ActiveDocument.CommandBars["Show Markup"].Controls.Count;
执行Show Markup命令条下的第7个Controls的实体的方法:
Globals.IRHelperBar.Application.ActiveDocument.CommandBars["Show Markup"].Controls[7].Excute();
1.3.2.2 多层节点的访问方式
1)子节点访问方式
如果Control下面还有子节点,查看其CommandBar下的Name;通过此名获访问其下的Controls。类似多叉树的访问方式。
Globals.IRHelperBar.Application.ActiveDocument.CommandBars["Reviewers"].Controls[1];
2)三层节点的访问方式
正常只是提供两级的访问结构CommandBars-Controls;如果有第三级并且需要访问,那么把Control提升为Command,创新构造两级结构Command-Control,从而实现第三层的访问。
This.Application.ActiveDocument.CommandBars["Menu Bar"].Controls[4]).CommandBar.Controls[16].Execute();
1.3.3.1 显示/隐藏标注
1)隐藏标注
调用API方式
wdApp.ActiveWindow.View.ShowRevisionsAndComments = False
控件方式
((dynamic)Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Reviewing"].Controls[1]).Control.ListIndex = 2;
2)显示标注
调用API方式
wdApp.ActiveWindow.View.ShowRevisionsAndComments = True
控件方式
((dynamic)Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Reviewing"].Controls[1]).Control.ListIndex = 1;
3)切换显示/隐藏标注
Globals.ThisAddIn.Application.Application.ActiveDocument.CommandBars["Show Markup"].Controls[3].Execute();
1.3.3.2 隐藏/显示审阅窗格
执行下面的语句,可以开始打开/关闭审阅窗格
doc.CommandBars["Reviewing"].Controls["Reviewing Pane"].Execute();
1.3.3.3 引入文件
((dynamic)Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Menu Bar"].Controls[4]).CommandBar.Controls[16].Execute();
1.3.3.4 附加对象
((dynamic)Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Menu Bar"].Controls[4]).CommandBar.Controls[17].Execute();
1.3.3.5 保存文件
Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Standard"].Controls[3].Execute();
1.3.3.6 退出应用
((dynamic)Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Menu Bar"].Controls[1]).CommandBar.Controls[21].Execute();
//Create Word Application
Word.Application wordApp = new Microsoft.Office.Interop.Word.Application();
//Create a new txt file to record controls' list
StreamWriter sw = System.IO.File.CreateText(@"C:\Word Command Bar Control List.txt");
//loop through wordApp.CommandBars to get all CommandBars
foreach (Office.CommandBar cb in wordApp.CommandBars)
{
sw.WriteLine(cb.Name);
//loop through each CommandBar's Controls collection to get all controls
foreach (Office.CommandBarControl cbc in cb.Controls)
{
sw.WriteLine("\t" + cbc.Caption);
}
}
http://support.microsoft.com/kb/302817
最小化word窗口时,关闭
Form1 fm;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
fm = new Form1();
fm.Show();
// fm.TopMost=false;
// this.Application.ActiveDocument.Windows.Count;
object aa = this.Application.ActiveDocument.CommandBars["Show Markup"].Controls[3].OnAction;
this.Application.WindowSize+=new Word.ApplicationEvents4_WindowSizeEventHandler(Application_WindowSize);
}
private void Application_WindowSize(Word.Document Doc, Word.Window Wn)
{
if (this.Application.WindowState == Word.WdWindowState.wdWindowStateMinimize)
{
fm.Hide();
}
else
{
fm.Show();
}
}
WPS插件开发可以在WPS二次开发论坛http://bbs.wps.cn/forum-wpsercikaifa-1.html找到开发的资料。
开发语言
WPS可以使用C++、VB6/VAB、.net三种语言
本人实现了C++、VB6/VAB两种语言的开发。
目前该种方法只在版本号为V9.1.0.4468中调试成功。
下载该向导:
http://bbs.wps.cn/forum.php?mod=viewthread&tid=22410767&extra=page%3D1%26filter%3Dtypeid%26typeid%3D151%26typeid%3D151
然后解压缩该文档,按照setup_vs2008.js,显示安装成功及代表插件开发向导按照成功。
打开vs2008-新建工程,即可以看到WPS Office插件开发模板。
在OnConnection函数中添加插件功能。
功能实现部分,test.h文件。
#pragma once
class __declspec(uuid("{D31D0AB3-B6A5-4FA7-A0C0-179DB9FBFF72}")) test;
_declspec(selectany) _ATL_FUNC_INFO OnClickButtonInfo =
{
CC_STDCALL,
VT_EMPTY,
2,
{ VT_DISPATCH, VT_BYREF | VT_BOOL }
};
using namespace AddInDesignerObjects;
class test :
public CComObjectRootEx
public CComCoClass
public IDispatchImpl<_IDTExtensibility2, &IID__IDTExtensibility2, &LIBID_AddInDesignerObjects>,
public IDispEventSimpleImpl<1, test, &DIID__CommandBarButtonEvents>,
public IDispEventSimpleImpl<2, test, &DIID__CommandBarButtonEvents>,
public IDispEventSimpleImpl<3, test, &DIID__CommandBarButtonEvents>,
public IDispEventSimpleImpl<4, test, &DIID__CommandBarButtonEvents>,
public IDispEventSimpleImpl<5, test, &DIID__CommandBarButtonEvents>,
public IDispEventSimpleImpl<6, test, &DIID__CommandBarButtonEvents>,
public IDispEventSimpleImpl<7, test, &DIID__CommandBarButtonEvents>
{
private:
WPS::_ApplicationPtr m_spWPSApp;
_CommandBarButtonPtr m_spButton1;
_CommandBarButtonPtr m_spButton2;
_CommandBarButtonPtr m_spButton3;
_CommandBarButtonPtr m_spButton4;
_CommandBarButtonPtr m_spButton5;
_CommandBarButtonPtr m_spButton6;
_CommandBarButtonPtr m_spButton7;
public:
DECLARE_REGISTRY_RESOURCEID(IDR_WPSCOMADDONS)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(test)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(_IDTExtensibility2)
END_COM_MAP()
BEGIN_SINK_MAP(test)
SINK_ENTRY_INFO(1, DIID__CommandBarButtonEvents, 0x01, OnClickButton1, &OnClickButtonInfo)
SINK_ENTRY_INFO(2, DIID__CommandBarButtonEvents, 0x01, OnClickButton2, &OnClickButtonInfo)
SINK_ENTRY_INFO(3, DIID__CommandBarButtonEvents, 0x01, OnClickButton3, &OnClickButtonInfo)
SINK_ENTRY_INFO(4, DIID__CommandBarButtonEvents, 0x01, OnClickButton4, &OnClickButtonInfo)
SINK_ENTRY_INFO(5, DIID__CommandBarButtonEvents, 0x01, OnClickButton5, &OnClickButtonInfo)
SINK_ENTRY_INFO(6, DIID__CommandBarButtonEvents, 0x01, OnClickButton6, &OnClickButtonInfo)
SINK_ENTRY_INFO(7, DIID__CommandBarButtonEvents, 0x01, OnClickButton7, &OnClickButtonInfo)
//SINK_ENTRY_INFO(3, __uuidof(ET::_ApplicationEvents),0x113005, SheetActivate, &SheetActivateInfo)
END_SINK_MAP()
typedef IDispEventSimpleImpl<1, test, &DIID__CommandBarButtonEvents> CommandBarButtonEvents1;
typedef IDispEventSimpleImpl<2, test, &DIID__CommandBarButtonEvents> CommandBarButtonEvents2;
typedef IDispEventSimpleImpl<3, test, &DIID__CommandBarButtonEvents> CommandBarButtonEvents3;
typedef IDispEventSimpleImpl<4, test, &DIID__CommandBarButtonEvents> CommandBarButtonEvents4;
typedef IDispEventSimpleImpl<5, test, &DIID__CommandBarButtonEvents> CommandBarButtonEvents5;
typedef IDispEventSimpleImpl<6, test, &DIID__CommandBarButtonEvents> CommandBarButtonEvents6;
typedef IDispEventSimpleImpl<7, test, &DIID__CommandBarButtonEvents> CommandBarButtonEvents7;
test()
{
}
~test()
{
}
public:
STDMETHOD(OnConnection)(IDispatch * Application,
ext_ConnectMode ConnectMode, IDispatch * AddInInst, SAFEARRAY * * custom)
{
try
{
m_spWPSApp = Application;
_CommandBarsPtr spCommandBars = m_spWPSApp->CommandBars;
CommandBarPtr spCommandBar = spCommandBars->Add("MOKA工具条",1 ,"",TRUE);
CommandBarControlsPtr ETCtrls =spCommandBar ->Controls;
KSO::CommandBarControlPtr popupButton1=ETCtrls->Add(1,"","",TRUE);
popupButton1->Caption = _bstr_t(L"显示标注");
KSO::CommandBarControlPtr popupButton2=ETCtrls->Add(1,"","",TRUE);
popupButton2->Caption = _bstr_t(L"隐藏标注");
KSO::CommandBarControlPtr popupButton3=ETCtrls->Add(1,"","",TRUE);
popupButton3->Caption = _bstr_t(L"打开文件");
KSO::CommandBarControlPtr popupButton4=ETCtrls->Add(1,"","",TRUE);
popupButton4->Caption = _bstr_t(L"附件对象");
KSO::CommandBarControlPtr popupButton5=ETCtrls->Add(1,"","",TRUE);
popupButton5->Caption = _bstr_t(L"保存文件");
KSO::CommandBarControlPtr popupButton6=ETCtrls->Add(1,"","",TRUE);
popupButton6->Caption = _bstr_t(L"退出应用");
//KSO::CommandBarControlPtr popupButton7=ETCtrls->Add(1,"","",TRUE);
//popupButton7->Caption = _bstr_t(L"文档模板");
CommandBarButtonEvents1::DispEventAdvise(popupButton1);
CommandBarButtonEvents2::DispEventAdvise(popupButton2);
CommandBarButtonEvents3::DispEventAdvise(popupButton3);
CommandBarButtonEvents4::DispEventAdvise(popupButton4);
CommandBarButtonEvents5::DispEventAdvise(popupButton5);
CommandBarButtonEvents6::DispEventAdvise(popupButton6);
//CommandBarButtonEvents7::DispEventAdvise(popupButton7);
}
catch(const _com_error&)
{
}
return S_OK;
}
STDMETHOD(OnDisconnection)(ext_DisconnectMode RemoveMode, SAFEARRAY * * custom)
{
return S_OK;
}
STDMETHOD(OnAddInsUpdate)(SAFEARRAY * * custom)
{
return S_OK;
}
STDMETHOD(OnStartupComplete)(SAFEARRAY * * custom)
{
return S_OK;
}
STDMETHOD(OnBeginShutdown)(SAFEARRAY * * custom)
{
return S_OK;
}
//隐藏标注
void __stdcall OnClickButton1(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
m_spWPSApp->ActiveWindow->View->ShowRevisionsAndComments = true;
}
catch (const _com_error& )
{
}
return;
}
//
void __stdcall OnClickButton2(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
m_spWPSApp->ActiveWindow->View->ShowRevisionsAndComments = false;
}
catch (const _com_error& )
{
}
return;
}
//打开文件
void __stdcall OnClickButton3(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
//m_spWPSApp->Selection->InsertFile("D:/win.txt",&vtMissing,&vtMissing,&vtMissing,&vtMissing);
// 引入文件
// WPS::WpsDialog aa = WPS::WpsDialog::wpsDialogInsertFile;
WPS::WpsDialog aa = WPS::WpsDialog::wpsDialogOpenFile;
m_spWPSApp->Dialogs->Item(aa)->Show();
}
catch (const _com_error& )
{
}
return;
}
//附加对象
void __stdcall OnClickButton4(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
// WPS::ShapeNodePtr pp = m_spWPSApp->ActiveDocument->Shapes->AddShape(ksoShapeActionButtonMovie, 100, 100, 200, 200,&vtMissing);
//m_spWPSApp->ActiveDocument->InlineShapes->AddOLEControl();
WPS::WpsDialog aa = WPS::WpsDialog::wpsDialogInsertOLEObject;
m_spWPSApp->Dialogs->Item(aa)->Execute();
}
catch (const _com_error& )
{
}
return;
}
//保存所有的文档
void __stdcall OnClickButton5(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
// m_spWPSApp->ActiveDocument->Save();
m_spWPSApp->CommandBars->Item[L"TabMenu Popup Menu"]->Controls->Item[L"保存所有文档(&E)"]->Execute();
}
catch (const _com_error& )
{
}
return;
}
//退出所有的文档并且一一询问是否需要保存修改过的文档,最后关闭应用
void __stdcall OnClickButton6(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
// m_spWPSApp->Documents->Close();
_variant_t tt=WPS::wpsPromptToSaveChanges;
m_spWPSApp->Quit(&tt,&vtMissing,&vtMissing);
}
catch (const _com_error& )
{
}
return;
}
};
程序运行后会直接调用本地安装WPS2013(V9.1.0.4468),该插件在开发工具-COM加载项中显示,并可以勾选决定是否加载该插件。
ofstream outfile("d://b.txt");
if(!outfile){
cout << "Unable to open otfile";
exit(1); // terminate with error
}
_bstr_t bstr = m_spWPSApp->CommandBars->Count;
CString strSql = (LPCSTR)bstr;
int b=_ttoi(strSql);
int a=0;
for(int a=1;a<=b;a++)
{
string strSql = (LPCSTR)m_spWPSApp->CommandBars->Item[a]->Name;
function openDoc () {
// body...
var openDocObj;
openDocObj = new ActiveXObject("SharePoint.OpenDocuments.2"); // 为了兼容Office XP,可以创建“SharePoint.OpenDocuments.1”
openDocObj.ViewDocument("http://localhost//葫芦岛三日游行程.doc");
}
“IE已限制此网页运行脚本或ActiveX控件”,允许运行该AtiveX控件,确定,即可以下载服务器的doc文档,在本地运行。但是chrome、Opera、firefox都不支持该控件。
3.2 注册表
b/s程序不允许调用本地的exe,如果是这样的话,互联网没有安全可言了
可以通过注册一个自己的协议的办法,如
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\form]
"URL Protocol"="D:\\form.exe"
@="form"
[HKEY_CLASSES_ROOT\form\DefaultIcon]
@="D:\\form.exe,1"
[HKEY_CLASSES_ROOT\form\shell]
[HKEY_CLASSES_ROOT\form\shell\open]
[HKEY_CLASSES_ROOT\form\shell\open\command]
@="\"D:\\form.exe\" \"%1\""
注册表工具的版本信息
HKEY_CLASSWES_ROOT\添加form树,树的名称对应自定义的URLProtocol的名称,web调用中需要用到这个名称
协议的名称,任意字符,后面不会用到
可应用程序的路径,只能是exe的程序
form添加一个分支,照抄
应用程序的路径,1照抄
form添加一个分支,照抄
form添加一个分支,照抄
应用程序路径,%1表示参数
注:
1) 路径使用双杠“\\”
2) 如果字符串中有双引号(”),那么需要加转义字符“\”
3) 将文件名称改为form.reg,双击文件执行,将这些项写入到注册表
检验是否注册成功
开始-运行 输入form:://test/,如果可以运行该程序,表示注册成功了;或者在浏览器的地址栏直接输入:form:://test/,可以运行则表示注册成功。
3.2.2.1 启动本地WPS
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\wps]
@="wps"
"URL Protocol"="C:\\Users\\Administrator\\AppData\\Local\\Kingsoft\\WPS Office\\9.1.0.4468\\office6\\wps.exe"
[HKEY_CLASSES_ROOT\wps\DefaultIcon]
@="C:\\Users\\Administrator\\AppData\\Local\\Kingsoft\\WPS Office\\9.1.0.4468\\office6\\wps.exe,1"
[HKEY_CLASSES_ROOT\wps\shell]
@="open"
[HKEY_CLASSES_ROOT\wps\shell\open]
@="open"
[HKEY_CLASSES_ROOT\wps\shell\open\command]
@="\"C:\\Users\\Administrator\\AppData\\Local\\Kingsoft\\WPS Office\\9.1.0.4468\\office6\\wps.exe\" \"%1\""
1) 将文件名改为wps.reg,双击执行该文件,注册上述各项。
2) 在程序-开始/运行/各种浏览器中输入wps:://test/(wps::/test/、wps:/test/、wps: /test/、wps: )即可以启动本地安装的WPS软件。
3.2.2.2 启动本地Word
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\word]
@="word"
"URL Protocol"="C:\\Program Files (x86)\\Microsoft Office\\Office14\\WINWORD.EXE"
[HKEY_CLASSES_ROOT\word\DefaultIcon]
@="C:\\Program Files (x86)\\Microsoft Office\\Office14\\WINWORD.EXE,1"
[HKEY_CLASSES_ROOT\word\shell]
@="open"
[HKEY_CLASSES_ROOT\word\shell\open]
@="open"
[HKEY_CLASSES_ROOT\word\shell\open\command]
@="\"C:\\Program Files (x86)\\Microsoft Office\\Office14\\WINWORD.EXE\" \"%1\""
1) 将文件名改为wps.reg,双击执行该文件,注册上述各项。
2) 在程序-开始/运行/各种浏览器中输入word:://test /(word::/test/、word:/test/、word: /test/、word: )即可以启动本地安装的word软件。
3) 在程序-开始/运行/各种浏览器中输入word:://id: /(word::/ id: /、word:/ id: /、word: / id: /、word: /id: )即可以启动本地安装的word软件。
3.2.2.3 各版本Word的注册表查询
http://support.microsoft.com/kb/822005/zh-cn
Word 2013 HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Word
Word 2010
HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Word
Word 2007
HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Word
Word 2003
HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Word
Word 2002
HKEY_CURRENT_USER\Software\Microsoft\Office\10.0\Word
Word 2000
HKEY_CURRENT_USER\Software\Microsoft\Office\9.0\Word