随笔 - 42  文章 - 0  评论 - 286 

   使用AxWebBrowser或者WebBrowser的方法将Office嵌入我们的.Net系统问题有几个,1是WebBrowser控件是一个比较重的控件,2是通过WebBrowser去控制Office如果出现问题没有办法进行调试与判断,也无法修改,3是Office对应的菜单没有办法控制。为此我们决定需求新的解决方案,使用微软提供的dsoFramer控件例子,这个例子使用VC++编写,本身是可以使用的,可以参见:

   http://support.microsoft.com/default.aspx?scid=kb;en-us;311765

在这里下载dsoFramer的源码

http://www.microsoft.com/downloads/details.aspx?familyid=CE2CA4FD-2169-4FAC-82AF-770AA9B60D77&displaylang=en

下面进行我们的改造过程

1.使用VisualStudio2005打开该VC工程,按系统提示进行转换

2.转换完成后,发现该控件缺少OLB文件,这个文件是控件的对象库,在引用该控件的时候要用到,编译该对象库需要mktyplib.exe但该工具在VS2005中已经不再提供,使用MIDL代替,但MIDL又不支持这种转换过来的工程,没想到第一步就遇到了挫折,为此想了很多办法,后来从VS2003中找到旧的mktyplib.exe,拷入VS2005\common\tools\bin下面,呵呵可以了,(这个应该算VS2005的一个Bug吧)

3.编译好ocx,通过Regsvr32 注册到系统中

4.创建一个C#工程,引入刚才的ocx

5.发现该控件,自带了菜单,工具栏,并且我们基本不能控制该控件,晕倒

6.决定自己将它的菜单栏放到我们的.Net  Form上,发现不能将 C++的菜单直接放过来,C++的有太多的控制了,如果要重写这些控制,就要吐血了,并且发现新的MenuStrip控件根本就不是一个菜单,传入C++后,不认识。费了好大的劲,将Form的MainMenu给传了进去,呵呵,这下行了,看看运行的效果:

怎么样,感觉还不错吧,现在这个Excel就可以好好的控制了,最主要的是, 如果你想增加什么新的东西,出现什么问题就可以自己调试解决了。

如果你要在OCX中增加接口,你必须同时修改三个地方,一个是ODL,OCX的接口定义文件,并且按照规范,一个是你的控件实现的对应的.H文件,一个实现的.CPP文件,这些都简单了。

6.菜单出来了,发现不能控制,又再次晕倒,不知所措了

解决办法,是通过OVerride窗体的WndProc方法,将菜单的事件,除了你自己的菜单以外的,都给传到OCX中。

在OCX中增加一个接口方法:ExecuteMenuMessage,它直接调用OnMenuMessage,呵呵,这样就行了,代码如下:

        protected override void WndProc(ref Message m)
        {
            IntPtr  lWParam=IntPtr.Zero  ;
            switch (m.Msg)
            {
                case WindowsMessages.WM_INITMENU :
                case WindowsMessages.WM_ENTERIDLE:
                case WindowsMessages.WM_MENUSELECT:
                case WindowsMessages.WM_INITMENUPOPUP:
                case WindowsMessages.WM_COMMAND :                 
                    ExecuteMenuMessage(m.Msg, m.WParam, m.LParam);
                    //Console.Write(m.Msg.ToString("X"));
                    //Console.Write("    ");
                    //Console.Write(lWParam.ToString("X"));
                    //Console.Write("    ");
                    //Console.WriteLine(m.LParam.ToString("X"));
                    break;               
            }
       
             base.WndProc(ref m);      
        }

   现在菜单信息也传入了,哦,创建菜单的程序如下,酷吧:

   private void Form1_Load(object sender, EventArgs e)
        {
            //if (this.Menu == null)
            {
                this.Menu = new MainMenu();
                CreateFileMenu();
                IntPtr hMainMenu = this.Menu.Handle;
                this.axFramerControl1.MainFormMenu = hMainMenu;
                this.axFramerControl1.MainForm = this.Handle;
            }
        } 
       
     

        private void CreateFileMenu()
        {
            IntPtr pFileMenu = MenuHelper.CreatePopupMenu();
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_STRING, FrameMenuMessage.MNU_NEW, "新建(&N)...\tCtrl+N");
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_STRING, FrameMenuMessage.MNU_OPEN, "打开(&O)...\tCtrl+O");
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_STRING, FrameMenuMessage.MNU_CLOSE, "关闭(&C)");
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_SEPARATOR, 0, string.Empty);
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_STRING, FrameMenuMessage.MNU_SAVE, "保存(&S)\tCtrl+S");
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_STRING, FrameMenuMessage.MNU_SAVEAS, "另存为(&A)...");
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_SEPARATOR, 0, string.Empty);
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_STRING, FrameMenuMessage.MNU_PGSETUP, "页面设置(&U)...");
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_STRING, FrameMenuMessage.MNU_PRINTPV, "打印预览(&V)");
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_STRING, FrameMenuMessage.MNU_PRINT, "打印(&P)...");
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_SEPARATOR, 0, string.Empty);
            MenuHelper.AppendMenu(pFileMenu, MenuFlags.MF_STRING, FrameMenuMessage.MNU_PROPS, "属性(&I)");

            MenuHelper.AppendMenu(this.Menu.Handle, MenuFlags.MF_BYPOSITION | MenuFlags.MF_POPUP, (uint)pFileMenu.ToInt32() , "文件(&F)");
            MenuHelper.DrawMenuBar(this.Handle);
        }

