[转]LibreOffice-SDK 开发实战:嵌入MFC-View 和 C# Winform

简介: 转自:http://www.aqcoder.com/blog/detail/id/1579bb39-9bcd-4c0f-9b02-67a851148196/ 前面片文章中我简要介绍了下 LibreOffice SDK 的环境配置,以及 cpp 中一个例子的编译。

转自:http://www.aqcoder.com/blog/detail/id/1579bb39-9bcd-4c0f-9b02-67a851148196/

前面片文章中我简要介绍了下 LibreOffice SDK 的环境配置,以及 cpp 中一个例子的编译。 接下来我们来看一下如何将 LibreOffice 嵌入到 MFC 的 View 中和 C# 的 Winform 中。先上两张效果图: MFC View:这里写图片描述

C# Winform:这里写图片描述

MFC View

这里我主要讲解 LibreOffice 的相关部分,MFC 相关的部分就要带过,特别注意环境设置(ps: 玩MFC 的童鞋都不用多说,不要闲我啰嗦 ^_^) 1.建立一个当文档程序

2.设置头文件包含目录

C:\LibreOffice4\sdk\include
C:\LibreOffice4\sdk\includecpp
AI 代码解读

注意第二个目录是编译 cpp 例子得到的,详见http://blog.csdn.net/my___dream/article/details/45176921

3.设置库目录 C:\LibreOffice4\sdk\lib

4.添加环境变量 PATH: C:\LibreOffice4\URE\bin

5.show you the code: 包含头文件以及命名空间

#include "sal/config.h"
#include <sal/main.h> #include <rtl/ustring.hxx> #include <osl/diagnose.h> #include <cppuhelper/bootstrap.hxx> #include <com/sun/star/bridge/XUnoUrlResolver.hpp> #include <com/sun/star/registry/XSimpleRegistry.hpp> #include <com/sun/star/lang/XMultiComponentFactory.hpp> #include <com/sun/star/frame/XDesktop.hpp> #include <com/sun/star/uno/Reference.h> #include <com/sun/star/lang/XComponent.hpp> #include <com/sun/star/awt/XSystemChildFactory.hpp> #include <com/sun/star/util/URL.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/container/XNameAccess.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/frame/XComponentLoader.hpp> #include <com/sun/star/frame/XTitle.hpp> #include <com/sun/star/util/URL.hpp> #include <com/sun/star/util/XCloseable.hpp> #include <com/sun/star/util/XCloseListener.hpp> #include <com/sun/star/util/CloseVetoException.hpp> #include <com/sun/star/uno/RuntimeException.hpp> #include <osl/file.hxx> #include <osl/process.h> #include <rtl/ustrbuf.hxx> #include <com/sun/star/awt/XSystemChildFactory.hpp> #include <com/sun/star/awt/XDialog2.hpp> #include <com/sun/star/awt/XControlModel.hpp> #include <com/sun/star/lang/SystemDependent.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp> #include <com/sun/star/util/XURLTransformer.hpp> #include <list> using namespace cppu; using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::beans; using namespace com::sun::star::frame; using ::rtl::OUString; using ::rtl::OUStringToOString; using namespace com::sun::star; using namespace container; using namespace osl; using namespace rtl; using namespace util; using namespace awt;
AI 代码解读

在 View 中重写 OnInitialUpdate 函数,键入如下代码:

