shelllink.cpp

来自「2 Freeware MFC classes to encapsulate sh」· C++ 代码 · 共 665 行 · 第 1/2 页

CPP
665
字号
/*
Module : SHELLLINK.CPP
Purpose: Implementation for an MFC class encapsulation of IShellLink
Created: PJN / 09-12-1998
History: PJN / 12-12-1998 1. Fixed a bug in CUrlShellLink::Save where m_sTarget was not being set.
                          2. Updated the trace comments in the code to include the function from 
                          which the function fails.
                          
Copyright (c) 1998 by PJ Naughter.  
All rights reserved.

*/

//////////////// Includes ////////////////////////////////////////////
#include "stdafx.h"
#include "ShellLink.h"
#define INITGUID
#include <initguid.h>
#include <shlguid.h>



//////////////// Macros / Locals /////////////////////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


//////////////// Implementation //////////////////////////////////////

CShellLinkInfo::CShellLinkInfo()
{
  //Set up some reasonable defaults
  m_pidl = NULL;
  m_wHotkey = 0;
  m_nIconIndex = 0;
  m_nShowCmd = SW_SHOW;
}

CShellLinkInfo::CShellLinkInfo(const CShellLinkInfo& sli)
{
  *this = sli;
}

CShellLinkInfo::~CShellLinkInfo()
{
  // Get the shell's allocator. 
  IMalloc* pMalloc;
  HRESULT hRes = SHGetMalloc(&pMalloc);
  if (!SUCCEEDED(hRes)) 
  {
    TRACE(_T("CShellLinkInfo::~CShellLinkInfo, Failed to get the shell's IMalloc interface, HRESULT was %x\n"), hRes);
    return;
  }

  //Free the pidl
  if (m_pidl)
  {
    pMalloc->Free(m_pidl);
    m_pidl = NULL;
  }

  // Release the pointer to IMalloc
  pMalloc->Release(); 
}

CShellLinkInfo& CShellLinkInfo::operator=(const CShellLinkInfo& sli)
{
  m_sTarget = sli.m_sTarget;
  m_pidl = sli.m_pidl;
  m_sArguments = sli.m_sArguments;
  m_sDescription = sli.m_sDescription;
  m_wHotkey = sli.m_wHotkey;
  m_sIconLocation = sli.m_sIconLocation;
  m_nIconIndex = sli.m_nIconIndex;
  m_nShowCmd = sli.m_nShowCmd;
  m_sWorkingDirectory = sli.m_sWorkingDirectory;

  return *this;
}

#ifdef _DEBUG
void CShellLinkInfo::Dump(CDumpContext& dc)
{
  CObject::Dump(dc);

  dc << _T("\nm_sTarget = ") << m_sTarget
     << _T("\nm_pidl = ") << m_pidl
     << _T("\nm_sArguments = ") << m_sArguments
     << _T("\nm_sDescription = ") << m_sDescription
     << _T("\nm_wHotkey = ") << m_wHotkey
     << _T("\nm_sIconLocation = ") << m_sIconLocation
     << _T("\nm_nIconIndex = ") << m_nIconIndex
     << _T("\nm_nShowCmd = ") << m_nShowCmd
     << _T("\nm_sWorkingDirectory = ") << m_sWorkingDirectory;
}
#endif


CShellLink::CShellLink()
{
  m_psl = NULL;
  m_ppf = NULL;
  m_bAttemptedInitialise = FALSE;
}

CShellLink::~CShellLink()
{
  if (m_ppf)
    m_ppf->Release();
  if (m_psl)
    m_psl->Release();
}

BOOL CShellLink::Initialise()
{
  BOOL bSuccess = FALSE;
  if (m_bAttemptedInitialise)
    bSuccess = (m_psl != NULL);
  else
  {
    //Instantiate the COM class
    HRESULT hRes = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*) &m_psl);
    if (SUCCEEDED(hRes))
    {
      //Also get a pointer to IPersistFile
      hRes = m_psl->QueryInterface(IID_IPersistFile, (LPVOID*) &m_ppf);
      bSuccess = SUCCEEDED(hRes);
      if (!bSuccess)
        TRACE(_T("CShellLink::Initialise, Failed in call to QueryInterface for IPersistFile, HRESULT was %x\n"), hRes);        
    }
    else
      TRACE(_T("CShellLink::Initialise, Failed in call to CoCreateInstance for IShellLink, HRESULT was %x\n"), hRes);

    m_bAttemptedInitialise = TRUE;
  }

  return bSuccess;
}