7.当关闭Excel后会怎么样,靠,菜单还在,并且每个都报错,肯定报错,OLE已经卸载了,只好跑去修改OCX控件中docObject的ClearMergeMenu,让它清除掉Excel的菜单,明白原理就简单了。

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::ClearMergedMenu (protected)
//
//  Frees the merged menu set by host.
//
STDMETHODIMP_(void) CDsoDocObject::ClearMergedMenu()

 if (m_hMenuMerged)
 {
        int cbMenuCnt = GetMenuItemCount(m_hMenuMerged);
  int iMainMenuCnt=0;
  if(this->m_hMenuMainForm)
   iMainMenuCnt=GetMenuItemCount(m_hMenuMainForm);

  for (int i = cbMenuCnt-1; i >0; --i)
  {
   if(this->m_hMenuMainForm)
   {
    RemoveMenu(m_hMenuMainForm,--iMainMenuCnt,MF_BYPOSITION);
   }
   RemoveMenu(m_hMenuMerged, i, MF_BYPOSITION);
  }
  if(m_hwndMainForm)
   DrawMenuBar(m_hwndMainForm);

  DestroyMenu(m_hMenuMerged);
  m_hMenuMerged = NULL;
 }
}

 

还有一些遗留问题:

   1.菜单合并时候,可以指定位置,这样有利于我们控制,这个暂时没做。

   2.文件菜单中,当Excel卸载后,文件菜单的部分不能自动置为灰色的,这里还没搞清楚是什么原因

 

好了如果你有兴趣,而且要使用类似的功能,可以找我,我可以提供源码,不过如果你改的更好了,别忘记给我一份,呵呵。

 

 

 

 

 

 

 

posted on 2006-04-19 08:53 caidehui 阅读(5250) 评论(45)  编辑 收藏 网摘

  回复  引用    
2006-04-19 11:26 | jassey[未注册用户]
感觉这样也比较麻烦
不如直接在Excel中加入宏或开发Excel的智能客户端应用,使用上也比较直观的。

主要是看要解决的问题,以及客户的需要。

  回复  引用  查看    
2006-04-19 17:31 | cjh      
学习
  回复  引用  查看    
2006-04-19 18:21 | xiao_p      
好东西… 谢谢了
一直用WebBrowser,被菜单折磨的够呛……

  回复  引用    
2006-04-26 15:28 | c#boy[未注册用户]
问一个问题:
当Excel嵌入web页的时候怎么用程序来控制它的数据显示?

  回复  引用    
2006-06-14 23:47 | 般若波若密多[未注册用户]
文章写得很好 我就是因为这东西菜单的问题才一直没敢用
这下好了

而且,我今天刚想的问题是 用dsoFramer open之后的excel文件怎么在c#的代码中作为对象引用的问题

想和你要一份源码我自己改改看

谢谢先
adams_z@msn.com 我的mail 也是msn号码

  回复  引用    
