1. 问题描述
最近在研究“如何实现在桌面程序中,实现内嵌office的功能,能够对办公文件(Excel/ Word/ PPT/ Visio)实现常见的查看、编辑、保存等功能”的问题。在思考实现的技术思路时,接触到了关联的ActiveX控件:dsoframer.ocx。于是,看了许多文章,趟过了一些坑,此处总结了一个简单的demo。希望能给需要的人以参考。
开发背景: vs2017+.net framework 4.6 + C#
关联控件: dsoframer.ocx(下载链接)(https://download.csdn.net/download/qq_34769196/13239121)
本次Demo源代码下载: DsoFramerOffice.rar(https://download.csdn.net/download/qq_34769196/13239154)
2. 效果展示
实现功能:
注册dsoframer.ocx控件。
取消注册dsoframer.ocx控件。
加载 ppt / excel / word 等office常用文件类型。
使用同一个AxDSOFramer.AxFramerControl类对象,在不同文件类型的文件间进行切换。
图片如下:
3. 步骤描述
注意: 需要本地安装了Office,dsoframer.ocx控件实质上是控制本地安装好的office来编辑文件,是一种在线编辑的形态。
不仅仅可以应用在桌面程序上,web网页上调用ActiveX控件也能达到同样的效果。
如果由需要,可以自行研究。
具体步骤:(总共就3个步骤)
注册“dsoframer.ocx”。
打开vs2017,项目中添加Com组件。
查看API文件,编写代码调用相关接口,实现所需功能。
尤其注意:
在vs中添加COM组件时,如果没有注册dsoframer.ocx,无法正常将其添加到工具箱,从而无法正常使用。
添加过程如下:
1.在工具箱中,点击右键菜单,弹出项中点击“选择项”。
2.在弹出窗口中,选择“Com组件” 选择框,勾选“DSO Framer Control Object”,点击确定。
注意:一定要注册dsoframer.ocx后,才能在添加com组件时,找到"DSO Framer Control Object"。
3.然后在工具箱中,成功添加了“DSO Framer Control Object”控件,可像按钮一样拖拽使用。
4. 关键步骤代码
注册dsoframer.ocx的部分代码:
/// <summary>
/// 注册dsoframer.ocx
/// </summary>
/// <returns>返回-1:注册失败;返回1:注册成功;返回2:已注册过,不用重复注册</returns>
public static int RegisterMain()
{
// 存放ocx文件的目录: bin\Debug\ocx\dsoframer.ocx
string fileFullPath = string.Format("{0}\\ocx\\dsoframer.ocx", System.Environment.CurrentDirectory);
string systemDrive = System.Environment.GetEnvironmentVariable("systemdrive");//获取系统所在的盘符
// 确保dsoframer.ocx存在
if (!File.Exists(fileFullPath) || String.IsNullOrEmpty(systemDrive))
return -1; // dsoframer.ocx不存在,注册失败
bool isRegisted = IsRegistered("00460182-9E5E-11D5-B7C8-B8269041DD57");
if (isRegisted)
return 2; // 已注册过,注册成功
string windowsPath = string.Empty;
if (GetOSBitCount() == "64")
windowsPath = string.Format("{0}\\Windows\\SysWOW64", systemDrive);
else
windowsPath = string.Format("{0}\\Windows\\System32", systemDrive);
if (!Directory.Exists(windowsPath))
return -1;//目标目录不存在,注册失败
// 复制dsoframer.ocx文件到C:\\Windows\\SysWOW64 或 C:\\Windows\\System32
File.Copy(fileFullPath, string.Format("{0}\\dsoframer.ocx", windowsPath), true);
bool result = Registe(string.Format("{0}\\dsoframer.ocx", windowsPath)); //开始注册
if (result)
{
return -1; //注册失败
}
return 1;//注册成功
}
//注册dsoframer.ocx
private static bool Registe(string fileFullName)
{
bool result = false;
System.Diagnostics.Process p = System.Diagnostics.Process.Start("regsvr32", fileFullName + " /s");//注册完毕不显示是否成功的提示
//System.Diagnostics.Process p = System.Diagnostics.Process.Start("regsvr32", fileFullName);//注册完毕显示是否成功的提示
if (p != null && p.HasExited)
{
Int32 exitCode = p.ExitCode;
if (exitCode == 0)
result = true;
}
return result;//成功时,返回false
}
取消注册dsoframer.ocx的部分代码:
//取消注册dsoframer.ocx
private static bool UnRegiste(string fileFullName)
{
bool result = false;
System.Diagnostics.Process p = System.Diagnostics.Process.Start("regsvr32", fileFullName + " /u");//取消注册
if (p != null && p.HasExited)
{
Int32 exitCode = p.ExitCode;
if (exitCode == 0)
result = true;
}
return result;//成功时,返回false
}
判断dsoframer.ocx是否已经注册的代码:
调用过程bool isRegisted = IsRegistered("00460182-9E5E-11D5-B7C8-B8269041DD57");
//判断控件是否已经注册
private static bool IsRegistered(String CLSID)
{
if (String.IsNullOrEmpty(CLSID))
return false;
String key = String.Format(@"CLSID\{{{0}}}", CLSID);
RegistryKey regKey = Registry.ClassesRoot.OpenSubKey(key);
if (regKey != null)
return true;
else
return false;
}
5. 举两个例子
至于如何创建AxDSOFramer.AxFramerControl对象,并调用属性方法实现具体功能,需要再研究具体的API文档。(此处不再详述)
1.隐藏AxDSOFramer.AxFramerControl对象的“标题栏、菜单栏、工具栏”,对应隐藏office的“标题栏、菜单栏、工具栏”。
private AxDSOFramer.AxFramerControl m_axFramerControl;
... ...
m_axFramerControl.Titlebar = false;//是否显示excel标题栏
m_axFramerControl.Menubar = false;//是否显示excel的菜单栏
m_axFramerControl.Toolbars = false;//是否显示excel的工具栏
2.初始化office控件,加载 Excel/ Word/ PPT/ Visio
/// <summary>
/// 初始化office控件,加载Excel/Word/PPT
/// </summary>
/// <param name="_sFilePath"></param>
private void InitOfficeControl(string _sFilePath)
{
try
{
if (m_axFramerControl == null)
{
throw new ApplicationException("请先初始化office控件对象!");
}
//this.m_axFramerControl.SetMenuDisplay(48);
//这个方法很特别,一个组合菜单控制方法,我还没有找到参数的规律,有兴趣的朋友可以研究一下
string sExt = System.IO.Path.GetExtension(_sFilePath).Replace(".", "");
//this.m_axFramerControl.CreateNew(this.LoadOpenFileType(sExt));//创建新的文件
this.m_axFramerControl.Open(_sFilePath, false, this.LoadOpenFileType(sExt), "", "");//打开文件
//隐藏标题
this.m_axFramerControl.Titlebar = false;
}
catch (Exception ex)
{
throw ex;
}
}
//下面这个方法是dso打开文件时需要的一个参数,代表office文件类型
/// <summary>
/// 根据后缀名得到打开方式
/// </summary>
/// <param name="_sExten"></param>
/// <returns></returns>
private string LoadOpenFileType(string _sExten)
{
try
{
string sOpenType = "";
switch (_sExten.ToLower())
{
case "xls":
sOpenType = "Excel.Sheet";
break;
case "xlsx":
sOpenType = "Excel.Sheet";
break;
case "doc":
sOpenType = "Word.Document";
break;
case "docx":
sOpenType = "Word.Document";
break;
case "ppt":
sOpenType = "PowerPoint.Show";
break;
case "pptx":
sOpenType = "PowerPoint.Show";
break;
case "vsd":
sOpenType = "Visio.Drawing";
break;
default:
sOpenType = "Word.Document";
break;
}
return sOpenType;
}
catch (Exception ex)
{
throw ex;
}
}
6. 总结
此次demo实现功能点不多,但可以帮助入门借助dsoframer.ocx控件实现在线编辑office功能的研究,能基本完成在winform桌面程序中,内嵌office办公程序的效果。
具体代码下载入口: DsoFramerOffice.rar(https://download.csdn.net/download/qq_34769196/13239154)
————————————————
版权声明:本文为CSDN博主「XY的技术笔记」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_34769196/article/details/110511741