青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

S.l.e!ep.¢%

像打了激速一樣,以四倍的速度運轉(zhuǎn),開心的工作
簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

給VC增加注釋/反注釋的功能

Posted on 2009-11-23 18:35 S.l.e!ep.¢% 閱讀(552) 評論(0)  編輯 收藏 引用 所屬分類: VC

給VC增加注釋/反注釋的功能
??????????????? ――楊科? 注:本文可隨意轉(zhuǎn)載, 但請保留我的署名(CopyLeft)

用過VB,PowerBuilder的朋友一定知道在它們的工具條上有兩個按鈕,用來完成對選中的代碼進行注釋或反注釋,而在VC中如果要注釋一段選中的代碼,除了在要注釋的代碼中添加/* 和 */外,就是對每一行都使用單行注釋//。其實在VC中提供了編寫插件的功能,VC將開發(fā)環(huán)境中的各種對象以COM接口的形式暴露出來,而且提供的插件應(yīng)用程序向?qū)Э梢酝瓿纱蟛糠值目蚣艽a,所以我們只需要添加我們想要的功能就可以了。所以我們可以利用這些COM接口來對VC的開發(fā)環(huán)境進行操作,這樣我們就可以完成對選中的代碼的注釋和反注釋功能。

下面具體描述以下開發(fā)這個插件的過程:
首先創(chuàng)建一個新工程,類型選擇DevStudio Add-in Widzard,填寫工程名稱后,單擊OK繼續(xù)。在接下來的頁面中選中Provides a toolbar,這會使我們創(chuàng)建的插件具有一個工具條,不需要選中Responds to Developer Studio events,因為我們不需要對開發(fā)環(huán)境中的事件作出響應(yīng),在上面的兩個文本框中,可以隨便輸入一些你對這個插件的描述及功能介紹,單擊Finish完成向?qū)А?/p>

對了,首先聲明以下,在VC中每一個Add-in都是一個COM組件,在Add-in的向?qū)е猩傻某绦蚴怯肕FC和ATL共同實現(xiàn)的,所以在生成的原代碼中你會看到兩個分別叫做theApp和_Module的全局變量。另外向?qū)槲覀兩闪艘粋€成為ICommands的接口,我們必須在這個接口添加適當?shù)姆椒▉硗瓿晌覀冃枰墓δ堋?/p>

讓我們看一下AppWidzard為我們生成了哪些類,首先我們會看到一個CCommands的類,而且其中實現(xiàn)了我們在上面提到的ICommands接口。一個稱為CDSAddIn的類,這個類中實現(xiàn)兩個方法OnConnection(), OnDisconnection(), 這兩個方法我們不會直接在程序中調(diào)用,而是由VC集成環(huán)境調(diào)用的,當VC啟動時它會首先查詢關(guān)于Add-ins的注冊信息,然后調(diào)用相應(yīng)組件的OnConnection()方法,所以在這個方法中我們應(yīng)該把我們要實現(xiàn)的命令添加到VC的繼承環(huán)境中,當這個插件被卸載或VC關(guān)閉時,VC會調(diào)用OnDisconnection()方法,在這里我們應(yīng)該釋放我們在OnConnection()中分配的資源。

剩下的就是應(yīng)用程序類了,另外還有一些必須的全局函數(shù)DllGetClassObject, DllCanUnloadNow, DllRegisterServer和DllUnregisterServer是COM組件的幾個通用實現(xiàn),可以查閱關(guān)于COM的書籍來了解這些知識。

AppWidzard生成的代碼中在ICommands接口中實現(xiàn)了一個與應(yīng)用程序同名的方法,通常這個方法名稱并不是我們需要的,所以下面就開始來改寫這個方法,把它改成CommentCode。雙擊ICommands接口中的與你應(yīng)用程序同名的方法,VC會打開一個與你的應(yīng)用程序同名的一個擴展名是odl的文件,找到一行叫做HRESULT YourAppCommandMethod()并把YourAppCommandMethod改成CommentCode(),然后打開Commands.cpp和Commands.h把其中的YourAppCommandMethod都改成CommentCode()。

現(xiàn)在我們修改DSAddIn.cpp,找到OnConnection方法,直接找到下面這斷代碼:
LPCTSTR szCommand = _T("YourAppCommand");
VARIANT_BOOL bRet;
CString strCmdString;
strCmdString.LoadString(IDS_CMD_STRING);
strCmdString = szCommand + strCmdString;
CComBSTR bszCmdString(strCmdString);
CComBSTR bszMethod(_T("YourAppCommandMethod"));
CComBSTR bszCmdName(szCommand);
VERIFY_OK(pApplication->AddCommand(bszCmdString, bszMethod, 0, m_dwCookie, &bRet));
并把它改成下面的樣子:
LPCTSTR szCommand = _T("CommentCode");
VARIANT_BOOL bRet;
CString strCmdString;
strCmdString.LoadString(IDS_CMD_STRING);
strCmdString = szCommand + strCmdString;
CComBSTR bszCmdString(strCmdString);
CComBSTR bszMethod(_T("CommentCode"));
CComBSTR bszCmdName(szCommand);
VERIFY_OK(pApplication->AddCommand(bszCmdString, bszMethod, 0, m_dwCookie, &bRet));
由于上面的代碼涉及到了字符串資源,所以我們再來看看上面提到的IDS_CMD_STRING的內(nèi)容,打開這個字符串資源改成下面的形式:
Comment Code Comment the selected code Comment the selected code