void CSDITestView::OnInitialUpdate() { CView::OnInitialUpdate(); CString strFileName = GetDocument()->GetPathName(); if (strFileName.IsEmpty()) return; using com::sun::star::lang::SystemDependent::SYSTEM_WIN32; // init XComponentContext & XMultiComponentFactory & XMultiServiceFactory Reference< XComponentContext > xContext(::cppu::bootstrap()); Reference< XMultiComponentFactory > xMultiComponetFactory = xContext->getServiceManager(); Reference<XMultiServiceFactory> xMultiServiceFactory(xMultiComponetFactory, UNO_QUERY); // create XComponentLoader Reference< XComponentLoader > xComponentLoader = Reference<XComponentLoader>( xMultiComponetFactory->createInstanceWithContext(OUString("com.sun.star.frame.Desktop"), xContext), UNO_QUERY); // create a XWindow & XFrame Adn the XWindow contain the XFrame Reference<XSystemChildFactory> xSystemChildFactory = Reference<XSystemChildFactory>( xMultiComponetFactory->createInstanceWithContext(OUString("com.sun.star.awt.Toolkit"), xContext), UNO_QUERY); Reference<XWindowPeer> xPeer = Reference<XWindowPeer>(xSystemChildFactory->createSystemChild( Any(reinterpret_cast<long>(m_hWnd)), Sequence<sal_Int8>(4), SYSTEM_WIN32), UNO_QUERY); if (xPeer.is()) { Reference<XWindow> xFrameContainerWindow = Reference<XWindow>(xPeer, UNO_QUERY); Reference<XFrame> xFrame = Reference<XFrame>(xMultiComponetFactory ->createInstanceWithContext(OUString("com.sun.star.frame.Frame"), xContext), UNO_QUERY); if (xFrameContainerWindow.is() && xFrame.is()) { xFrame->initialize(xFrameContainerWindow); Reference<XFrames> xChildContainer = Reference<XFramesSupplier>(xComponentLoader,UNO_QUERY)->getFrames(); xChildContainer->append(xFrame); xFrame->setName(OUString("myframe")); // to identify frame } Reference<XSystemDependentWindowPeer> xPeer(xFrameContainerWindow, UNO_QUERY); if(xPeer.is()) { xFrameContainerWindow->setVisible(true); long lh = 0; xPeer->getWindowHandle(Sequence<sal_Int8>(4), SYSTEM_WIN32) >>= lh; m_hPlatformContainerWindow = reinterpret_cast<HWND>(lh); } } // load component Sequence<PropertyValue> properties; properties.realloc(2); properties[0] = PropertyValue(OUString("ReadOnly"), 0, Any(false), PropertyState_DIRECT_VALUE); properties[1].Name = OUString(OUString("passwd")); properties[1].Value = Any(OUString("abc")); URL url; OUString ousUrl, ousWorkingDir, ousPathUrl; osl_getProcessWorkingDir(&ousWorkingDir.pData); osl::FileBase::getFileURLFromSystemPath(strFileName.GetBuffer(), ousPathUrl); osl::FileBase::getAbsoluteFileURL(ousWorkingDir, ousPathUrl, ousUrl); url.Complete = OUString(ousUrl); Reference<XURLTransformer> urltf = Reference<XURLTransformer>(xMultiComponetFactory ->createInstanceWithContext(OUString("com.sun.star.util.URLTransformer"), xContext), UNO_QUERY); urltf->parseStrict(url); Reference<XComponent> xComponent = xComponentLoader->loadComponentFromURL(url.Complete, OUString("myframe"),4, properties);// move windowCWnd* pWnd =CWnd::FromHandle(m_hPlatformContainerWindow);if(pWnd){CRect rect;CWnd::FromHandle(m_hWnd)->GetClientRect(&rect); pWnd->MoveWindow(rect, TRUE);}// save to close m_xComponet = xComponent; m_xDesktop =Reference<XDesktop>(xComponentLoader, UNO_QUERY);}
AI 代码解读

代码解释(按注释行解释): 1. 首先是判断有没打开文档,没有就返回,这个不需要解释了,一定要判断哦。。。

  1. // init XComponentContext & XMultiComponentFactory & XMultiServiceFactory 初始化组件上下文、组件工厂(顺带提一下,LibreOffice 需要 UNO 编程的知识, 没接触过 UNO 的童鞋看看这个 中文:https://wiki.openoffice.org/wiki/Zh/Documentation/DevGuide/OpenOffice.org_Developers_Guide) 英文:https://wiki.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide

  2. // create XComponentLoader 创建 com.sun.star.frame.Desktop 对象得到 XComponentLoader 接口

  3. // create a XWindow & XFrame Adn the XWindow contain the XFrame 这里英文注释写的不是很准确,鄙人英文不是很好就这么写了 T_T。这部分是为了得到 XWindows 接口用于承载 XFrame 后面加载的组件都在 XFrame 容器当中。 首先,创建一个 com.sun.star.awt.Toolkit 对象得到 XSystemChildFactory,调用 XSystemChildFactory.createSystemChild() 方法得到 XWindowPeer 接口,注意这个方法传入了父窗口句柄,也就是 View 的句柄。 接着,创建一个 com.sun.star.frame.Frame 对象得到 XFrame 接口,并进行初始化工作,然后得到 XFrames 接口并调用 XFrames.getFrames() 方法加入到 Frame 集合当中。 最后,设置 com.sun.star.frame.Frame 对象的名称,这个很关键,以为后面要根据名称加载组件。 最最后,得到 XSystemDependentWindowPeer 接口,调用 XSystemDependentWindowPeer.getWindowHandle() 方法得到容器的窗口句柄。

  4. // load component 加载组件,这里特别要注意 URL 对象,因为从 GetPathName() 方法得到文件路径是 Window 的路径格式(也就是反斜杠),我们要把他转化为 Unix 系统下的路径格式(也就是正斜杠,到底谁反人类了 T_T) 然后调用 XComponentLoader 接口的 XComponentLoader.loadComponentFromURL() 方法加载组件。注意第二个参数一定要和步骤 4 中设置的 com.sun.star.frame.Frame 对象的名字相同,你得告诉人家加载到那个容器里嘛~~

  5. // move window 这段代码也没什么好解释的了,就是窗口的定位。

  6. 最后几个是成员变量是为了关闭文档,注意:如果不关闭文档后面再打开程序,打开同一个文档是会挂掉,因为 UNO 对象是跨进访问的,你的程序关了 soffice.exe 和 soffice.bin 两个进程都还在,而你打开的文档信息在进程中,所以挂掉。。。 这里只是做个示例和试验,所以代码没有考虑结构和严谨性,容易出 BUG ,请不要吐槽 ->_->

所以,在析构函数中加入如下代码:

CSDITestView::~CSDITestView() { Reference< XCloseable > xClaseable = Reference< XCloseable >(m_xComponet, UNO_QUERY); xClaseable->close(false); m_xDesktop.clear(); }
AI 代码解读

以及成员变量

HWND m_hPlatformContainerWindow;
com::sun::star::uno::Reference< com::sun::star::frame::XDesktop > m_xDesktop; com::sun::star::uno::Reference< com::sun::star::lang::XComponent > m_xCompone
AI 代码解读

OK, MFC 的示例就酱完了,刚开始看 UNO 的代码可能有点累,都是模板和接口,建议先收悉一下 UNO 编程的相关知识,上面给的中文连接还有没翻译完,建议看英文的。。。英文不好的程序员不是好程序员 ->_->

C# Winform

Winform 的代码步骤是一样的: 初始化 --> 创建容器 --> 加载组件 --> 移动窗口。 1. 创建工程 2. 添加引用: \LibreOffice4\sdk\cli\ 目录下有 cli_basetypes.dll、cli_cppuhelper.dll、cli_oootypes.dll、cli_ure.dll、cli_uretypes.dll 5 个程序集,都引用上 3. 上代码:

[DllImport("user32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] public static extern int MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool bRePaint); public Form1() { InitializeComponent(); m_xContext = uno.util.Bootstrap.bootstrap(); mxMSFactory = (XMultiServiceFactory)m_xContext.getServiceManager(); XComponentLoader aLoader = (XComponentLoader) mxMSFactory.createInstance("com.sun.star.frame.Desktop"); XSystemChildFactory xSystemChildFactory = (XSystemChildFactory)mxMSFactory.createInstance("com.sun.star.awt.Toolkit"); XWindowPeer xWindowPeer = xSystemChildFactory.createSystemChild(new Any(this.Handle.ToInt32()), new byte[4], 1); XWindow xWindow = (XWindow)xWindowPeer; XFrame xFrame = (XFrame)mxMSFactory.createInstance("com.sun.star.frame.Frame"); xFrame.initialize(xWindow); XFramesSupplier xFrameSupplier = (XFramesSupplier)aLoader; xFrameSupplier.getFrames().append(xFrame); xFrame.setName("myframe"); XSystemDependentWindowPeer xSDWindowPeer = (XSystemDependentWindowPeer)xWindow; xWindow.setVisible(true); object hHandle = xSDWindowPeer.getWindowHandle(new byte[4], 1).Value; XComponent xComponent = aLoader.loadComponentFromURL("file:///C:/test.odt", "myframe", 4, new unoidl.com.sun.star.beans.PropertyValue[0]); MoveWindow(new IntPtr((int)hHandle), 0, 0, this.Width, this.Height, true); }
AI 代码解读

这个实例在主窗口初始化的时候就加载了,所以加载的文档是写死的,注意是正斜杠哦。。。 代码基本和 C++ 的一样就不解释了,提一下就是 MoveWindows() 用到了 Win32API 不知道 C# 如何调用 Win32API 的童鞋自己 Google 吧 ^_^ 好了,我也刚开始学 LO,这种方法还没在实际项目中验证,如有错漏之处还请大神请教,共勉。。。

目录
打赏
0
0
0
0
1
分享
相关文章
HarmonyOS NEXT~鸿蒙开发能力:HarmonyOS SDK AI 全解析
本文深入解析HarmonyOS SDK中的AI功能集,涵盖分布式AI引擎、核心组件(NLP、计算机视觉等)及智能决策能力。通过代码示例与开发实践指南,帮助开发者掌握环境配置、性能调优及多场景应用(智能家居、移动办公等)。同时探讨性能优化策略与未来演进方向,助力构建高效分布式智能应用。
113 9
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
290 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
C#实现上位机开发,串口通信,读写串口数据并处理16进制数据
C#实现上位机开发,串口通信,读写串口数据并处理16进制数据。在自动化、物联网以及工业控制行业中,上位机开发是一项重要的技能。本教程主要介绍使用C#进行上位机开发,重点在于串口通信和数据处理。
819 82
揭秘 Microsoft.Docker.SDK:让容器开发更轻松的强大工具揭秘
随着云计算和容器技术的快速发展,`Docker` 已经成为容器化技术的事实标准。`Microsoft` 作为 `Docker` 的主要支持者和参与者,推出了 `Microsoft.Docker.SDK`,旨在帮助开发者更轻松地进行容器开发。本文将深入揭秘 Microsoft.Docker.SDK 的功能、使用方法以及它在容器开发中的应用。
131 12
【04】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-正确安装鸿蒙SDK-结构目录介绍-路由介绍-帧动画(ohos.animator)书写介绍-能够正常使用依赖库等-ArkUI基础组件介绍-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
【04】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-正确安装鸿蒙SDK-结构目录介绍-路由介绍-帧动画(ohos.animator)书写介绍-能够正常使用依赖库等-ArkUI基础组件介绍-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
293 5
【04】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-正确安装鸿蒙SDK-结构目录介绍-路由介绍-帧动画(ohos.animator)书写介绍-能够正常使用依赖库等-ArkUI基础组件介绍-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
【02】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-准备工具安装-编译器DevEco Studio安装-arkts编程语言认识-编译器devco-鸿蒙SDK安装-模拟器环境调试-hyper虚拟化开启-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
【02】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-准备工具安装-编译器DevEco Studio安装-arkts编程语言认识-编译器devco-鸿蒙SDK安装-模拟器环境调试-hyper虚拟化开启-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
229 2
【02】鸿蒙实战应用开发-华为鸿蒙纯血操作系统Harmony OS NEXT-项目开发实战-准备工具安装-编译器DevEco Studio安装-arkts编程语言认识-编译器devco-鸿蒙SDK安装-模拟器环境调试-hyper虚拟化开启-全过程实战项目分享-从零开发到上线-优雅草卓伊凡
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
303 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【01】完整开发即构美颜sdk的uni官方uts插件—让所有开发者可以直接使用即构美颜sdk的能力-优雅草卓伊凡
【01】完整开发即构美颜sdk的uni官方uts插件—让所有开发者可以直接使用即构美颜sdk的能力-优雅草卓伊凡
180 23
【01】完整开发即构美颜sdk的uni官方uts插件—让所有开发者可以直接使用即构美颜sdk的能力-优雅草卓伊凡
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
127 0
一个包含了 50+ C#/.NET编程技巧实战练习教程
一个包含了 50+ C#/.NET编程技巧实战练习教程
215 18

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问