在应用程序中创建快捷方式

发表于:2007-07-01来源:作者:点击数: 标签:
1.引言 在Windows 3.x中,软件安装程序通常使用动态数据交换(DDE)的方法在程序管理器(Program Manager)中创建一个程序组(Program Group)。随着Windows95/98/NT这些32操作系统在系统内核和用户界面上的巨大改进,这种方法在已经不再适用了。现在,几乎所有的


1.引言
  在Windows 3.x中,软件安装程序通常使用动态数据交换(DDE)的方法在程序管理器(Program Manager)中创建一个程序组(Program Group)。随着Windows95/98/NT这些32操作系统在系统内核和用户界面上的巨大改进,这种方法在已经不再适用了。现在,几乎所有的安装程序都是在“开始”菜单中添加新的菜单项,或者在桌面上建立新的快捷方式(Shortcut)(有时还要建立相应的菜单组或文件夹来包含多个菜单项或快捷方式),以便于用户使用时方便快捷地启动软件。
  通过手工操作建立这些菜单项或快捷方式并不复杂,在一般Windows使用手册中都有介绍,相信大家都很熟悉,在此不再赘述。笔者在有关资料的基础上,通过实践摸索,找到了在应用程序中完成上述工作的方法。这正是开发安装程序所必需的。

2.快捷方式的实质

  Windows的快捷方式实际上是一个带有扩展名LNK的数据文件,其中包含有用于访问Windows某一对象(即在资源管理器中所能浏览的所有对象,包括文件,文件夹,驱动器及打印机等)的有关信息,如目标对象的路径和名称,工作目录,要传递的命令行参数,运行时的初始显示状态,图标及其快捷键等。通过在快捷方式上单击鼠标右键并在弹出菜单中选择“属性”可以观察该快捷方式的这些性质。

  快捷方式的数据文件如果存放在C:\Windows\Desktop子目录下,这个快捷方式就会显示在桌面上,而如果存放在C:\Windows\”Start Menu”下面为建立该程序后需添加的代码(方框内部分):

// SortCut.cpp :

BOOL CSortCutApp::InitInstance()

{  ......  

  CoInitialize (NULL);

  CSortCutDlg dlg;

  m_pMainWnd = &dlg;

  ......

  CoUninitialize ();

  return FALSE;

}

// SortCutDlg.cpp :

#include "stdafx.h"

#include "SortCut.h"

#include "SortCutDlg.h"



#include "NameDlg.h"



#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif



//起始文件夹的PIDL

int nBeginAt=CSIDL_DESKTOPDIRECTORY;

......

///浏览文件夹

BOOL BrowseForFolder(

  LPITEMIDLIST pidlRoot,//浏览开始处的PIDL

  LPITEMIDLIST *ppidlDestination,

        //浏览结束时所选择的PIDL

  LPCSTR lpszTitle)//浏览对话框中的提示文字

{  BROWSEINFO BrInfo ;



  ZeroMemory( &BrInfo, sizeof(BrInfo)) ;

  BrInfo.hwndOwner = HWND_DESKTOP ;

  BrInfo.pidlRoot = pidlRoot ;

  BrInfo.lpszTitle = lpszTitle ;



  //浏览文件夹

  *ppidlDestination= SHBrowseForFolder(&BrInfo);

  //用户选择了取消按钮

  if(NULL == *ppidlDestination)

    return FALSE ;

  return TRUE ;

}

//取得快捷方式的目标应用程序名

SelectMenuItem( LPSTR szFileName)

{

  OPENFILENAME ofn ;

  static CHAR szFilter[] = "Programs\0*.exe\0" ;



  ZeroMemory(&ofn, sizeof( OPENFILENAME)) ;

  ofn.lStructSize = sizeof( OPENFILENAME) ;

  ofn.hwndOwner = HWND_DESKTOP;

  ofn.lpstrFilter = szFilter ;

  ofn.nFilterIndex = 0 ;

  ofn.nMaxFile = MAX_PATH ;

  ofn.lpstrTitle = "请选择目标应用程序:" ;

  ofn.lpstrFile = szFileName ;

  ofn.Flags = OFN_FILEMUSTEXIST |

      OFN_PATHMUSTEXIST | OFN_EXPLORER ;

  //文件浏览

  if(!GetOpenFileName( &ofn))//选择了取消按钮

    return FALSE ;

  return TRUE ;

}

//取得要创建的快捷方式的名字

BOOL GetShortcutCrt(LPSTR szPath)

{

  LPITEMIDLIST pidlBeginAt, pidlDestination ;

  

  // 取得开始菜单或桌面的PIDL

  SHGetSpecialFolderLocation( HWND_DESKTOP,

        nBeginAt, &pidlBeginAt) ;

  // 取得要创建的快捷方式所在的位置

  if( !BrowseForFolder(pidlBeginAt,             &pidlDestination,

        "请选择快捷方式所在的位置:"))

    return FALSE ;

  // 把PIDL转换为路径名

  SHGetPathFromIDList( pidlDestination, szPath) ;

  // 取得快捷方式名称

  CNameDlg name_dlg;

  if(name_dlg.DoModal() == IDCANCEL)  

    return FALSE ;

  //把快捷方式名和扩展名.LNK添加到路径名后

  //形成完整的快捷方式数据文件名

  wsprintf(szPath+lstrlen(szPath),"\\%s.lnk",

        name_dlg.m_strName) ;

  return TRUE ;

}

