<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

       Prelude

      小T今年剛從大學畢業(yè)。由于上學的時候不好好學習,畢業(yè)時候找工作非常困難。好在平時上C語言課幫女生寫作業(yè)還積攢了一點經(jīng)驗值,好歹最后還是找到了一份寫程序的工作。上班第一天,他接到一個任務,給一個word 2003的插件添加一個command bar,上面再添加一個command bar button。倒霉的小T,悲慘的生活從此拉開了序幕。

       Section 1

      每一個新手,都應該感謝google。沒有他,真不知道該怎么把事情搞定。小T也不例外。在一番尋找之后,不花多少力氣。頗有基礎的小T已經(jīng)能夠創(chuàng)建一個Command Bar了。代碼雖然是Ctrl+C, Ctrl+V過來的,不過能用就行。

      CommandBar commandBar = application.CommandBars.Add("TestCommandBar", MsoBarPosition.msoBarTop, falsetrue);

      commandBar.Visible = true;

      搞定了Command Bar,勝利還會遠嗎?我們小T還蠻仔細的,特意多啟動了幾次Word。確保每次它都在那,而且只有一個。小T暗自得意,并順帶對M$公司心生敬意。真是一個偉大的公司啊。設計的軟件可擴展性這么好,簡單易學。

      繼續(xù)放狗。不多時,Command Bar Button也搞定了。

      CommandBarControl commandBarControl = commandBar.Controls.Add(MsoControlType.msoControlButton, Type.Missing, Type.Missing, Type.Missing, true);
      CommandBarButton commandBarButton 
      = (CommandBarButton)commandBarControl;
      commandBarButton.Caption 
      = "TestCommandBar";
      commandBarButton.Style 
      = MsoButtonStyle.msoButtonCaption;
      commandBarButton.Visible 
      = true;

      恩,那Type.Missing是什么東西?哎,早知道用VBA寫,可能會容易一些。接下來就是響應Click事件啦。

      commandBarButton.Click += delegate {MessageBox.Show("Hello");};

      我KAO!居然一次成功。可以用了,交差吧。小T走到QA面前,把程序給她裝上。開心地去吃午飯了,準備慶祝一下這難得的開門紅。

      Section 2

      午飯歸來。QA就報了一個bug。這可能是小T從業(yè)以來處理的第一個Bug吧。恭喜,你的與蟲斗其樂無窮的生活正式宣告開始了。Bug還蠻詭異的,就是你不停地點。到一定次數(shù),MessageBox就不再出來了。小T心想,我KAO,這是什么鳥問題啊?好吧,我來試試。我點一下。我點兩下。我點三下。。。。喂?玩我那?沒問題啊。于是小T把Jira上的Bug Report標記為Can not reproduce。心中暗暗不爽,什么鳥QA嘛。

       不多久,QA過來告訴他,重現(xiàn)啦,又重現(xiàn)啦。小T望著reopen的Bug Report,覺得很不是滋味。好吧,我多試試。點了N下。耶?真的誒,這是咋回事?放狗吧,搜了半天,沒發(fā)現(xiàn)啥有用的。在網(wǎng)絡和debugger之間耗費了接近一個下午之后,終于找到了一個同樣悲慘的人在一篇blog的小字中提到了這個問題的原因。正確的寫法麻煩多了:

      private _CommandBarButtonEvents_ClickEventHandler handler;
      private CommandBarButton commandBarButton;

      private void InitializeCommandBar(Application application)
      {
        CommandBar commandBar 
      = application.CommandBars.Add("TestCommandBar", MsoBarPosition.msoBarTop, falsetrue);
        commandBar.Visible 
      = true;
        CommandBarControl commandBarControl 
      = commandBar.Controls.Add(MsoControlType.msoControlButton, Type.Missing, Type.Missing, Type.Missing, true);
        commandBarButton 
      = (CommandBarButton)commandBarControl;
        commandBarButton.Caption 
      = "TestCommandBar";
        commandBarButton.Style 
      = MsoButtonStyle.msoButtonCaption;
        commandBarButton.Visible 
      = true;
        handler 
      = new _CommandBarButtonEvents_ClickEventHandler(commandBarButton_Click);
        commandBarButton.Click 
      += handler;
      }

      private void commandBarButton_Click(CommandBarButton Ctrl, ref bool CancelDefault)
      {
        MessageBox.Show(
      "Hello");
        GC.Collect();
      }

       好,這下就算強制GC也不會出問題了。寫完這些代碼,小T開始抱怨起來了。這么多人罵M$,那不是沒有道理的啊。。。

      Section 3

       第二天早上。QA又報Bug了。創(chuàng)建一個新文檔,在新創(chuàng)建的文檔里,按鈕不好使了。小T第一反應是怎么可能,代碼都是一樣的,我又沒判斷當前是哪篇文檔?難道他們是兩個command bar?不過鐵的事實擺在那里,還真有問題。小T的第一個懷疑就是,兩篇word文檔是兩個word進程。然后有傳說中的并發(fā)問題?懷疑很快被否定了,Word在大部分情況下只有一個進程(嘿嘿,大部分情況。。。)。那會是什么問題呢?哎,一早上的好心情就給它糟蹋了。放狗吧。這下就更加沒有頭緒了。你說我怎么把這個現(xiàn)象用關(guān)鍵字描述出來呢?找都不好找。等到快下班,功夫不負有心人。在一次無意的嘗試之后,發(fā)現(xiàn)了問題的解決方案,那就是“一行代碼”:

      commandBarButton.Tag = "TestCommandBar";

       我KAO,居然這么簡單……但是文檔就是不寫(MSDN唱到:就不告訴你,就不告訴你,就不告訴你~)

       Section 4

      事情到這里還沒完。一天BA告訴小T,需求有變化。客戶說這按鈕能不能加到我平常用的Command Bar上啊。那么多Command Bar我不喜歡。好吧,那就給它加到Standard Command Bar上吧。改一行代碼就行,嘿嘿,知道什么叫Well-Design了吧:

      CommandBar commandBar = application.CommandBars["Standard"];

      嗯,挺好的。工作正常。咦?等我再試一下。shit!怎么有兩個Test Command Bar Button出來?我KAO,又多了一個。。。無語。之前的代碼咋就沒問題呢?那就在添加之前判斷一下吧,如果之前的button存在,就不添加了。

      foreach (CommandBarControl ctrl in commandBar.Controls)
      {
        
      if (ctrl.Tag.Equals("TestCommandBar"))
        {
          
      return;
        }
      }

      小T覺得很不爽。添加按鈕的時候我不是說了是Temporary嘛:

      CommandBarControl commandBarControl = commandBar.Controls.Add(MsoControlType.msoControlButton, Type.Missing, Type.Missing, Type.Missing, true);

       呵呵,誰讓你相信MSDN的啊?真是天真的傻孩子。事實證明,Temporary的行為極其詭異。

      Section 5

      好日子似乎來臨了。插件裝在客戶的機器上,一直良好。版本2.0就快要發(fā)布了。這個時候問題出現(xiàn)了。QA發(fā)現(xiàn),V1.0卸載之后,按鈕還在那里。嗯,這個問題我知道,小T心想。就是那個Temporary的問題嘛。看來不光是不能添加兩遍,還得考慮怎么刪掉它。那不如每次程序退出的時候就刪了吧,省得夜長夢多。

      ApplicationEvents4_Event events = application;
      events.Quit 
      += delegate {
        CommandBar commandBar 
      = application.CommandBars["Standard"];
        commandBar.Reset();
      };

      但是。。。沒有效果。有些時候,是沒有解釋的。看來只能寫一個Uninstaller來卸載啦。

      public class Program
      {
        
      public static void Main(string[] args)
        {
          Application application 
      = new Application();
          application.Visible 
      = true;
          application.CommandBars[
      "Standard"].Reset();
        }
      }

      小T禁不住想問,為什么基本同樣的代碼在不同的地方執(zhí)行就有不同的效果呢?

      畫外音:嗯,This is a good question~~這正式Office插件開發(fā)的奇妙之處啊。

      這個時候,我們的小T已經(jīng)不再是菜鳥了。但是你以為你已經(jīng)知道了一切了嗎?嘿嘿。。。

      Section 6

      難以伺候的客戶又抱怨了。這個按鈕為什么不能自定義啊。哦,我們偉大的word 2003,它有強大的用戶自定義功能。小T寫的按鈕必須在Standard Command Bar上,拖到別的地方去下次又會創(chuàng)建出一個新的出來。公司的UD人員看到了,en,這可用性太差啦。不行,得給我改。好吧,小T,心想,我真是命苦啊。改進后的代碼,不再強制要求在Standard Command Bar下了。

      CommandBarControl foundControl = application.CommandBars.FindControl(Type.Missing, Type.Missing, "TestCommandBar", Type.Missing);
      if (foundControl != null)
      {
        
      return;
      }

       嘿嘿,循環(huán)都省了。

      Section 7

      小T在上一個項目干得不錯。于是公司覺得小T干這個比較在行,所以第二個項目也是一個word 2003的插件。小T這次總結(jié)上次的經(jīng)驗,一開始就關(guān)注這卸載的問題。在無數(shù)個皓首窮經(jīng),不眠不休的夜晚之后,終于讓小T找到了更可靠的使用word api的辦法。那就是不用word api。word 2003的command bar的改動其實是存儲在template和document上的。所以小T把之前添加一大堆代碼濃縮成了一句話:

      object install = true;
      application.AddIns.Add(
      @"c:\my_template.dot", ref install);

       這類型為ref object的函數(shù)參數(shù)實在是。。。(無語,[ref object]就更加牛x了。。。)。然后再結(jié)合FindControl,監(jiān)聽事件。齊活,小T終于感覺自己摸到了門道。

      Section 8

      新項目的需求中包括讓不同文檔窗口上的按鈕狀態(tài)獨立。就像你按下B,當前輸入的文字就粗體了那樣。這下可把小T難住了。不過,不死的小T還是最終活下來了。其實也沒幾行代碼,關(guān)鍵就是你知道不知道。word application有一個隱藏屬性(其實沒隱藏,只是文檔上沒說,官方說法是It is for internal use。。。)CustomizationContext。所以:

      private void HandleNewDocument(Document document)
      {
        application.CustomizationContext 
      = document;
        InitializeCommandBar(application);
      }

       小T這次真的有些得意了。這我都能搞定,太天才了。擁有多年開發(fā)經(jīng)驗的PM走過來,三擊了一下word的快捷方式。瞬間啟動了三個word窗口。僵死了半分鐘之后,發(fā)現(xiàn)兩個窗口上有command bar,一個沒有。出錯日志表明,word api拋出了ComException。。。小T,頓時覺得有一些無奈,word出錯,我能怎么辦?把CustomizationContext那行去掉,一切正常。。。

      Conclusion

      Command Bar的王道是用.dot加CustomizationContext。但是要認識到這一點,不寫爛兩三個項目是做不到的。小T的原型也就是本人,在寫兩個Outlook 2007插件,一個Outlook 2003插件,一個Excel 插件,N個PowerPoint插件,一個Word插件,然后再來寫一個Word插件的時候才認識到這一點。。。也許只是我太笨了。

      以上只是故事的很少一部分。關(guān)于command bar的故事還有很多,比如怎么樣取消built-in command bar button的行為,OnAction有什么用,Command bar與Accessibility api的關(guān)系,以及著名的Outlook+Word+Command Bar問題。限于個人體力值有限,就不繼續(xù)展開講了。每個故事背后,都是無數(shù)人的心酸,血淚與青春。M$的東西一如既往地易學難精,而且沒有道理。關(guān)鍵是最終你不能獲得什么真本事,只能獲得一堆“知識”。這些“知識”只對Office開發(fā)有用,如果不做office開發(fā)根本沒有什么價值。在這里,奉勸大家,如果不能換一個項目的話,那就提早離職吧。不要把時間浪費在Office這個愚蠢的平臺上了。如果你還真把它當做一個平臺的話。

      posted on 2008-10-29 23:52  taowen  閱讀(5007)  評論(18)    收藏  舉報
      主站蜘蛛池模板: 产综合无码一区| 国产人与禽zoz0性伦多活几年| 国产精品免费中文字幕| 少妇高潮流白浆在线观看| 亚洲老妇女一区二区三区| 亚洲亚洲人成综合网络| 好爽毛片一区二区三区四| 成人综合人人爽一区二区| 欧美高清狂热视频60一70| 日韩一区二区三区无码影院| 国内视频偷拍久久伊人网| 国产专区精品三级免费看| аⅴ天堂中文在线网 | 久久久精品2019中文字幕之3| 成人区人妻精品一区二区| 久久月本道色综合久久| 亚洲日本韩国欧美云霸高清| 国产亚洲欧洲AⅤ综合一区| 国产亚洲精品岁国产精品| 色久综合色久综合色久综合| 一二三四中文字幕日韩乱码| 久爱www人成免费网站| 日韩av毛片福利国产福利| 免费无码又爽又刺激高潮虎虎视频| 人妻丰满熟妇av无码区不卡| 亚洲精品有码在线观看| 久久亚洲精品11p| 亚洲av日韩av一区久久| av无码免费一区二区三区| 亚洲成人av高清在线| 桃花岛亚洲成在人线AV| 在线观看热码亚洲AV每日更新| 精品久久久bbbb人妻| 超碰人人超碰人人| 国产精品一区二区色综合| 精品超清无码视频在线观看| 国产精品久久蜜臀av| 成人免费视频一区二区三区| www免费视频com| 日韩一区二区三区理伦片| 免费人妻无码不卡中文字幕18禁|