编程实现自定义系统右键菜单功能
来源:优易学  2010-1-14 12:17:17   【优易学:中国教育考试门户网】   资料下载   IT书店

  一、前言

  在 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++;

  }

  }

[1] [2] [3] 下一页

责任编辑:cyth

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训