zoukankan      html  css  js  c++  java
  • C#:使用dsoframer.ocx控件实现内嵌office效果(详解)

    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

  • 相关阅读:
    unity, sceneview 中拾取球体gizmos
    C#, float.ToString()的一个坑
    unity, SerializedObject.FindProperty不要写在Editor的OnEnable里,要写在OnInspectorGUI里
    unity, 查看.anim中的动画曲线(和帧)
    unity, Graphics.Blit (null, null, mat,0);
    unity, GL.TexCoord or GL.Color must put before GL.Vertex!!!
    (MyEclipse) MyEclipse完美破解方法(图)
    博客园kubrick主题
    sina微博加入到博客园
    MyEclipse 2014 破解图文详细教程
  • 原文地址:https://www.cnblogs.com/javalinux/p/14592053.html
Copyright © 2011-2022 走看看