現(xiàn)在我們可以編譯這個應(yīng)用程序,應(yīng)該不會出現(xiàn)錯誤,單擊運行會彈出一個對話框要你指定一個宿主應(yīng)用程序來調(diào)用這個DLL, 因為我們是為VC開發(fā)插件應(yīng)用,所以找到你VC的可執(zhí)行文件目錄并選中msdev.exe。當另一個VC啟動后,選擇Tools¦Customize...,叢屬性頁種選擇Add-ins and Macro Files標簽,單擊Browse按鈕,選擇你剛生成的DLL文件,這時旁邊的列表框,會出現(xiàn)你編寫的插件的名字,單擊Close關(guān)閉對話框,這是在工具條的下面會出現(xiàn)一個小工具條,將鼠標移動工具條的按鈕上面,會出現(xiàn)Comment the selected code的代碼提示, 單擊按鈕會彈出一個對話框,這是AppWidzard對這個命令的缺省實現(xiàn)。

下面我們該實現(xiàn)我們的具體功能的代碼了。由于VC把它集成環(huán)境中對象通過COM接口暴露出來,所以我們就利用這些對象來實現(xiàn)注釋代碼的功能。這里有兩個問題:1、我們怎么能知道VC中當前打開的文檔是否是源代碼而不是圖形或?qū)υ捒颍?、我們怎么才能知道當前源代碼文檔中的被選擇的文本。下面我通過實際的代碼來解釋這兩個問題。

1、查找當前打開的源代碼編輯其中的文檔并查找當前選中的文本。這里我寫了一個函數(shù)因為在實現(xiàn)反注釋的時候我們還需要完成相同的功能。請參閱代碼中的注釋(注意相應(yīng)接口指針的釋放):
HRESULT CCommands::GetTextSelection(IApplication *pApplication, ITextSelection** pTextSelection)
{
IDispatch* pDispatch;
//通過有集成環(huán)境傳進來的應(yīng)用程序?qū)ο蟛檎耶斍疤幱诨顒訝顟B(tài)的文檔對象,注意返回的是一個IDispatch接口指針。
HRESULT hr = pApplication->get_ActiveDocument(&pDispatch);
//此處應(yīng)注意即使get_ActiveDocument()函數(shù)成功返回pDispatch指針仍有可能為空(即VC中沒有文檔打開),所以此處要判 //斷pDispatch是否為空
if (SUCCEEDED(hr) && pDispatch != NULL)
{
//取得IGenericDocument接口的指針,我們可以通過該接口指針來查詢當前的活動文檔是否是文本文檔。
IGenericDocument* pDocument;
hr = pDispatch->QueryInterface(IID_IGenericDocument, (void**)&pDocument);
if (FAILED(hr))
{
pDispatch->Release();
return E_NOINTERFACE;
}
pDispatch->Release();

//在此處查詢ITextDocument接口,如果能成功返回,就說明當前文檔是文本文檔。
ITextDocument* pTextDocument;
hr = pDocument->QueryInterface(IID_ITextDocument, (void**)&pTextDocument);
if (FAILED(hr))
{
pDocument->Release();
return E_NOINTERFACE;
}
pDocument->Release();

//現(xiàn)在我們有了當前的活動的文本文檔,我們就可以通過get_Selection函數(shù)來獲得當前選中的文本,這里要求的還是 //一個IDispatch接口的指針
hr = pTextDocument->get_Selection(&pDispatch);
if (FAILED(hr))
{
pTextDocument->Release();
return E_NOINTERFACE;
}
pTextDocument->Release();
//通過QueryInterface()方法取回ITextSelection的接口指針。
hr = pDispatch->QueryInterface(IID_ITextSelection, (void**)pTextSelection);
if (FAILED(hr))
{
pDispatch->Release();
return E_NOINTERFACE;
}
pDispatch->Release();

}
else
return E_NOINTERFACE;
return S_OK;
}

