分享
 
 
 

在CPP文件中自动添加函数注释的ADDIN

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

当公司要求你用统一的格式写函数注释时,这个小东西也许可以帮些忙。

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("//------------------------------------------------\r\n");

m_szEnd = _T("//------------------------------------------------\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("// 名称:") + szName + _T("\r\n");

}

void CCmtBlock::ExtractPurpose()

{

CString szTemp = m_szPurpose;

m_szPurpose = _T("// 功能:") + 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("// 参数:无\r\n");

return;

}

m_szParam = _T("// 参数:");

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("// [") + 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("// 返回:") + 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("// 作者:") + 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("//");

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有