关于Word Add-in Form 控件使用
今日,应客户需求需要来个WORD 2003的ADD-IN功能,功能大概是:分权限,管理者要在DOCUMENT中动态插入TEXTBOX、CHECKBOX之类的控件,并生成出这份WORD,给个按钮,把它和他插入的这些控件表示发给JAVA端存起来;使用者呢,在JAVA端下了那份WORD后,在ADD-IN里登陆,就着之前的控件来填写各种记录,然后按个按钮,在WORD里把这些控件的值都发去JAVA那边。(可能有朋友说直接上JAVA端来个FORM不就完了,不过也实在没办法,那些WORD的种类太多,而且使用者大部分时间可能要去到完全没网络的地方干活然后记录数据的,所以只能来个ADD-IN先存着WORD,回去再发上去咯。)
就着这要求呢,首先要解决是ADD-IN插入控件的功能来,这个其实不难,2007VSTO中直接有CONTENT CONTROLS,更方便,不过2003和之前的版本没那玩意,只能上ACTIVE控件,也就是COM,比较烦人...
这里贴段找了各种资料后的
private void KemaButton_Click(Office.CommandBarButton cmdBarbutton, ref bool cancel) { try { Word.Application ap = this.Application; Word.Selection selection = this.Application.ActiveDocument.Application.Selection; object start = selection.Start; object end = selection.End; Word.Range range = this.Application.ActiveDocument.Range(ref start, ref end); object oRange = range; Word.Document doc = ap.ActiveDocument; object oleClass = "Forms.TextBox.1"; Word.OLEFormat of = doc.InlineShapes.AddOLEControl(ref oleClass, ref oRange).OLEFormat; string fieldname = "TextBoxTTTT"; Microsoft.Vbe.Interop.Forms.TextBox cx = of.Object as Microsoft.Vbe.Interop.Forms.TextBox; if (cx != null) { cx.Text = "Testing a label"; cx.set_Value(ref temp11); cx.DblClick += new Microsoft.Vbe.Interop.Forms.MdcTextEvents_DblClickEventHandler(cx_DblClick); } } catch (Exception ex) { MessageBox.Show(ex.ToString()); } }
如上就可以插入一个COM控件啦。
现在烦了我两天的东西来了,Microsoft.Vbe.Interop.Forms.TextBox这个类里居然没封装有NAME ID 之类的表示用的东西,郁闷得,找了很多还是没有。
后来偶然回去VBA里看到,上面我加入哪个DblClick事件居然是 TextBox1_DblClick,直接郁闷了,明明就有表示居然出不来,所以开始逐层往上RELACTOR,找了大半天后才在Word.OLEForma.Object这个类型是System._ComObject的对象中找到NAME,不过确实没有被封装,在EXCEL那边有Excel.OLEObject这个类,但是到了WORD这边不知道为啥就被秒了,只能反射拿出来,后面也基本就是逻辑的解决了,下面吧代码MARK下哈,防止以后忘。
//反射设值 string fieldname = "TextBoxTTTT"; object ofilename = fieldname; of.Object.GetType().InvokeMember("Name", System.Reflection.BindingFlags.SetProperty, null, of.Object, new[] { ofilename }); //反射取值 Word.Application ap = this.Application; Word.Document doc = ap.ActiveDocument; foreach (Word.InlineShape temp in doc.InlineShapes) { object oleClass = temp.OLEFormat.ProgID; Microsoft.Vbe.Interop.Forms.TextBox cx = temp.OLEFormat.Object as Microsoft.Vbe.Interop.Forms.TextBox; result += string.Format("Name: {0}\r\n\r\n", temp.OLEFormat.Object.GetType().InvokeMember("Name", System.Reflection.BindingFlags.GetProperty, null, temp.OLEFormat.Object, null).ToString()); }