上面的方法已經(jīng)解決了這兩個問題,接下來的任務(wù)就是實現(xiàn)注釋被選中的代碼。請參閱下面的代碼(省略了錯誤處理的部分代碼)
HRESULT CCommands::CommentSelectedCode(ITextSelection *pTextSelection)
{
long lTopLine = -1;
long lBottomLine = -1;
long lCurLine;
long lCurColumn;
//取得被選中文本的最上面一行的行號
HRESULT hr = pTextSelection->get_TopLine(&lTopLine);
//取得被選中文本的最下面一行的行號
hr = pTextSelection->get_BottomLine(&lBottomLine);

long iLine;
CString s;
_variant_t v((long)dsMove);
//循環(huán),針對選中的每一行,在前面加上VC的單行注釋//
for(iLine = lTopLine; iLine <= lBottomLine; iLine++)
{
hr = pTextSelection->MoveTo(iLine, 1, v);
if (SUCCEEDED(hr))
{
pTextSelection->SelectLine();
BSTR bstrLineText;
hr = pTextSelection->get_Text(&bstrLineText);
if (SUCCEEDED(hr))
{
s = bstrLineText;
s = _T("http://") + s;
pTextSelection->put_Text(s.AllocSysString());
}
}
}
return S_OK;
}

上面的代碼就完成了對選中的代碼的注釋問題,下面添加對選中的代碼的反注釋功能,其中的代碼大體相同,這里主要講解如何間命令添加到VC的開發(fā)環(huán)境中去。
在ClassView中右鍵單擊ICommands接口,選擇Add method...,添加UncommentCode方法,參照上面的代碼實現(xiàn)相應(yīng)的功能。
打開CDSAddIn類的OnConnection方法,在添加CommentCode方法的下面添加下面的代碼:
szCommand = _T("UncommentCode");
strCmdString.LoadString(IDS_CMD_UNCOMMENT);
strCmdString = szCommand + strCmdString;
bszCmdString = strCmdString;
bszMethod = _T("UncommentCode");
CComBSTR bszCmdUncommentName = szCommand;
VERIFY_OK(pApplication->AddCommand(bszCmdString, bszMethod, 1, m_dwCookie, &bRet));

然后在OnConnection()方法的下面的代碼中
if (bFirstTime == VARIANT_TRUE)
{
VERIFY_OK(pApplication->AddCommandBarButton(dsGlyph, bszCmdName, m_dwCookie));
}
添加一行,如下面的代碼
if (bFirstTime == VARIANT_TRUE)
{
VERIFY_OK(pApplication->AddCommandBarButton(dsGlyph, bszCmdName, m_dwCookie));
VERIFY_OK(pApplication->AddCommandBarButton(dsGlyph, bszCmdUncommentName, m_dwCookie));
}
在上面的pApplication->AddCommand()調(diào)用中,第三個參數(shù)1,指定了該命令所對應(yīng)的圖像在位圖資源中的位置。

適當?shù)男拚こ痰馁Y源,完成的應(yīng)用程序應(yīng)該可以完成VB,PowerBuilder中的代碼的注釋和反注釋功能。

另外,由于VC中的插件是通過COM技術(shù)實現(xiàn)的,所以能支持COM規(guī)范的語言都可以用來編寫VC插件。

