设为首页 加入收藏

TOP

编程实现自定义系统右键菜单功能
2014-11-23 21:26:51 】 浏览:4187
Tags:编程 实现 定义 系统 菜单 功能

  一、前言


  在 Windows 的资源管理器窗口中,我们见过 WinZIP,WinRAR 等软件能在文件或文件夹的默认快捷菜单中添加几个菜单项,它可以使用户无须进入软件内部而直接在视窗中进行压缩/解压操作,十分方便用户操作,这无疑是一个较好的应用模型,它就是我们所说的Shell扩展技术。本文将以一个普通的源代码统计程序为例来说明怎样实现Shell扩展技术。


  二、实现原理


  为了在Windows的任何视窗中扩展文件或文件夹的默认菜单,我们必须使Windows在显示快捷菜单加载我们的程序段,一般我们利用COM组件来达到这个目的。COM组件分为三种:进程内服务程序,本地服务程序,以及远程服务程序。要想让explorer加载并执行我们的代码,当然得使用进程内服务程序,它的表现形式是 DLL, DLL在加载后被映射到可执行程序的虚拟地址空间,我们向explorer提供一些接口,explorer将在显示快捷菜单时调用它们时,我们可以在那些接口中做一些我们想做的事,如添加快捷菜单,实现菜单项功能等等,从而实现Shell扩展了。


  至于源代码统计,则不难实现。这里我以C/C++风格的源代码为例,并应用一种最简单的统计规则,当统计文件时,我们将代码内容读入缓存,判断每一个字符是否为换行符(\n),若是,计数加1。当然我们是对文件夹进行统计更有意义,所以我们可以使用递归的方法遍历文件夹内所有文件,找出有效文件 (这里我仅统计C/C++程序,所以只处理后缀名为.C、.CPP、.H 的文件),根据前面的方法一一统计即可求出文件夹内所有代码的总行数。


  三、实现过程


  1.新建一个VC工程,选定ATL COM AppWizard类型,工程起名为SrcCount,进入下一步;


  2.选择服务类型为DLL(默认选项)即可,这里不需要MFC支持(若加入MFC支持的话,编写代码时会方便些,但程序失去ATL短小精悍的特点了,熊掌与鱼不可兼得:)),进入下一步;


  3.现在会显示工程的配置信息,我们按确定按钮后就建立一个ATL COM组件了。


  4.我们现在加入一个组件对象,在工程的快捷菜单上选择New ATL Object…,在随后的对话框中的种类中选择Simple Object,单击下一步,在“Short Name”中填写CountLines,Attributes属性页中按默认选项,单击确定按钮。我们可以在VC的工作区里看到已添加一个接口 ICountLines。


  5.为该接口添加方法,在接口的快捷菜单上按右键,选择Add method…,方法名为GetFileLines,它的参数分别为:[in]BSTR *pFilePath, [out]int *lines。它的作用是统计源代码文件的行数。下面是代码的主要实现部分:


  //////////////////////////////////////////////////////////////////////////////////////////////////////////


  // 作用:获取源文件的代码行数


  // 参数:1. pFilePath :输入参数,指定源文件的路径;


  //2. lines:输出参数,获得源文件的代码行数。


  STDMETHODIMP CCountLines::GetFileLines(BSTR *pFilePath, int *lines) {


  // 存放代码的总行数


  int totalLine = 0;


  // 打开文件


  HANDLE hFile = CreateFile((TCHAR *)pFilePath, GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);


  if ((HANDLE)-1 == hFile)


  {


  *lines = -1;


  return S_FALSE;


  }


  // 开辟缓冲区存放文件内容


  DWORD dwFileSize = GetFileSize(hFile, NULL);


  BYTE *lpBuffer = new BYTE[dwFileSize];


  memset(lpBuffer, 0, dwFileSize);


  DWORD dwRead = 0;


  BOOL bReadFile = ReadFile(hFile, lpBuffer, dwFileSize, &dwRead, NULL);


  assert(bReadFile && dwRead == dwFileSize);


  // 我们这里仅用一个简单的统计规则,即以换行符(‘\n’)为一行代码结束的标记


  for (unsigned i = 0; i < dwFileSize; i++)


  {


  if (lpBuffer[i] == ''\n'')


  {


  totalLine++;


  }


  }


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇高质量程序设计指南:strcpy的实现 下一篇C语言基础(02-数据类型、运算符与..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目