`

支持代码完成和函数提示

阅读更多

支持代码完成和函数提示

来自http://www.cppprog.com/2009/1111/176_4.html

VS的代码完成和函数提示功能是很值得称道的,它们可以极大地提高我们的编程效率(造成我现在写代码时往往只记住前四个字母,如果在对象后面点了小数点后不出现提示就会心慌意乱的说-_-),尽管有时也会失效。

做为IDE这个功能是绝对不能少D。即使你只打算做个编辑器,如果有这个功能那也是一大亮点啊~~(目前很多代码编辑器都没这个功能的说)。

关于函数提示的几个命令以SCI_CALLTIP作为前缀,这里只介绍我们即将使用的几个命令(更多命令见:http://scintilla.sourceforge.net/ScintillaDoc.html#CallTips

  • SCI_CALLTIPSHOW(int posStart, const char *definition) 显示提示。posStart表示显示位置,definition是显示的内容
  • SCI_CALLTIPCANCEL 取消提示
  • SCI_CALLTIPACTIVE 如果当前编辑器中有提示信息,返回1,否则返回0
  • SCI_CALLTIPSETHLT(int highlightStart, int highlightEnd) 设置提示中的高亮位置,在VS里我们输入函数实参时函数提示会高亮当前输入的参数名。

在我们程序中加入提示的最佳时机是SCN_CHARADDED(见上一节)事件。当用户输入左圆括号'('时,取得括号左边的函数名,然后显示出该函数的完整定义。

下面的代码实现了CreateWindow和MoveWindow两个API的函数提示

  1. //我们要高亮的两个函数
  2. const size_t FUNCSIZE=2;
  3. char* g_szFuncList[FUNCSIZE]={ //函数名
  4.     "CreateWindow(",
  5.     "MoveWindow("
  6. };
  7. char* g_szFuncDesc[FUNCSIZE]={ //函数信息
  8.     "HWND CreateWindow("
  9.     "LPCTSTR lpClassName,"
  10.     " LPCTSTR lpWindowName,"
  11.     " DWORD dwStyle, "
  12.     " int x,"
  13.     " int y,"
  14.     " int nWidth,"
  15.     " int nHeight, "
  16.     " HWND hWndParent,"
  17.     " HMENU hMenu,"
  18.     " HANDLE hInstance,"
  19.     " PVOID lpParam"
  20.     ")",
  21.     "BOOL MoveWindow("
  22.     "HWND hWnd,"
  23.     " int X,"
  24.     " int Y,"
  25.     " int nWidth,"
  26.     " int nHeight,"
  27.     " BOOL bRepaint"
  28.     ")"
  29. };
  30. void __fastcall TForm1::WndProc(Messages::TMessage &Message)
  31. {
  32.     TForm::WndProc(Message);
  33.     if(Message.Msg == WM_NOTIFY)
  34.     {
  35.         SCNotification* notify = (SCNotification*)Message.LParam;
  36.         ...
  37.         if(notify->nmhdr.code == SCN_CHARADDED)
  38.         {
  39.             ...
  40.             // 函数提示功能
  41.             static const char* pCallTipNextWord = NULL;//下一个高亮位置
  42.             static const char* pCallTipCurDesc = NULL;//当前提示的函数信息
  43.             if(notify->ch == '('//如果输入了左括号,显示函数提示
  44.             {
  45.                 char word[1000]; //保存当前光标下的单词(函数名)
  46.                 TextRange tr;    //用于SCI_GETTEXTRANGE命令
  47.                 int pos = SendEditor(SCI_GETCURRENTPOS); //取得当前位置(括号的位置)
  48.                 int startpos = SendEditor(SCI_WORDSTARTPOSITION,pos-1);//当前单词起始位置
  49.                 int endpos = SendEditor(SCI_WORDENDPOSITION,pos-1);//当前单词终止位置
  50.                 tr.chrg.cpMin = startpos;  //设定单词区间,取出单词
  51.                 tr.chrg.cpMax = endpos;
  52.                 tr.lpstrText = word;
  53.                 SendEditor(SCI_GETTEXTRANGE,0, sptr_t(&tr));
  54.                 
  55.                 for(size_t i=0; i<FUNCSIZE; i++) //找找有没有我们认识的函数?
  56.                 {
  57.                     if(memcmp(g_szFuncList[i],word,sizeof(g_szFuncList[i])) == 0)
  58.                     {     //找到啦,那么显示提示吧
  59.                         pCallTipCurDesc = g_szFuncDesc[i]; //当前提示的函数信息
  60.                         SendEditor(SCI_CALLTIPSHOW,pos,sptr_t(pCallTipCurDesc));//显示这个提示
  61.                         const char *pStart = strchr(pCallTipCurDesc,'(')+1; //高亮第一个参数
  62.                         const char *pEnd = strchr(pStart,',');//参数列表以逗号分隔
  63.                         if(pEnd == NULL) pEnd = strchr(pStart,')');//若是最后一个参数,后面是右括号
  64.                         SendEditor(SCI_CALLTIPSETHLT,
  65.                             pStart-pCallTipCurDesc, pEnd-pCallTipCurDesc);
  66.                         pCallTipNextWord = pEnd+1;//指向下一参数位置
  67.                         break;
  68.                     }
  69.                 }
  70.             }
  71.             else if(notify->ch == ')'//如果输入右括号,就关闭函数提示
  72.             {
  73.                 SendEditor(SCI_CALLTIPCANCEL);
  74.                 pCallTipCurDesc = NULL;
  75.                 pCallTipNextWord = NULL;                
  76.             }
  77.             else if(notify->ch == ',' && SendEditor(SCI_CALLTIPACTIVE) && pCallTipCurDesc)
  78.             {
  79.                 //输入的是逗号,高亮下一个参数
  80.                 const char *pStart = pCallTipNextWord;
  81.                 const char *pEnd = strchr(pStart,',');
  82.                 if(pEnd == NULL) pEnd = strchr(pStart,')');
  83.                 if(pEnd == NULL) //没有下一个参数啦,关闭提示
  84.                     SendEditor(SCI_CALLTIPCANCEL);
  85.                 else
  86.                 {
  87.                     SendEditor(SCI_CALLTIPSETHLT,pStart-pCallTipCurDesc, pEnd-pCallTipCurDesc);
  88.                     pCallTipNextWord = pEnd+1;
  89.                 }
  90.             }
  91.         }//if(notify->nmhdr.code == SCN_CHARADDED)
  92.         ...
  93.     }//if(Message.Msg == WM_NOTIFY)
  94. }

当然,这个提示功能相当山寨啦。比如函数名和括号之间有空格提示就不出来了,函数嵌套调用时只会提示最后一个函数的参数。关于如果改进,大家各显神通吧。

另外,还有一个提外话,在实际的使用中,我们的函数信息不可能象这里一样是写死的,而是依据用户的输入动态生成的函数名及信息列表。这就涉及到一个C++代码解析的问题(还好,只要解析函数声明就行了),对于这一点,牛X的同学可以自己写解析代码;次牛X的可以考虑用WAVE,Spirit,Regex等库帮助解析;象偶这种不牛的同学,则可以考虑利用CTAGS工具在后台线程中生成tag文件,我们从tag文件里取就可以了(当然,效率嘛~~可以参考C++Builder的函数提示效率-_-)。

代码完成和函数提示的用法类似,前缀是SCI_AUTOC,具体命令见:http://scintilla.sourceforge.net/ScintillaDoc.html#Autocompletion

直接上代码:

  1. void __fastcall TForm1::WndProc(Messages::TMessage &Message)
  2. {
  3.     TForm::WndProc(Message);
  4.     if(Message.Msg == WM_NOTIFY)
  5.     {
  6.         ...
  7.         if(notify->nmhdr.code == SCN_CHARADDED)
  8.         {
  9.             ...
  10.             if(notify->ch == '.')
  11.             {
  12.                 char word[1000]; //保存当前光标下的单词
  13.                 TextRange tr;    //用于SCI_GETTEXTRANGE命令
  14.                 int pos = SendEditor(SCI_GETCURRENTPOS); //取得当前位置
  15.                 int startpos = SendEditor(SCI_WORDSTARTPOSITION,pos-1);//当前单词起始位置
  16.                 int endpos = SendEditor(SCI_WORDENDPOSITION,pos-1);//当前单词终止位置
  17.                 tr.chrg.cpMin = startpos;  //设定单词区间,取出单词
  18.                 tr.chrg.cpMax = endpos;
  19.                 tr.lpstrText = word;
  20.                 SendEditor(SCI_GETTEXTRANGE,0, sptr_t(&tr));
  21.                 if(strcmp(word,"file.") == 0) //输入file.后提示file对象的几个方法
  22.                 {
  23.                     SendEditor(SCI_AUTOCSHOW,0,
  24.                         sptr_t(
  25.                             "close "
  26.                             "eof "
  27.                             "good "
  28.                             "open "
  29.                             "rdbuf "
  30.                             "size"
  31.                         ));
  32.                 }
  33.             }
  34.             ...

SCI_AUTOCSHOW命令的第一个参数表示已经输入了多少个字符。这对于代码自动完成是很有帮助的,比如我们可以用它帮助用户输入长串的单词,如:

  1. if(strcmp(word,"Create") == 0)
  2. {
  3.     SendEditor(SCI_AUTOCSHOW,6,//已经输入了6位字符
  4.         sptr_t(
  5.             "CreateBitmap "
  6.             "CreateDC "
  7.             "CreateHandle "
  8.             "CreateWindow "
  9.             "CreateWindowEx"
  10.         ));
  11. }

 

分享到:
评论

相关推荐

    代码编辑器(支持自动缩进,语法高亮,代码折叠,函数提示,行号显示)

    2.支持代码折叠功能,如下 void f() { } 3.支持自动代码缩进 int main() { while(true) { printf("great"); } } 4.支持行号显示,如程序左显示 5.支持函数参数自动提示功能,...

    vb6的AutoCode代码提示代码自动完成

    在编程过程中,代码提示和自动完成功能对于提高开发效率至关重要。"vb6的AutoCode代码提示代码自动完成"是一个针对VB6.0的插件,它增强了原生IDE的功能,帮助开发者快速输入代码。 AutoCode是这个插件的名字,它的...

    代码智能提示,代码联想,代码自动完成,AutoComplete源码参考

    代码自动完成是基于智能提示和联想的进一步扩展,它能够在编写代码的过程中自动插入完整的语句或块。例如,当你开始输入一个常见的函数或方法时,IDE会自动填充剩余的部分。在Delphi中,这种功能对于频繁使用的VCL...

    Excel自定义函数智能提示插件及示例

    在默认情况下,Excel不会为自定义函数提供自动完成或参数提示。但有了这个插件,当你在单元格中输入自定义函数时,它会像内置函数那样显示函数名、参数列表以及简短的描述,帮助用户更快地理解和使用自定义函数。这...

    曾几何时IAR也开始支持函数智能提示了

    IAR编程环境智能提示功能是指IAR从某个版本开始支持代码自动补全和参数提示功能,这个功能可以帮助开发者快速完成代码编写,提高开发效率。在本文中,我们将对IAR编程环境智能提示功能进行详细介绍,并提供详细的...

    java 代码提示 首字母 提示

    4. **代码模板(Code Templates)**: 除了首字母提示外,许多IDE还支持自定义代码模板,允许开发者为常见的代码片段设置快捷方式。例如,“sout”可以快速插入System.out.println()语句。 5. **Javadoc提示**: 当你...

    VC++代码提示工具

    4. **重构支持**:强大的代码提示工具往往包含代码重构功能,如重命名变量、提取方法等,这些操作可以保持代码的整洁和一致性。 5. **文档提示**:在选择函数或类时,工具通常会显示其使用说明和参数信息,无需离开...

    VS2010代码提示插件VissualAssist

    Visual Assist是针对Visual Studio的一个非常受欢迎的第三方代码提示和增强插件,它极大地提升了开发者的编程效率。 Visual Assist插件在Visual Studio 2010中的主要功能包括: 1. **智能感知增强**:Visual ...

    Code Composer Studio代码提示辅助软件

    在编程过程中,这种智能代码提示不仅限于基本的变量和函数名,还包括系统库中的函数、特定API、自定义的宏定义等。此外,它还支持多语言,比如C、C++以及特定的嵌入式语言。通过与KeyBoardHook.dll这样的动态链接库...

    51CTO下载-EditPlus代码提示

    4. **代码折叠**:除了代码提示,EditPlus还支持代码折叠,这对于处理大型代码文件非常有用。可以隐藏不需立即查看的部分,让代码结构更加清晰,方便阅读和编辑。 5. **颜色高亮**:EditPlus可以根据不同的语法结构...

    vs2008代码提示软件

    6. **Visual Assist X**:压缩包中的"Visual_Assist_X_V10.5.1715_Cracked"是一个第三方插件,它扩展了VS2008的代码提示和智能辅助功能,提供了更多的语言支持、更高效的代码补全和自定义设置,使编程更加便捷。...

    vim代码提示、系统调用提示、文件浏览器等

    它不仅包含基本的关键词补全,还支持函数、变量和类的补全。而`neocomplete`则是一个轻量级的替代方案,它能够与许多其他Vim插件无缝集成,提供类似的功能。 系统调用提示是另一个提升开发效率的重要特性。例如,`...

    代码提示编辑器

    这款编辑器集成了代码收藏和智能提示功能,帮助开发者在编写代码时能够快速定位和插入所需的代码片段。 首先,让我们深入了解一下“代码收藏”这一特性。它允许开发者将常用的代码段、函数或者API保存成收藏,便于...

    vue加载完成后的回调函数方法

    上述代码的意图是,在Vue实例被挂载到DOM后,立即执行一个alert()函数来提示“vue加载完成”。然而,根据代码的格式,它看起来有一点错误。实际上,mounted应该是一个函数而不是一个对象。正确的用法应该是: ```...

    visual_assist vs代码提示助手

    Visual Assist提供了智能感知(IntelliSense)功能,它能够根据上下文自动完成代码,包括类名、函数名、变量名等,极大地减少了手动输入的时间。不仅如此,它还支持自定义代码模板,使得编写常见的代码结构变得快速...

    VS2008的JavaScript代码提示功能

    随着JavaScript的发展,更新的Visual Studio版本会不断改进这些特性,提供更强大的代码提示和调试工具。 在提供的压缩包文件“ASP.NET AJAX深入浅出系列课程(19):VS 2008的JavaScript代码提示功能”中,你可能会...

    Sql代码智能提示工具 智能工具

    Sql代码智能提示工具是数据库开发人员的得力助手,它极大地提升了编写SQL语句的效率和准确性。在本文中,我们将深入探讨此类工具的核心功能、重要性以及如何使用。 首先,Sql代码智能提示工具通常具备以下特性: 1...

    让MyEclipse与VS一样-----代码提示功能

    4. **自定义模板**:MyEclipse支持自定义代码模板,通过“Window”-&gt;“Preferences”-&gt;“Java”-&gt;“Code Style”-&gt;“Code Templates”可以创建自己的代码片段,比如常用的构造函数、循环、异常处理等,这样在编写...

    VS2010番茄插件 代码提示 VAssistX

    VAssistX是一款针对Microsoft Visual Studio 2010的强大代码提示和增强插件,它为开发者提供了丰富的代码补全、智能感知以及代码导航功能,极大地提高了开发效率。该插件尤其适用于那些寻求更高效编程体验的C++...

    SQL代码提示插件(SQL Assistant)

    SQL代码提示插件,如"SQL Assistant",是数据库开发者和管理员的重要工具,尤其是在处理Microsoft SQL Server (MSSQL)时。这款插件为用户提供了一种高效的方式来进行SQL查询编写,通过提供类似PL/SQL Developer中的...

Global site tag (gtag.js) - Google Analytics