2006-07-13 08:43 | jfan[未注册用户]
很好!问一个问题:如果用vb.net能否实现?谢谢了
  回复  引用    
2006-09-18 10:11 | zlg[未注册用户]
我看到了你写的excel潜入的文章,非常棒我现在也遇到了这个问题不知是否可以将你的代码发一份给我啊!谢谢;
QQ:79508619
mail:zlg.zhuzhu@gmail.com

  回复  引用    
2006-09-19 13:56 | zlg[未注册用户]
哦~~非常感谢你的回信~~但是我有个问题想请教你,就是我怎么才能通过这个控件获得它打开的对象呢?(例如:我用这个控件打开了excel,我如何才能获得这个打开的excel对象呢!)谢谢!
  回复  引用    
2006-10-25 08:03 | yil9999[未注册用户]
我想在web網頁中加入WORD或EXCEL文件,当可以編輯,要如何做呢?

请多多指教,謝謝!

QQ:47207454
mail:dgn_yilang@hotmail.com

  回复  引用    
2006-11-25 10:18 | Tangb4c[未注册用户]
最近在写一个显示PPT文件,然后还有一些让用户不能保存其内容。想要一份你的这个代码,看看能不能用在PPT方面。谢谢
b4c@yeah.net

  回复  引用    
2006-11-25 10:26 | Tangb4c[未注册用户]
对了,想问一个问题
我使用WebBrowser来显示PPT,但不让用户保存、修改PPT,
我想屏蔽鼠标右键来实现

我想的解决方案:
1、之前我想的是做一个继承WebBrowser的类,然后重写
protected override void WndProc(ref system.Windows.Forms.Message m)
将右键过滤,不过发现不行~,截取不到鼠标右键的消息
2、访问WebBrowser里面封装的显示PPT的ActiveX,来实现禁止保存、复制等目的,不过从前天到今天,在网上找了很久,也没有找到这种类似的解决方案。

程序人生你知道怎么解决吗?能不能帮帮我,谢谢

  回复  引用    
2006-12-08 15:58 | veelee[匿名][未注册用户]
veelee@sohu.com

兄弟.希望能得到一份

  回复  引用    
2007-02-03 14:02 | elber[未注册用户]
hi,你好你文章中的功能正是我需要。
能将源代码共享一下吗
我的邮箱是
chenh@kingdee.com
谢谢

  回复  引用    
2007-02-08 22:39 | pink_edward[未注册用户]
您好,我正在研究这个内容麻烦您发一份,谢谢
邮箱:pink_edward@126.com

  回复  引用    
2007-02-09 16:09 | hbqhdlc[未注册用户]
请问LZ有没有控制word的代码,共享一下.谢谢.我的邮箱:hbqhdlc@163.com
  回复  引用    
2007-03-27 11:44 | 天涯[未注册用户]
楼主,我最近在用这个,可是你的MenuHelper是自己封装的吧,希望得到你的一份源代码,谢谢!
Email:larler@163.com
非常感谢

  回复  引用    
2007-04-03 02:09 | aspdotnet[未注册用户]
您好,我正在研究这个内容麻烦您发一份,谢谢
邮箱:aspdotnet@yeah.net

  回复  引用    
2007-04-16 17:31 | 段杰[未注册用户]
能否给我一份啊,期待中。都快被excel折腾得受不了
duanzhfieng@lawyee.net,谢谢

  回复  引用    
2007-04-16 21:04 | 段杰[未注册用户]
能否给我一份啊,期待中。都快被excel折腾得受不了
duanzhifeng@lawyee.net,谢谢,刚才拼错了

  回复  引用    
2007-04-16 21:04 | 段杰[未注册用户]
能否给我一份啊,期待中。都快被excel折腾得受不了
duanzhifeng@lawyee.net,谢谢,刚才拼错了

  回复  引用    
2007-04-16 21:04 | 段杰[未注册用户]
能否给我一份啊,期待中。都快被excel折腾得受不了
duanzhifeng@lawyee.net,谢谢,刚才拼错了

  回复  引用    
2007-04-26 12:21 | lixiangqun515[未注册用户]
谢谢,给我一个吧,lixiangqun515@163.com
  回复  引用    