BOOL CShellLink::Create(const CShellLinkInfo& sli)
{
  if (!Initialise())
    return FALSE;

  m_sli = sli;

  return TRUE;
}

BOOL CShellLink::Save(const CString& sFilename)
{
  if (!Initialise())
    return FALSE;

  //Validate our parameters
  if (m_sli.m_pidl == NULL)
    ASSERT(!m_sli.m_sTarget.IsEmpty());
  ASSERT(!sFilename.IsEmpty());
  ASSERT(m_psl);
  ASSERT(m_ppf);

  BOOL bSuccess = FALSE;
  HRESULT hRes;

  //Convert the path to a UNICODE string
  WCHAR wszPath[MAX_PATH];
#ifndef _UNICODE
  ::MultiByteToWideChar(CP_ACP, 0, sFilename, -1, wszPath, MAX_PATH);
#else
  _tcscpy(wszPath, sFilename);
#endif

  //Set the various link values
  if (m_sli.m_pidl)
  {
    hRes = m_psl->SetIDList(m_sli.m_pidl);
    if (!SUCCEEDED(hRes))
      TRACE(_T("CShellLink::Save, Failed in call to IShellLink::SetIDList, HRESULT was %x\n"), hRes);
  }
  else
  {
    hRes = m_psl->SetPath(m_sli.m_sTarget);
    if (!SUCCEEDED(hRes))
      TRACE(_T("CShellLink::Save, Failed in call to IShellLink::SetPath, HRESULT was %x\n"), hRes);
  }

  hRes = m_psl->SetWorkingDirectory(m_sli.m_sWorkingDirectory);
  if (!SUCCEEDED(hRes))
    TRACE(_T("CShellLink::Save, Failed in call to IShellLink::SetWorkingDirectory, HRESULT was %x\n"), hRes);

  hRes = m_psl->SetIconLocation(m_sli.m_sIconLocation, m_sli.m_nIconIndex);
  if (!SUCCEEDED(hRes))
    TRACE(_T("CShellLink::Save, Failed in call to IShellLink::SetIconLocation, HRESULT was %x\n"), hRes);

  hRes = m_psl->SetDescription(m_sli.m_sDescription);
  if (!SUCCEEDED(hRes))
    TRACE(_T("CShellLink::Save, Failed in call to IShellLink::SetDescription, HRESULT was %x\n"), hRes);

  hRes = m_psl->SetArguments(m_sli.m_sArguments);
  if (!SUCCEEDED(hRes))
    TRACE(_T("CShellLink::Save, Failed in call to IShellLink::SetArguments, HRESULT was %x\n"), hRes);

  hRes = m_psl->SetHotkey(m_sli.m_wHotkey);
  if (!SUCCEEDED(hRes))
    TRACE(_T("CShellLink::Save, Failed in call to IShellLink::SetHotkey, HRESULT was %x\n"), hRes);

  hRes = m_psl->SetShowCmd(m_sli.m_nShowCmd);
  if (!SUCCEEDED(hRes))
    TRACE(_T("CShellLink::Save, Failed in call to IShellLink::SetShowCmd, HRESULT was %x\n"), hRes);

  //Save the link to file
  hRes = m_ppf->Save(wszPath, TRUE);
  if (SUCCEEDED(hRes))
    bSuccess = TRUE;
  else
    TRACE(_T("CShellLink::Save, Failed in call to IPersistFile::Save, HRESULT was %x\n"), hRes);

  return bSuccess;
}

