ocean

嘿嘿,我的地盘由我来
随笔 - 95, 文章 - 0, 评论 - 1030, 引用 - 19
数据加载中……

2006年6月22日

在MOSS中给增强型RTF字段增加按钮

很多人会抱怨MOSS默认的讨论区比较弱,比起大部分BBS来说,确实少了很多功能。实际上对于MOSS的讨论区来说,已经是一个树型结构了, 我们只要稍加改善,就能够让讨论区更完善一些。

昨天中午和同事讨论起这个话题,认为讨论区只要要改进4个地方:

  • 1:贴图,也就是能否在编辑帖子的时候,同时上传图片,并且贴到正文里面。这个我在前几天的blog里面已经讲了,这个功能已经实现了, 大家可以参考:在MOSS中实现自动上传图片
  • 2:有头像,这个功能MOSS本身就有。大家看我的讨论区,我的帖子就有我的头像,当然现在还不允许大家自己设置头像,我想以后我会实现这个功能。
  • 3:有签名,能够在发帖的时候增加签名档,这个是需要改进的地方。也是我考虑下一步去实现的。
  • 4:能够贴表情,也就是类似QQ,MSN一样,能有贴表情的按钮。

    今天我们就讲讲如何实现第4个,首先看贴图:

    这张图截自我的网站的讨论区, http://www.oceanstudio.net/Lists/SharePoint3/AllItems.aspx,大家可以自己去看实际效果,当然为了防止恶意灌水,本讨论区需要注册。

    我的实现方式很简单,讨论区默认的正文输入框是一个增强型的RTF,我做的就是在上面加了一个按钮。

    上篇Blog我们曾经讲过,如果要替换掉整个编辑器,我只要重写RTE_ConvertTextAreaToRichEdit()这个函数就可以了。但是有时我只希望增加一两个按钮,如何做呢?

    FullHtml,也就是增强型RTF的工具栏的按钮,都在RTE_FullHtmlToolBarDefinitionFactory()这个函数里面定义这,这里面有一个toolbar变量,我们只要在合适 的位置,增加我们的按钮就可以,我把它加入到插入图片的按钮后面,向toolbar加入按钮的时候,首先要生成一个新按钮,按钮有三种:

  • 1:ExecCmdButton,这属于命令按钮,就是点中按钮后没有多余界面出来,比如copy,paste,cut等
  • 2: JScriptButton,这些都会弹出对话框,比如“插入图片”,“插入链接”这些按钮等
  • 3:SpecialButton,这些就是类似我做的这个插入表情的按钮,它会有一个下拉单,让你选择,另外还有就是选择“前景色”,“背景色”的这些按钮。就是类似下图这样的。
    //////////////////////自定义按钮///////////////////////////
    //增加表情按钮
    toolBar.push(
    new C_RTE_TB_SpecialButton(
    g_strRTEInsertEmoticonMnemonic,
    RTE_GenerateInsertEmoticonToolBarButtonHtml,
    true,
    new C_RTE_TB_SetEnabledAlways()));
    ///////////////////////////////////////////////////////////
    

    创建好按钮后,就要生成这个按钮的主体html,这个我们定义一个新函数:RTE_GenerateInsertEmoticonToolBarButtonHtml。生成完按钮主体后, 就要生成那个表情选择器,这个选择器我也创建了一个新函数RTE_DD_OpenInsertEmoticonSelector。选择器实际上有现成的一些函数可以调用。 这个函数就是:RTE_DD_GenerateMenuItemHtml,每个MenuItem就是一个表情按钮。通过这些已经预定好的函数生成选择器后,你会发现你不用去设定位置, 它会自动的在你的按钮的下方出现。

    当你的按钮出来之后,你需要做的就是点击按钮返回的动作,这个动作会调用RTE_ExecuteCommandOnSelection这个函数,在这个函数里面,执行了 docEditor.execCommand()函数,执行插入图像的动作,每个表情就是一个图片。

    if (strCommand == "InsertEmoticon") {
    docEditor.execCommand("InsertImage", fUserInterface,
    RTE_GetServerRelativeImageUrl("Emoticon/" + strValue));
    }
    

    这里提醒大家注意一下的就是,我们的toolbar是在一个Iframe里面的,所以点击了表情按钮之后,实际上的函数调用发生在Iframe内部,如果你想让它调用 父框架的函数,那么请使用parent或者top。这个按钮我一共花了3个小时,但是这个小问题就花了我1个小时的时间,之后才恍然大悟想起来表情按钮都是在Iframe中。

    当然实际上做一个按钮不需要那么长时间,除了刚刚的那个Iframe问题之外,我还花了一些时间来收集表情图片,并且一个一个的写到数组里面,这个也属于个体力活。

    当我们给这个工具栏加上按钮后,那么每个字段,只要采用了增强RTF型,就会有这个插入表情的功能。

    本篇blog首发:oceanstudio-blog

    欢迎访问海洋工作室

  • posted @ 2008-08-01 22:29 ocean 阅读(1132) | 评论 (5)编辑

    在MOSS中实现自动上传图片

    我经常会被问到这么两个问题:

  • 在MOSS中,我们是否能换掉那个多行文本输入框默认的html编辑器?
  • 在多行文本输入框的html编辑工具栏中,插入图片那个按钮是否能让我将本地的图片上传到服务器上?

    我也不太清楚为什么,这两个问题我确实被问了无数遍,我每次都会回答:可以,没有问题。然后天马行空的说 一些我的想法,结果很多人还是没有搞清楚。恰好现在我也希望我的讨论区有图片上传的功能,昨天晚上就开始真正 的去实现这么一个文件上传。

    我在本文中,就具体的谈一谈,我们应该如何去实现它,并且阐述一下MOSS自身的一些机理。

    我做了一个小例子,大家可以先看一下,当然大家也可以从 http://www.oceanstudio.net/Lists/SharePoint3/AllItems.aspx这里直接看到我做的例子,为了防止机器人在我的讨论区灌水,本讨论区是需要注册登录才能发帖子的。我是贴图大王,大家先看贴图:

    首先,当我们点击“插入图片”按钮后,弹出了对话框,为了实现文件上传功能,我直接替换掉了这个对话框。

    这个对话框有两个功能,第一个就是原先的功能,你可以自己填写url,第二个功能就是你可以选择上载,然后通过uploadfile 控件,选择一个文件。在这里,我选择了我桌面上的一个图片文件,这个文件也是我的网站海洋工作室的logo。

    点击上传按钮,这个时候会显示上载成功。然后我们就可以点击确定按钮了。

    点击了确定按钮之后,我们可以看到,这个logo图片已经显示在多行文本区了。

    这是我们点击确定后,新建的一个帖子,图片能够正确的在web页面上显示出来。现在大家发帖子,就可以将自己的错误 信息截图直接贴到正文里,而不需要像以前那样添加到附件里面那么麻烦了。

    我们看一下这个图片的属性,这个图片显示的路径是:http://www.oceanstudio.net/Lists/SharePoint3/_ocean_upload/12861814871598000-logo.jpg, logo.jpg是这个文件的原文件名,为了防止文件名冲突,我直接在文件名前面加了一个时间戳。

    我终于过完了贴图瘾,下面我们就谈谈我们如何来做,大家觉得很奇怪,既然我从昨天晚上才开始想起来做,几个小时就做完了, 连blog都写出来了,这么简单的东西,SharePoint产品组干吗不直接加上这个功能?毕竟这是一个很实用的功能。

    我认为这个主要在于几点:

  • 最严重的问题,上传的图片存放在什么位置?这实际上是个很严重的问题,因为大家会发现我做的例子,当你的项目还没有 添加的时候,图片就已经上传到服务器上了。我是自己定了一个位置,位于列表的_ocean_upload目录,这个目录是我自己建立的。 但是很明显开发组不能这么干,因为如果我关闭了浏览器,那么这个上传上去的图片就永远存在与服务器上了,那么作为一个产品 来说,这是不能忍受的。而对于我们一个具体的解决方案,可以具体情况具体分析,我可以存放在任何位置,只要我觉得合适就可以。
  • 权限问题,MOSS的每个项目都是可以有单独权限的,而很明显项目里面的内容,如果有图片的话,那么这些图片的权限 也应该跟随项目的权限,而像我这样直接放在一个统一的目录里面,就等于凡是能阅读这个列表库的,就都能看到这些图片,图片的权限就无法 和具体的每一个栏目挂钩了。
  • 有人会说,那为什么不像附件一样呢?我们说附件,虽然你选择了附加文件,但是这些文件是当你点击确定,添加整个项目的时候 才会上传的,而不是事先传上去的。如果我们不事先上传图片,那么图片的位置就只能用一个统一的占位符来表示,而无法在编辑的时候直接预览, 我想这也是这个方案的一个问题。

    开发组可能考虑了还要多的东西,最终没有将这个功能加入进来,SPS2003没有,MOSS2007也同样没有。

    但是,我们却可以进行扩展,MOSS是个很灵活的架构,在MOSS的平台上进行开发,你会觉得非常的优雅,因为MOSS确实是一个非常优秀的开发平台。

    首先我们从原理开始讲起,第一个问题,我们能否替换掉那个Html编辑器?这个答案是没有问题,方案有二

  • 1:我们直接通过MOSS2007的自定义字段类型的特性,直接开发一个新的字段类型,这时UI是我们自己控制的,我们可以直接嵌入一个我们想要的HTML编辑器,这也是 最省时省力的方案。然后在需要用到的地方,建立这个新类型的字段就可以了。
  • 2:有人较真,说我就想改掉它自带的,而不是新建一个类型,那实际上就复杂了,我们就需要研究一下MOSS是如何做的了。

    我们知道,在MOSS里面,多行文本有三种形式,简单型,RTF型和增强RTF型。我们真正要动手的,实际上就是这个RTF型和增强RTF型。那么 在你新建或者编辑项目,含有这些类型的字段时,MOSS是如何做的呢?

    MOSS首先输出一个textarea标签,这个标签是多行文本框,然后紧随其后,它会调用一个JavaScript函数:RTE_ConvertTextAreaToRichEdit(),这个函数的定义如下:

      function RTE_ConvertTextAreaToRichEdit(
    strBaseElementID,
    fRestrictedMode,
    fAllowHyperlink,
    strDirection,
    strWebLocale,
    fSimpleTextOnly,
    fEditable,
    fUseDynamicHeightSizing,
    iMaxHeightSize,
    iMinHeightSize,
    strMode,
    urlWebRoot,
    strThemeUrl,
    strBodyClassName,
    fAllowRelativeLinks,
    strBaseUrl,
    fUseDynamicWidthSizing,
    iMaxWidthSize,
    iMinWidthSize,
    fEnforceAccessibilityMode,
    fPreserveScript,
    fHookUpEvents,
    fGenerateToolbar
    )
    

    其中第11个参数是strMode,这个参数为"FullHtml"时,就是增强的RTF类型,如果是Compatible,就是普通RTF类型。那么这个函数在哪儿呢? 它位于C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\2052下的FORM.JS ,这个路径是默认安装的路径,如果是英文版,就把2052换成1033(下同)。然后我们就可以打开FORM.JS看看这个函数是如何实现的。这个文件比较 长,差不多有6000行,好在没有进行任何混淆,版式也很规整,所以读起来并不难。通过阅读源代码,我们知道它在页面生成了一个IFrame,我们 所编辑的所有内容,都会被存到这个IFrame里面,并且使用RTE_TransferIFrameContentsToTextArea这个函数把IFrame里面的内容显示到 TextArea里面。所以实际上如果我们要替换编辑器的话,我们只要重新写这个函数就可以了,我们可以重写这个函数,输出我们自己的html编辑器, 只要最终在保存之前,我们把我们的html编辑器里面的内容存到这个TextArea里面就可以了。

    当然替换一个htmleditor实在是不划算的事情,因为自己写一个htmleditor很复杂,当然如果有现成的并且免费的html editor也不错。 不过我想大多数人,都希望修改原来的editor,比如增加个按钮什么的,这个也是可以做到的。因为在RTE_GetCompatibleToolBarDefinition 和RTE_FullHtmlToolBarDefinitionFactory这两个函数里面,定义了toolbar里面的按钮,我们只要在这里面增加新的按钮即可。

    下面就回到了第二个问题,如果我仅仅是希望添加图片的时候,让图片具有上传的功能,我该如何做呢?当点击了html编辑工具栏的“插入图片” 按钮后,调用了RTE_ModalDialog这个函数,在这个函数里面,弹出了那个对话框,这个对话框默认是/_layouts/RteDialog.aspx,因为MOSS 是不提供源代码的,所以改写RteDialog.aspx困难一点,我所采用的方法,就是重新写一个对话框。并且在这个对话框里面实现文件上传的功能。

    在写之前,我们要考虑一个问题,就是上传的图片放在什么地方?我想有下面几个地方:

  • 1:放在磁盘目录里面,并且这个磁盘目录能够在web上访问到,这种方式最简单,因为直接脱离了MOSS,我们的代码里面也不需要对MOSS进行任何操作了。 缺点就是完全脱离了MOSS,当我对我的网站进行备份时,我需要单独为磁盘上的这些图片备份。而且权限系统完全脱离了MOSS的管辖。
  • 2:放在MOSS的某个文件夹中,如果我们一个MOSS公共文件夹里面,有点就是当我备份站点时,这些图片会被一同备份。缺点是所有的图片都在一个文件夹里面, 会比较乱,而且权限无法区分清楚。
  • 3:放在各自的列表的某个文件夹里面,我的那个例子就是采用的这个方法,比如那个SharePoint讨论区,列表的名字是"SharePoint3",上传图片就会 放到对应的"SharePoint3/_ocean_upload"这么一个目录里面,第二种方法是一个网站对应一个目录,现在这种方法是一个列表对应一个目录。这个好处就是 当你删除列表时,图片也会一并被删除。权限也限制到了列表级,也就是拥有列表读权限的就能访问。缺点是权限仍然没有和某一个具体的项目挂钩。
  • 4:图片放到相应的项目所对应的目录下,我们知道如果列表允许附件,那么所有附件都会放在Attachment这个目录里面,并且在这个目录里面根据项目的id 分子目录,附件则放在对应项目的子目录里面,这样的好处就是当某个项目删除后,图片也立即删除了。但是要实现这个还是有一定问题的。主要就在与新建项目时, 还不知道新建的项目的id,这个时候先上传图片根本不知道放在什么地方,所以最终我采用了第三个方案。

    还有一个问题就是,我们的web application放在什么地方?很多文章都讲我们要放在_layouts下面,实际上,我们放到任何位置都可以,我 放的位置是/OceanFileUpload,大家从截图上就能看到。/OceanFileUpload是我在IIS下建立的虚拟应用,这个虚拟应用只要在MOSS的 站点下就可以使用MOSS的上下文。

    这个文件具体怎么上传我就不细讲了,因为在asp.net2.0里面,文件上传实在太容易了,有自带的FileUpload控件。当点击了上载按钮后,就把上传的 文件存到MOSS里面,讲文件存到MOSS里面,我们可以使用public SPFile Add(string urlOfFile, Stream stream);这个函数,其中的stream我们 可以直接从FileUpload.FileContent获得,因为这个FileContent本身就是一个Stream类型的。当然你的项目要引用Microsoft.Sharepoint.dll。

    文件上传完毕后,返回这个文件在服务器上的url就可以了。

    另外,因为网站采用Form认证后,批量上传图片的功能就无法使用了,所以我干脆自己做了一个Silverlight相册,这是基于Silverlight2 beta2的,欢迎大家去做客。点击进入我的图片

    本篇blog首发:oceanstudio-blog

    欢迎访问海洋工作室

  • posted @ 2008-07-30 00:26 ocean 阅读(1504) | 评论 (14)编辑

    在Windows Server2008中运行MOSS不能启动Excel Service的问题

         摘要: 如果你现在使用Windows Server 2008 beta3
    来运行MOSS2007,那么你可能会遇到一个我问题,就是MOSS2007中的Excel Calculation Service 无法启动,你可以用本文中的方法来启动此服务。  阅读全文

    posted @ 2007-09-09 22:40 ocean 阅读(1799) | 评论 (1)编辑

    我也谈谈执行力

         摘要: 最近在博客园里面闲诳,发现谈执行力的两篇文章,这个我比较感兴趣,我也发表了一个评论,其主要主张就是管理者,管人是非常重要的,这个要比管理者自身所掌握的技术重要。我引了《史记》中刘邦说过的一段话“夫运筹策帷帐之中,决胜于千里之外,吾不如子房;镇国家,抚百姓,给馈饷,不绝粮道,吾不如萧何;连百万之兵,战必胜,攻必取,吾不如韩信。此三人,皆人杰也,吾能用之,此吾所以取天下也。”。我们知道刘邦和项羽打仗,没有一条计谋是自己出的,没有一场战役是自己指挥的,在未得韩信之前也是屡战屡败。那刘邦为什么成功呢?这就是有人才,而且在于能够知人善人,有时你的手里有人才,但是你不能用,一样不成。刘邦后面跟着一句“项羽有一范增而不能用,此其所以为我擒也。”。后面接着有一哥们说这个太理论化了,怎么具体呢?  阅读全文

    posted @ 2007-08-06 03:46 ocean 阅读(5956) | 评论 (20)编辑

    微软新技术巡展活动

    在5月23日广州、5月25日深圳,下午将举行微软最新的技术巡展活动,涉及Silverlight、Longhorn、Dynamic CRM、OBA。详细情况请参考:
    广州:http://sharepoint.microsoft.com/sharepoint/worldwide/cn/south/Event/微软新技术预览活动(广州).aspx
    深圳:http://sharepoint.microsoft.com/sharepoint/worldwide/cn/south/Event/微软新技术预览活动(深圳).aspx

    posted @ 2007-05-20 23:11 ocean 阅读(2112) | 评论 (9)编辑

    将网站从WSS2.0升级到WSS3.0的心得

         摘要: 最近终于抽出写时间,将网站从WSS2.0升级到WSS3.0,根据升级的过程,将升级的一些经验总结了一下,大家共享。
    此文不是一份完整的升级文档,是在我具体实施升级的一些步骤和经验总结。升级的官方文档请参考:http://technet2.microsoft.com/Office/en-us/library/91046a84-57a1-40cb-a32c-ff3395073dc91033.mspx?mfr=true  阅读全文

    posted @ 2007-01-07 19:52 ocean 阅读(3257) | 评论 (7)编辑

    借宝地宣传一下:海洋工作室sps2007版用户系统正式运行!

           MOSS2007可以使用Form认证,并且用户基于provider模式,我使用membership做了一个用户系统,大家可以到 http://wss3.oceanstudio.net 体验一下。同时在本周日,我将在深圳做一个“SPS 2007中的Form认证”的讲座,是深圳俱乐部的活动,地址在深南中路核电大厦3层深圳信狮北大测试(地铁科学馆站C口,电话83697000,83697001)。时间是下午2点开始(1点半开始签到)。有兴趣的朋友可以去听听。
           相应的一些心得会在后面写出来。

    posted @ 2006-07-27 01:19 ocean 阅读(2463) | 评论 (9)编辑

    开发Sharepoint2007的Webpart备忘

         摘要: 想开发Sharepoint2007的Webpart吗,一步一步走进来。  阅读全文

    posted @ 2006-06-28 00:51 ocean 阅读(2679) | 评论 (0)编辑

    在Sharepoint2007新建站点

         摘要: 在Sharepoint2007中创建一个站点,和Sharepoint2003中差别不大,但是有些小地方有所改变。首先是默认不在Sites下了,而是在根下  阅读全文

    posted @ 2006-06-26 20:58 ocean 阅读(2072) | 评论 (2)编辑

    Sharepoint2007列表中的目录

        在Sharepoint2007中有一个新特性,就是列表里面可以建立目录了。在Sharepoint2003中,只有文档库、图片库和表单库里面可以建立目录。我想基于这些特性,原来基于列表开发的一些WebPart就需要做适当改变了。

       

    更多Sharepoint2007资讯....

    posted @ 2006-06-24 17:27 ocean 阅读(1475) | 评论 (6)编辑

    Sharepoint2007中的我的站点

         摘要: 在Sharepoint2007中,仍然存在“我的站点”,但是创建方式有所变化  阅读全文

    posted @ 2006-06-23 13:44 ocean 阅读(1691) | 评论 (1)编辑

    Sharepoint2007中的用户选择器

         摘要: 在Sharepoint2007中,User类型的数据提供了选择器,并且提供了姓名检查。  阅读全文

    posted @ 2006-06-22 11:40 ocean 阅读(1576) | 评论 (0)编辑