2007-05-28 12:55 | yzy[未注册用户]
谢谢,给我一份吧!
yzy@caxa.com

  回复  引用    
2007-06-29 14:31 | tinsk[未注册用户]
谢谢,给我一个吧,tinsk@163.com
  回复  引用    
2007-07-15 08:25 | llj[未注册用户]
谢谢,给我一个吧,liliujiang@163.com
  回复  引用    
2007-07-17 16:45 | Telemann[未注册用户]
非常感谢楼主在该技术上的突破和分享,给我也发一份吧。谢谢。
telemann@sina.com

  回复  引用    
2007-08-08 09:48 | 楼主你好[未注册用户]
非常感谢楼主在该技术上的突破和分享,给我也发一份吧。谢谢。
cclx@sogou.com

  回复  引用    
2007-08-28 21:53 | ppying[未注册用户]
点一下主界面上的菜单,显示菜单,然后再点击Excel Worksheet,你可以发现主界面菜单根本不会消失.不知如何解决此问题?望赐教.
dsoFramer版本 : 1.3

请将解决的方案发送ppying@21cn.com
谢谢!

  回复  引用    
2007-10-14 23:28 | 黄河[未注册用户]
谢谢,给我一份吧,我研究这一块好几天了,一直无法突破这一点
rivery@21cn.com

  回复  引用    
2007-11-05 18:30 | zhanghao[未注册用户]
谢谢,给我一份吧,我研究这一块好几天了,一直无法突破这一点
zhanghao_zhh@hotmail.com

  回复  引用    
2007-11-05 19:31 | 大寨小子[未注册用户]
谢谢,也给传一份吧!

不知道可不可以不用控件本身所带的菜单,但是,自己能调用他的菜单呢??

chunhui-889@163.com

  回复  引用    
2008-05-22 12:04 | liqinxiong[未注册用户]
谢谢,也给传一份吧!

不知道可不可以不用控件本身所带的菜单,但是,自己能调用他的菜单呢?? 我主要想控制他的复制粘贴功能,还有,能不能直接在内存打开Excel,而不用通过磁盘文件呢?比如从数据库读到数据后直接打开,保存时也保存到数据库中。

  回复  引用  查看    
2008-05-26 13:16 | 锁儿      
……
this.axFramerControl1.MainFormMenu = hMainMenu;
this.axFramerControl1.MainForm = this.Handle;
……
可是FramerControl控件中并无MainFormMenu,MainForm 属性啊?不知是不是我的DsoFramer的版本有误。

希望楼主能传一份源码,谢之不尽(surer214@tom.com)

  回复  引用  查看    
2008-05-28 00:13 | 求知无傲      
511391577@163.com 多谢先。
  回复  引用    
2008-05-31 09:33 | 迷宫[未注册用户]
急需!谢谢先!183848022@QQ.com
  回复  引用    
2008-07-30 10:55 | renhaojie[未注册用户]
你好!可以把你做的本文的例子发一份给我吗?我正在用dsoframer编winform下的程序,苦于找不到合适的接口语句。我的电子邮箱 :renhaoj2008@126.com,谢谢!

  回复  引用  查看    
2008-08-07 16:52 | 荔橙伊珊雨      
?
  回复  引用    
2008-08-07 17:17 | Cai[未注册用户]
很抱歉,很久不做开发了,所以大家需要的源代码我也无法找到了。如果找到我再贴上来
  回复  引用    
2008-10-04 14:36 | winile[未注册用户]
能否给我一份源代码呢?os9@21cn.com
  回复  引用    
2008-10-09 13:05 | Yocus[未注册用户]
能否共享一份给我啊,mail: mzsoft001@163.com
  回复  引用    
2008-10-14 20:21 | 254304714[未注册用户]
能给我一份源代码吗,自己弄了一个星期的,还是不行~~谢谢了
lion254304714@126.com

  回复  引用  查看    
2008-12-25 09:19 | 温景良(Jason)      
能否共享一份给我啊,mail: wjl_wjl520@163.com
  回复  引用    
2009-04-04 00:30 | 幻神zeus
你好,能否提供一份源码啊谢谢你
94273850@qq.com




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 378782




相关文章:

相关链接: