http://www.moon-soft.com/doc/7553.htm
當公司要求你用統一的格式寫函數注釋時,這個小東西也許可以幫些忙。
ma2jun@sina.com
設計目標:
1. 自動提取函數名稱;2. 自動提取函數功能注釋(假設在頭文件中);3. 自動列出參數列表;4.自動提取返回值;5.自動填寫作者及日期(作者名稱可以設置)
例如:
//------------------------------------------------
// 名稱:CDSAddIn::OnConnection
// 功能:
// 參數:[IApplication* pApp] ---
//?????? [VARIANT_BOOL bFirstTime] ---
//?????? [long dwCookie] ---
//?????? [VARIANT_BOOL* OnConnection] ---
// 返回:STDMETHODIMP ---
// 作者:麻軍? 2002-3-4
//------------------------------------------------
STDMETHODIMP CDSAddIn::OnConnection(IApplication* pApp, VARIANT_BOOL bFirstTime, long dwCookie, VARIANT_BOOL* OnConnection)
設計思想:
1. 使用IDSAddIn接口;2. 設計CCmtBlock(COMMENT BLOCK)類維護注釋中的各個字段,用來提供擴展靈活性。
實現:
//-----------------------------------------------------------------------------------------------------
// CmtBlock.h: interface for the CCmtBlock class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_CMTBLOCK_H__51B4002A_A935_4764_80B5_03103D5E716E__INCLUDED_)
#define AFX_CMTBLOCK_H__51B4002A_A935_4764_80B5_03103D5E716E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <vector>
class CCmtBlock?
{
public:
?CCmtBlock();
?~CCmtBlock();
private:
?CString m_szBegin;?????? // 注釋首行(hard coded)
?CString m_szName;??????? // 函數名稱(auto)
?CString m_szPurpose;???? // 函數功能(auto)
?CString m_szParam;?????? // 函數參數列表(auto)
?CString m_szReturn;????? // 函數返回(can change)
?CString m_szAuthor;????? // 函數作者(auto)
?CString m_szEnd;???????? // 注釋尾行(hard coded)
?CString m_szFuncDefine;? // 函數定義(自動獲得)
//?CString m_szBlock;?????? // 函數注釋塊
?std::vector< CString* > m_arrSort;? // 注釋部分的排列順序
private:
?void ExtractName();????? // 提取名稱
?void ExtractPurpose();?? // 提取功能
?void ExtractParam();???? // 提取參數列表
?void ExtractReturn();??? // 提取返回類型
?void ComposeAuthorAndDate(); // 編輯作者和日期時間
public:
?void SetFunctionDefine( CString szFuncDefine );?? // 設置函數定義(自動獲得)
?CString ComposeComment();?? // 編輯函數注釋
?void SetPurpose( CString& szFuncPurpose ) {
??m_szPurpose = szFuncPurpose; }? // 設置函數頭文件中的注釋
};
#endif // !defined(AFX_CMTBLOCK_H__51B4002A_A935_4764_80B5_03103D5E716E__INCLUDED_)
//-----------------------------------------------------------------------------------------------------
// CmtBlock.cpp: implementation of the CCmtBlock class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "AutoComment.h"
#include "CmtBlock.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CCmtBlock::CCmtBlock()
{
?m_szBegin = _T("http://------------------------------------------------\r\n");
?m_szEnd?? = _T("http://------------------------------------------------\r\n");
?m_arrSort.clear();
?m_arrSort.push_back( &m_szBegin );
?m_arrSort.push_back( &m_szName );
?m_arrSort.push_back( &m_szPurpose );
?m_arrSort.push_back( &m_szParam );
?m_arrSort.push_back( &m_szReturn );
?m_arrSort.push_back( &m_szAuthor );
?m_arrSort.push_back( &m_szEnd );
}
CCmtBlock::~CCmtBlock()
{
?m_arrSort.clear();
}
void CCmtBlock::ExtractName()
{
?int iPosSpace = m_szFuncDefine.FindOneOf(_T(" "));
?int iPosBracket = m_szFuncDefine.FindOneOf(_T("("));
?CString szName = m_szFuncDefine.Mid( iPosSpace, iPosBracket-iPosSpace );
?szName.TrimLeft();
?szName.TrimRight();
?m_szName = _T("http:// 名稱:") + szName + _T("\r\n");
}
void CCmtBlock::ExtractPurpose()
{
?CString szTemp = m_szPurpose;
?m_szPurpose = _T("http:// 功能:") + szTemp + _T("\r\n");
}
void CCmtBlock::ExtractParam()
{
?// 得到參數表
?int iPosLeftBracket = m_szFuncDefine.FindOneOf(_T("("));
?int iPosRightBracket = m_szFuncDefine.ReverseFind(_T(')'));
?CString szParamTable = m_szFuncDefine.Mid( iPosLeftBracket+1, iPosRightBracket-iPosLeftBracket-1 );
?// 分解參數
?// 判斷是否具有參數
?szParamTable.TrimLeft();
?szParamTable.TrimRight();
?if( szParamTable == _T("") )
?{
??// 沒有參數
??m_szParam = _T("http:// 參數:無\r\n");
??return;
?}
?m_szParam = _T("http:// 參數:");
?int iPos1 = 0;
?int iPos2 = 0;
?CString szOneParam = _T("");
?CString szOneLine;
?int iLineCount = 0;
?szParamTable += _T(",");
?while( ( iPos2 = szParamTable.Find( _T(','), iPos1 ) ) != -1 )
?{
??iLineCount++;
??// 找到參數
??szOneParam = szParamTable.Mid( iPos1, iPos2-iPos1 );
??szOneParam.TrimLeft();
??szOneParam.TrimRight();
??if( iLineCount == 1 )
???szOneLine = _T("[") + szOneParam + _T("] --- ");
??else
???szOneLine = _T("http://?????? [") + szOneParam + _T("] --- ");
??szOneLine += _T("\r\n");
??// 添加到函數列表上
??m_szParam += szOneLine;
??iPos1 = iPos2 + 1;
?}
//?::MessageBox( NULL, szParamTable, NULL, MB_OK );
}
void CCmtBlock::ExtractReturn()
{
?CString szRet = m_szFuncDefine.Mid( 0, m_szFuncDefine.FindOneOf( _T(" ") ) );
?m_szReturn = _T("http:// 返回:") + szRet + _T(" --- \r\n");
}
extern CString g_szAuthor;? // 作者名稱
void CCmtBlock::ComposeAuthorAndDate()
{
?CString szAuthor = g_szAuthor;//_T("Author");
?COleDateTime& date = COleDateTime::GetCurrentTime();
?CString szDate = date.Format( VAR_DATEVALUEONLY );
?m_szAuthor = _T("http:// 作者:") + szAuthor + _T("? ") + szDate + _T("\r\n");
}
void CCmtBlock::SetFunctionDefine( CString szFuncDefine )
{
?m_szFuncDefine = szFuncDefine;
}
CString CCmtBlock::ComposeComment()
{
?ExtractName();????? // 提取名稱
?ExtractPurpose();?? // 提取功能
?ExtractParam();???? // 提取參數列表
?ExtractReturn();??? // 提取返回類型
?ComposeAuthorAndDate(); // 編輯作者和日期時間
?CString szBlock = _T("");
?for( int i=0;i<m_arrSort.size();i++)
??szBlock += *m_arrSort[i];
?return szBlock;
}
//-----------------------------------------------------------------------------------------------------
AutoCommentCommandMethod 函數是ADDIN向導自動建立的那個函數
/////////////////////////////////////////////////////////////////////////////
// CCommands methods
STDMETHODIMP CCommands::AutoCommentCommandMethod()
{
?AFX_MANAGE_STATE(AfxGetStaticModuleState());
?// TODO: Replace this with the actual code to execute this command
?//? Use m_pApplication to access the Developer Studio Application object,
?//? and VERIFY_OK to see error strings in DEBUG builds of your add-in
?//? (see stdafx.h)
//?VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE));
//?::MessageBox(NULL, "AutoComment Command invoked.", "AutoComment", MB_OK | MB_ICONINFORMATION);
//?VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE));
?// 得到當前文檔
?CComPtr<IDispatch> pDispActDocument = NULL;
?m_pApplication->get_ActiveDocument( &pDispActDocument );
?if( !pDispActDocument )
??return E_FAIL;
?CComQIPtr< ITextDocument, &IID_ITextDocument > pDoc( pDispActDocument );
?// 得到選擇對象
?CComPtr< IDispatch > pDispSelection;
?pDoc->get_Selection( &pDispSelection );
?if( !pDispSelection )
??return E_FAIL;
?CComQIPtr< ITextSelection, &IID_ITextSelection > pSelection( pDispSelection );
?// 得到函數定義(假設光標插在函數定義中)
?//??? -- 尋找的標志是:頭(NewLine),尾({)>> 將來實現
?// 選擇函數定義的第一行
?CComBSTR bstrFuncDefine;
?pSelection->SelectLine();
?pSelection->get_Text( &bstrFuncDefine );
?// 將光標插入行的起始位置
?VARIANT var1,var2;
?VariantInit( &var1 );
?VariantInit( &var2 );
?pSelection->StartOfLine( var1, var2 );
?if( bstrFuncDefine.Length() == 0 )
??return E_FAIL;? // 不是函數定義
?USES_CONVERSION;
?CString szFuncDefine = W2A(bstrFuncDefine);
?m_CmtBlock.SetFunctionDefine( szFuncDefine );
?// 找到頭文件中函數定義的注釋
?CString& szFuncComm = FindFunctionPurposeInHeader( szFuncDefine );
?m_CmtBlock.SetPurpose( szFuncComm );
?// 構成函數注釋字符串
?CString szBlock = m_CmtBlock.ComposeComment();
?BSTR bstrBlock;
?bstrBlock = A2W( szBlock );
?pSelection->put_Text( bstrBlock );
?return S_OK;
}
CString CCommands::FindFunctionPurposeInHeader( CString& szDefine )
{
?CString szRet;
?// 得到當前文檔
?CComPtr<IDispatch> pDispActDocument = NULL;
?m_pApplication->get_ActiveDocument( &pDispActDocument );
?if( !pDispActDocument )
??return "";
?CComQIPtr< ITextDocument, &IID_ITextDocument > pDoc( pDispActDocument );
?if( !pDoc )
??return "";
?// 得到函數名稱
?CString szFuncName;
?int iPosSpace = szDefine.FindOneOf(_T(":"));
?int iPosBracket = szDefine.FindOneOf(_T("("));
?szFuncName = szDefine.Mid( iPosSpace+2, iPosBracket-iPosSpace-2 );
?szFuncName.TrimLeft();
?szFuncName.TrimRight();
?// 打開對應的.h文件
?CComBSTR bstrFullName;
?pDoc->get_FullName( &bstrFullName );
?CString szFullName( bstrFullName );
?szFullName.MakeLower();
?CString szExt = szFullName.Right( 3 );
?if( szExt != "cpp" )?? // 不是.cpp
??return "";
?szFullName.TrimRight( "cpp" );
?szFullName += "h";? // 轉換成.h
?CStdioFile file;
?if( !file.Open( szFullName, CFile::modeRead ) )
??return "";
?CString szLine;
?CString szPurpose;
?int pos;
?while( file.ReadString( szLine ) )
?{
??// 檢查每一行是否有函數名稱
??if( (pos=szLine.Find( szFuncName )) != -1 )
??{
???// 檢查szFuncName的前后字符是否為空格and'('
???// 構造一個字符串在szFuncName的前后個加一個字符
???CString szTemp = szLine.Mid( pos-1, szFuncName.GetLength()+2 );
???if( szTemp.Left(1) != " " ||
????( szTemp.Right(1) != " " && szTemp.Right(1) != "(" ) )
????szRet = "";
???else
???{
????// 找到函數聲明
????// 查看當前行的末尾有沒有注釋
????int posSplash = 0;
????if( ( posSplash = szLine.ReverseFind( '/' ) ) != -1 )
?????szRet = szLine.Right( szLine.GetLength() - posSplash - 1 );
????else
????{
?????// 查看下一行有沒有注釋
?????if( file.ReadString( szLine ) )
?????{
??????szLine.TrimLeft();
??????szLine.TrimRight();
??????if( szLine.Left(1) == "/" )
??????{
???????// 有注釋
???????szLine.TrimLeft("http://");
???????szRet = szLine;
??????}
??????else
???????szRet = "";
?????}
?????else
??????szRet = "";
????}
???}
??}
?}
?file.Close();
?szRet.TrimRight();
?szRet.TrimLeft();
?return szRet;
}
//-----------------------------------------------------------------------------------------------
// 在CDSAddIn::OnConnection函數中改寫以下代碼,注意:CParamDlg 類是一個輸入作者名稱的對話框類
?if (bFirstTime == VARIANT_TRUE)
?{
??VERIFY_OK(pApplication->
???AddCommandBarButton(dsGlyph, bszCmdName, m_dwCookie));
??// 第一次使用讓用戶輸入姓名
??CParamDlg dlgParam;
??if( dlgParam.DoModal() == IDOK )
??{
???g_szAuthor = dlgParam.m_szAuthor;
???// 存入注冊表
???::WriteProfileString("DSAddIn_AutoComment","Author",g_szAuthor);
??}
?}
?else
?{
??char szAuthor[255];
??::GetProfileString("DSAddIn_AutoComment","Author","Author",szAuthor,sizeof(szAuthor));
??g_szAuthor = CString(szAuthor);
?}
//-------------------------------------------------------------------------------------------------
希望大家能提出寶貴意見 :-)
Ma Jun -----? ma2jun@sina.com? Jurassic xian corp.
感謝Kamp Huang給這個東東找了個家:
http://wsdnorgtypeb.51.net/kamp/zip/AutoComment.rar