本文來自CSDN博客,轉(zhuǎn)載請標明出處:http://blog.csdn.net/panbinfeng/archive/2006/04/17/666816.aspx

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国内成+人亚洲| 艳妇臀荡乳欲伦亚洲一区| 欧美在线视屏| 国产精品多人| 亚洲精品乱码久久久久久蜜桃91| 国产精品视频一二三| 日韩视频中文字幕| 一区二区欧美国产| 亚洲视频1区| 欧美精品国产精品| 亚洲国产美女久久久久| 亚洲精品欧洲| 欧美视频在线观看 亚洲欧| 日韩视频中文字幕| 羞羞色国产精品| 国产主播一区二区三区四区| 香蕉久久夜色| 欧美性大战久久久久| 亚洲欧洲一区二区在线观看| 亚洲免费成人av| 国产精品日本精品| 午夜综合激情| 9i看片成人免费高清| 亚洲一区久久久| 国产一区二区三区在线免费观看 | 欧美日韩一区二区在线观看| 一本到高清视频免费精品| 欧美在线视频a| 99成人免费视频| 一区二区在线视频| 国产精品久久久久久久9999| 欧美一区二区三区在线播放| 亚洲精品在线观| 91久久精品日日躁夜夜躁欧美 | 欧美日韩在线看| 久久久一本精品99久久精品66| 亚洲电影网站| 国内精品写真在线观看| 欧美日韩在线免费| 欧美日韩国产首页在线观看| 亚洲精品乱码久久久久久久久| 国产日韩欧美成人| 国产精品自拍视频| 国产农村妇女毛片精品久久麻豆| 欧美va亚洲va国产综合| 久久综合久色欧美综合狠狠| 久久久欧美精品| 久久精品欧美日韩精品| 久久久久久久久久久成人| 欧美一区二区视频97| 欧美一区二区黄色| 久久―日本道色综合久久| 乱中年女人伦av一区二区| 免费日韩成人| 国产精品成人观看视频免费| 国产欧美日韩视频一区二区| 国户精品久久久久久久久久久不卡 | 国产日本欧美一区二区| 国产一区二区福利| 亚洲精品免费在线播放| 亚洲香蕉伊综合在人在线视看| 午夜免费久久久久| 亚洲第一页在线| 亚洲视频碰碰| 欧美二区不卡| 国产日韩亚洲欧美精品| 亚洲精品国产精品乱码不99按摩| 久久青草福利网站| 国产精品久久久久久久久免费樱桃| 国产精品腿扒开做爽爽爽挤奶网站| 国产一级揄自揄精品视频| 亚洲午夜久久久久久久久电影院| 久久国产直播| 香蕉久久夜色精品| 欧美日韩一区二区三区四区五区| 亚洲美女电影在线| 噜噜噜91成人网| 亚洲精品之草原avav久久| 久热成人在线视频| 久久大逼视频| 黄色在线成人| 久久午夜电影网| 性18欧美另类| 极品尤物久久久av免费看| 久久精品一级爱片| 久久全国免费视频| 亚洲人成人99网站| 日韩亚洲在线| 国产在线拍偷自揄拍精品| 麻豆91精品91久久久的内涵| 久久亚洲电影| 亚洲欧美日韩一区| 激情久久久久久久| 亚洲国产导航| 国产精品视频第一区| 久久中文字幕导航| 免费在线观看成人av| 99精品国产福利在线观看免费| 这里只有视频精品| 亚洲大片精品永久免费| 亚洲国产精选| 国产亚洲综合性久久久影院| 亚洲一区免费观看| 欧美激情亚洲一区| 欧美日韩国产在线播放| 国产精品一区免费在线观看| 亚洲第一久久影院| 欧美在现视频| 亚洲人成网站999久久久综合| 中文国产成人精品久久一| 久久综合九九| 国产精品久久久久久久午夜| 91久久午夜| 久久夜色精品国产亚洲aⅴ| 99精品欧美一区| 欧美高清在线播放| 韩日成人av| 久久精品观看| 亚洲综合色在线| 欧美日产一区二区三区在线观看 | 欧美亚洲一区二区在线| 亚洲激情视频| 另类专区欧美制服同性| 国产一区在线视频| 午夜免费久久久久| 最新国产成人在线观看| 欧美专区中文字幕| 亚洲婷婷综合久久一本伊一区| 欧美国产日韩免费| 亚洲日本中文字幕| 亚洲国产婷婷| 欧美大尺度在线| 亚洲裸体视频| 欧美激情片在线观看| 蜜桃久久精品乱码一区二区| 一区免费视频| 麻豆91精品91久久久的内涵| 久久久福利视频| 在线日韩日本国产亚洲| 欧美成人精品h版在线观看| 久久久久免费观看| 亚洲精品影视| 一区二区三区日韩精品视频| 欧美日韩精品在线| 亚洲一区免费观看| 亚洲免费福利视频| 欧美日韩中文在线观看| 亚洲欧美日韩一区| 亚洲欧美国产制服动漫| 国产精品日韩一区二区三区| 亚洲一区视频| 欧美成人在线免费视频| 久久久久青草大香线综合精品| 国产一本一道久久香蕉| 性欧美激情精品| 午夜精品视频网站| 久久爱另类一区二区小说| 久久www成人_看片免费不卡| 亚洲激情女人| 亚洲一区国产视频| 亚洲第一精品影视| 一区二区三区高清在线观看| 国产欧美91| 亚洲国产精品久久久久秋霞不卡| 欧美日韩在线视频首页| 久久网站免费| 欧美日韩1区| 欧美在线播放一区| 欧美激情导航| 久久久精品一品道一区| 欧美高清在线播放| 久久女同精品一区二区| 欧美日韩精品免费观看视一区二区| 久久精品123| 欧美午夜精品理论片a级按摩| 亚洲乱码视频| 亚洲视频专区在线| 亚洲国产高潮在线观看| 亚洲色图制服丝袜| 亚洲国产欧美日韩| 亚洲免费综合| 99re8这里有精品热视频免费| 亚洲综合清纯丝袜自拍| 日韩视频免费观看高清完整版| 香港久久久电影| 亚洲永久精品大片| 欧美精品国产一区| 蜜桃久久av一区| 国产欧美精品国产国产专区| 亚洲激情成人| 亚洲电影第1页| 午夜国产精品视频免费体验区| 亚洲美女av在线播放| 久久超碰97人人做人人爱| 亚洲视频播放| 欧美金8天国| 欧美激情一区二区久久久| 狠狠色香婷婷久久亚洲精品 | 亚洲天堂第二页| 亚洲免费视频在线观看|