//创建快捷方式

BOOL CreateLink (

  LPSTR szPath,//快捷方式的目标应用程序名

  LPSTR szLink)//快捷方式的数据文件名(*.lnk)

{

HRESULT hres ;

IShellLink * psl ;

IPersistFile* ppf ;

WORD wsz[ MAX_PATH] ;

  //创建一个IShellLink实例

  hres = CoCreateInstance( CLSID_ShellLink, NULL,

    CLSCTX_INPROC_SERVER, IID_IShellLink,

    (void **)&psl) ;

if( FAILED( hres))

    return FALSE ;

  //设置目标应用程序

  psl -> SetPath( szPath) ;

  //设置快捷键(此处设为Shift+Ctrl+@#R@#)

  psl -> SetHotkey( MAKEWORD( @#R@#,

      HOTKEYF_SHIFT |HOTKEYF_CONTROL)) ;

  //从IShellLink获取其IPersistFile接口

  //用于保存快捷方式的数据文件 (*.lnk)

  hres = psl -> QueryInterface( IID_IPersistFile,

      (void**)&ppf) ;

if( FAILED( hres))

    return FALSE ;

// 确保数据文件名为ANSI格式

MultiByteToWideChar( CP_ACP, 0, szLink, -1,

      wsz, MAX_PATH) ;

  //调用IPersistFile::Save

  //保存快捷方式的数据文件 (*.lnk)

hres = ppf -> Save( wsz, STGM_READWRITE) ;

  //释放IPersistFile和IShellLink接口

ppf -> Release( ) ;

psl -> Release( ) ;

return TRUE;

}

//删除文件夹

BOOL DeleteFolder( LPSTR pszFolder)

{

  SHFILEOPSTRUCT fos ;

  

  ZeroMemory( &fos, sizeof( fos)) ;

  fos.hwnd = HWND_DESKTOP;

  fos.wFunc = FO_DELETE ;

  fos.fFlags = FOF_SILENT | FOF_ALLOWUNDO ;

  fos.pFrom = pszFolder ;



  // 删除文件夹及其内容

  if( 0 != SHFileOperation( &fos))

    return FALSE ;

  return TRUE;

}

//取得要删除的快捷方式

BOOL GetShortcutDel (

    LPSTR lpszInitDir,//选择文件的开始目录

    LPSTR lpszShortcut)//快捷方式名

{

  OPENFILENAME ofn ;

  char szFilter[] = "Shortcuts\0*.lnk\0" ;



  ZeroMemory(&ofn,sizeof( OPENFILENAME));

  ofn.lStructSize = sizeof( OPENFILENAME) ;

  ofn.hwndOwner = HWND_DESKTOP ;

  ofn.lpstrFilter = szFilter ;

  ofn.nFilterIndex = 0 ;

  ofn.nMaxFile = MAX_PATH ;

  ofn.lpstrTitle = "请选择要删除的快捷方式:" ;

  ofn.lpstrFile = lpszShortcut;

  ofn.lpstrInitialDir = lpszInitDir ;

  ofn.Flags = OFN_FILEMUSTEXIST |

    OFN_PATHMUSTEXIST | OFN_EXPLORER |

    OFN_NODEREFERENCELINKS ;

  //文件浏览

  if(! GetOpenFileName( &ofn))//选择了取消按钮

    return FALSE ;

  return TRUE ;

}

//删除快捷方式的数据文件 (*.lnk)

BOOL DeleteLink( LPSTR lpszShortcut)

{

  SHFILEOPSTRUCT fos ;



  ZeroMemory( &fos, sizeof(fos)) ;

  fos.hwnd = HWND_DESKTOP ;

  fos.wFunc = FO_DELETE ;

  fos.pFrom = lpszShortcut;

  fos.pTo = NULL ;

  fos.fFlags = FOF_SILENT | FOF_ALLOWUNDO ;

  //删除快捷方式(*.lnk)

  if( 0 != SHFileOperation( &fos))

    return FALSE ;

  return TRUE ;

}

// 通知shell有关变化

void NotifyShell(LONG wEventId,//事件标志

      LPSTR szPath)//路径

{  

  SHChangeNotify( wEventId,

          SHCNF_FLUSH | SHCNF_PATH,

          szPath,0);

  //取得szPath的父目录

  char* p;

  for( p=szPath+lstrlen(szPath)-1;

      *p != @#\\@#;

      p--);

  *p=@#\0@#;

  SHChangeNotify(SHCNE_UPDATEDIR

      |SHCNE_INTERRUPT,

      SHCNF_FLUSH | SHCNF_PATH,szPath,0);

}

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

// CSortCutDlg dialog

CSortCutDlg::CSortCutDlg(CWnd* pParent /*=NULL*/)

  : CDialog(CSortCutDlg::IDD, pParent)

{

  //{{AFX_DATA_INIT(CSortCutDlg)

  //把圆形按钮“桌面”设为选中状态

  m_nLocation = 0;

  ……

}

原文转自:http://www.ltesting.net