BOOL CShellLink::Load(const CString& sFilename)
{
  if (!Initialise())
    return FALSE;

  //Validate our parameters
  ASSERT(!sFilename.IsEmpty());
  ASSERT(m_psl);
  ASSERT(m_ppf);

  BOOL bSuccess = FALSE;

  //Convert the path to a UNICODE string
  WCHAR wszPath[MAX_PATH];
#ifndef _UNICODE
  ::MultiByteToWideChar(CP_ACP, 0, sFilename, -1, wszPath, MAX_PATH);
#else
  _tcscpy(wszPath, sFilename);
#endif

  //Load the link from file
  HRESULT hRes = m_ppf->Load(wszPath, STGM_READ);
  if (SUCCEEDED(hRes))
  {
    //Get the various link values
    TCHAR szBuf[_MAX_PATH];
    WIN32_FIND_DATA fd;

    hRes = m_psl->GetPath(szBuf, _MAX_PATH, &fd, SLGP_UNCPRIORITY);
    if (SUCCEEDED(hRes))
      m_sli.m_sTarget = szBuf;
    else
      TRACE(_T("CShellLink::Load, Failed in call to IShellLink::GetPath, HRESULT was %x\n"), hRes);

    hRes = m_psl->GetIDList(&m_sli.m_pidl);
    if (!SUCCEEDED(hRes))
      TRACE(_T("CShellLink::Load, Failed in call to IShellLink::GetIDList, HRESULT was %x\n"), hRes);

    hRes = m_psl->GetWorkingDirectory(szBuf, _MAX_PATH);
    if (SUCCEEDED(hRes))
      m_sli.m_sWorkingDirectory = szBuf;
    else
      TRACE(_T("CShellLink::Load, Failed in call to IShellLink::GetWorkingDirectory, HRESULT was %x\n"), hRes);

    hRes = m_psl->GetIconLocation(szBuf, _MAX_PATH, &m_sli.m_nIconIndex);
    if (SUCCEEDED(hRes))
      m_sli.m_sIconLocation = szBuf;
    else
      TRACE(_T("CShellLink::Load, Failed in call to IShellLink::GetIconLocation, HRESULT was %x\n"), hRes);

    hRes = m_psl->GetDescription(szBuf, _MAX_PATH);
    if (SUCCEEDED(hRes))            
      m_sli.m_sDescription = szBuf;
    else
      TRACE(_T("CShellLink::Load, Failed in call to IShellLink::GetDescription, HRESULT was %x\n"), hRes);

    hRes = m_psl->GetArguments(szBuf, _MAX_PATH);
    if (SUCCEEDED(hRes))
      m_sli.m_sArguments = szBuf;
    else
      TRACE(_T("CShellLink::Load, Failed in call to IShellLink::GetArguments, HRESULT was %x\n"), hRes);

    hRes = m_psl->GetHotkey(&m_sli.m_wHotkey);
    if (!SUCCEEDED(hRes))
      TRACE(_T("CShellLink::Load, Failed in call to IShellLink::GetHotkey, HRESULT was %x\n"), hRes);

    hRes = m_psl->GetShowCmd(&m_sli.m_nShowCmd);
    if (!SUCCEEDED(hRes))
      TRACE(_T("CShellLink::Load, Failed in call to IShellLink::GetShowCmd, HRESULT was %x\n"), hRes);

    bSuccess = TRUE;
  }
  else
    TRACE(_T("CShellLink::Load, Failed in call to IPersistFile::Load, HRESULT was %x\n"), hRes);

  return bSuccess;
}

BOOL CShellLink::Resolve(CWnd* pParentWnd, DWORD dwFlags)
{
  if (!Initialise())
    return FALSE;

  //Validate our parameters
  ASSERT(!m_sli.m_sTarget.IsEmpty());
  ASSERT(m_psl);
  ASSERT(m_ppf);

  BOOL bSuccess = FALSE;

  //Do the actual link resolve
  HWND hWnd = NULL;
  if (pParentWnd)
    hWnd = pParentWnd->GetSafeHwnd();
  HRESULT hRes = m_psl->Resolve(hWnd, dwFlags);

  if (SUCCEEDED(hRes))
    bSuccess = TRUE;
  else
    TRACE(_T("CShellLink::Resolve, Failed in call to IShellLink::Resolve, HRESULT was %x\n"), hRes);

  return bSuccess;
}

CString CShellLink::GetPath() const
{
  return m_sli.m_sTarget;
}

CString CShellLink::GetArguments() const

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?