隐藏

C#:使用dsoframer.ocx控件实现内嵌office效果(详解

发布:2021/4/2 17:05:25作者:管理员 来源:本站 浏览次数:1052

1. 问题描述

最近在研究“如何实现在桌面程序中,实现内嵌office的功能,能够对办公文件(Excel/ Word/ PPT/ Visio)实现常见的查看、编辑、保存等功能”的问题。在思考实现的技术思路时,接触到了关联的ActiveX控件:dsoframer.ocx。于是,看了许多文章,趟过了一些坑,此处总结了一个简单的demo。希望能给需要的人以参考。

开发背景: vs2017+.net framework 4.6 + C#
关联控件: dsoframer.ocx(下载链接)
本次Demo源代码下载: DsoFramerOffice.rar
2. 效果展示

实现功能:

    注册dsoframer.ocx控件。
    取消注册dsoframer.ocx控件。
    加载 ppt / excel / word 等office常用文件类型。
    使用同一个AxDSOFramer.AxFramerControl类对象,在不同文件类型的文件间进行切换。
    图片如下:
    1-功能点
    2-打开ppt,查看编辑
    2-打开Excel,查看编辑
    3-打开word,查看编辑

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的工具栏

    1
    2
    3
    4
    5

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