<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    coolfiry

    認認真真做人,兢兢業業做事!
    posts - 39, comments - 17, trackbacks - 0, articles - 0

    VC++內部COM插件的編程實現

    Posted on 2006-09-30 22:58 Coolfiry 閱讀(278) 評論(0)  編輯  收藏 所屬分類: C/C++
    一、閑聊

      今天要談的話題是COM,稍微深入一點,不知道大家用過C++Test或者Visual Assistant之類的軟件沒有,它們都有個非常引人注目的功能,那就是把它們自身嵌入到VC開發環境中去。這個功能讓我癡迷不已,原因只有一個:我想做一個可以嵌入VC開發環境的VC工程解析器,這樣用戶在VC開發環境中就可以直接對當前或所有工程進行各種分析,統計。那么實現它簡單嗎?簡單,Next和Copy即可輕松完成;僅僅這些嗎?不是,它的背后還有博大精深的COM做支撐。不管困難與否,還是讓我們先試為快。

      二、效果圖

    ?

      三、實現步驟:

      <3.1>新建一個<DevStudio Add-in Wizard>類型工程,輸入工程名稱"CodeAnalyser".

      <3.2>進入第二個畫面,系統要求用戶輸入插件的名稱和描述信息。并且要求用戶選擇是否需要生成工具欄以及是否自動添加VC事件響應代碼。


      <3.3>點擊"Finish"結束向導,進入代碼編輯窗口。

      在這里我們要說的一點是:該工程引用了ICommands接口,并從該接口上派生出 CCommands類。該類完成了所有用戶自定義函數接口,VC應用程序消息響應和VC調試動作的消息響應工作。當我們真正為CCommands類添加成員函數之前我們必須先為ICommands接口添加相應的函數接口聲明。在本工程中我總共為ICommands接口添加了兩個函數接口,它們名字分別為:GetCurDirCommandMethod和QuitCommandMethod聲明如下:(在CodeAnalyer.odl文件中)

    interface ICommands : IDispatch
    {
     // methods
     [id(1)] //在Vtable中的函數索引號
     HRESULT GetCurDirCommandMethod(); //得到VC當前工作目錄

     [id(2)] //在Vtable中的函數索引號
     HRESULT QuitCommandMethod (); //退出VC編輯器
    };

      在接口ICommands添加接口函數,那么相應的我們也要在類CCommands中聲明和實現ICommands接口函數,函數的內部代碼和普通工程代碼沒什么區別。

    //Implement(CCommands類內部接口函數的聲明)
    public:
    STDMETHOD(GetCurDirCommandMethod)(THIS);
    STDMETHOD(QuitCommandMethod)(THIS);

    //Function Code(Ccommands類內部接口函數的實現)
    //得到當前VC開發環境的工作目錄[您也可以讓它成為你想要實現的功能代碼]
    STDMETHODIMP CCommands::GetCurDirCommandMethod()
    {
     AFX_MANAGE_STATE(AfxGetStaticModuleState());
     VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));
     BSTR bstrCurDir;
     m_pApplication->get_CurrentDirectory(&bstrCurDir);
     CString str(bstrCurDir);
     ::MessageBox(NULL, str, "VC工作目錄", MB_OK | MB_ICONINFORMATION);
     VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));
     return S_OK;
    }

    //退出VC開發環境

    STDMETHODIMP CCommands::QuitCommandMethod()
    {
     AFX_MANAGE_STATE(AfxGetStaticModuleState());
     VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));
     if(::MessageBox(NULL,"您想退出VC++編輯器嗎(Y/N)?","詢問信息...", MB_YESNO | MB_ICONQUESTION) == IDYES)
      m_pApplication->Quit();
      VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));
     return S_OK;
    }

      <3.4> 創建工具欄,連接工具欄按鈕事件

      所有的幕后工作已經準備就緒,只差個工具欄界面就一切OK了。打開類CDSAddIn,它里面有三個成員函數,其中OnConnection和OnDisconnection成員函數的意義非常重要。它們的意義如下:

      <1>OnConnection:插件的初始化任務都在這里完成。如COM服務的啟動,工具欄/菜單欄的創建,工具欄按鈕/菜單項的添加與修改等等。

      <2>OnDisconnection:插件的卸載工作都在這里完成。如COM服務的卸載,工具欄/菜單欄的銷毀,釋放等等。

      了解了它們各自的用途之后我們就可以在相應的消息事件中添加代碼了。很顯然工具欄的初始化應該在OnConnection事件中完成。

      在OnConnection事件中系統首先獲得了VC應用程序接口,然后調用一個接口函數:AddCommand來為插件添加命令和命令影射函數。然后再使用另外一個接口函數AddCommandBarButton向工具欄中添加工具欄按鈕,其中每個工具欄按鈕會和一個命令標志符號相連接,這樣就能實現按鈕和命令(消息)之間的一一對應。下面是添加一個命令和一個工具欄按鈕的代碼(如果你要添加多個工具欄按鈕只要重復此步驟即可):

    LPCTSTR szCommand = _T("GetCurDirCommand");
    VARIANT_BOOL bRet;
    CString strCmdString;
    strCmdString.LoadString(IDS_CMD_STRING);
    strCmdString = szCommand + strCmdString;
    CComBSTR bszCmdString(strCmdString);
    CComBSTR bszMethod(_T("GetCurDirCommandMethod"));

    CComBSTR bszCmdName(szCommand); //和下面添加工具欄按鈕對應

    VERIFY_OK(pApplication->AddCommand(bszCmdString,bszMethod,0,dwCookie,&bRet));
    //AddCommand 參數含義:
    //bszCmdString:命令字符串。
    //bszMethod:Icommands接口函數名。
    //第三個參數代表位圖偏移量。
    //第四和第五個參數分貝為系統參數和返回值(參照MSDN的IApplication介紹)

    if (bRet == VARIANT_FALSE)
    {
     *OnConnection = VARIANT_FALSE;
     return S_OK;
    }

    //添加工具欄按鈕
    if (bFirstTime == VARIANT_TRUE)
    {
     VERIFY_OK(pApplication->AddCommandBarButton(dsGlyph, bszCmdName, m_dwCookie));
    }

      <3.5> 編譯,連接及在VC中引入插件

      以上就是我們所有的代碼工作,接下來趕快Build以下吧。編譯通過的話,在你的工程Debug目錄下會有個dll文件。然后打開VC編輯器,在VC任何一個工具欄上點擊鼠標右鍵,彈出如下圖所示菜單。然后選擇”Customize”子菜單,打開如下圖所示的工具欄定制窗口:


      接著選擇該窗口的最后一頁"Add-Ins and Macro Files"出現下圖所示窗口。


      然后點擊”Browse...”按鈕,這時打開你工程下的Debug目錄中的DLL文件,這樣你就可以看到你制作的工具欄了。同樣你再次打開上面的菜單,這次可以看到多了一個工具欄,并且名字亂七八糟的,怎么改變工具欄的名字呢?方法很簡單:打開上面窗口中的”Toolbars”選項頁,在工具欄列表框中找到你的工具欄,然后在”Toolbar name”編輯框中輸入你想要的名字即可。再打開上面的菜單看看名字是不是變了,哈哈!


      OK,今天的話題就聊到這里。
    主站蜘蛛池模板: 久久精品免费视频观看| 日本免费人成视频播放| 亚洲Av无码一区二区二三区| 国产免费拔擦拔擦8x| 野花香高清在线观看视频播放免费| 亚洲电影唐人社一区二区| 日本黄色免费观看| 中文字幕在线免费看线人| 亚洲a视频在线观看| 亚洲人成无码网站久久99热国产| 四虎成人精品永久免费AV| 亚洲免费网站观看视频| 亚洲av无码成人黄网站在线观看| 午夜免费福利影院| 在线看片免费人成视频福利| 亚洲另类无码专区首页| 亚洲成AV人片在线观看ww| 蜜桃精品免费久久久久影院| 无码av免费一区二区三区试看| 国产午夜亚洲精品不卡电影| 亚洲视频在线观看网址| 亚洲另类激情专区小说图片| 青青在线久青草免费观看| 成在线人视频免费视频| 亚洲精品成a人在线观看夫| 亚洲日本一区二区| 久久亚洲AV无码西西人体| 四虎成人免费影院网址| 久久久久久毛片免费播放| 一级A毛片免费观看久久精品| 亚洲国产成人精品电影| 精品亚洲一区二区| 亚洲高清无码在线观看| 最近2019中文字幕mv免费看| 免费成人高清在线视频| 二级毛片免费观看全程| 精品久久亚洲一级α| 亚洲一区二区三区高清不卡| 亚洲AV无码一区二区二三区入口| 亚洲免费无码在线| 国产aa免费视频|