⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shortcut.cpp

📁 The code for this article was written for version 1.0 of the Active Template Library (ATL). The cu
💻 CPP
字号:
// ShortCut.cpp : Implementation of CShortCutSvrApp and DLL registration.

#include "stdafx.h"
#include "ShortCutSvr.h"
#include "ShortCut.h"

// Provided by wizard
HRESULT CShortCut::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_IShortCut,
	};

	for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
	{
		if (InlineIsEqualGUID(*arr[i],riid))
			return S_OK;
	}
	return S_FALSE;
}

// Constructor creates IShellLink and IPersistFile object pointers
CShortCut::CShortCut()
{
	m_bsLink = NULL;
	m_pLink = NULL;
	HRESULT hr = CoCreateInstance(
					CLSID_ShellLink, 
					NULL,
					CLSCTX_INPROC_SERVER,
					IID_IShellLink, 
					(void **)&m_pLink);
	if (hr != S_OK) {
		Error("Can't create shortcut");
	}
	hr = m_pLink->QueryInterface(
					IID_IPersistFile,
				  	(void **)&m_pPersist);
	if (hr != S_OK) {
		Error("Can't make persistent");
	}
}

// Destructor destroys object pointers
CShortCut::~CShortCut()
{
	m_pLink->Release();
	m_pLink = NULL;
	m_pPersist = NULL;
	SysFreeString(m_bsLink);
}


// Properties

// Path of file represented by shortcut
HRESULT CShortCut::get_Path(BSTR * pbsRet)
{	
	WIN32_FIND_DATA fd;
	TCHAR tsz[MAX_PATH];
	Load();
	HRESULT hr = m_pLink->GetPath(tsz, MAX_PATH, &fd, 0);
	if (!SUCCEEDED(hr)) {
		*pbsRet = T2BSTR(NULL);
		return Error("Path get failed");
	}
	*pbsRet = T2BSTR(tsz);
	
	return hr;		
}
HRESULT CShortCut::put_Path(BSTR bs)
{	
	USES_CONVERSION;

	// Make sure file exists
	if (_taccess(W2CT(bs), 0)) {
		return Error("File not found");
	}
	HRESULT hr = m_pLink->SetPath(W2CT(bs));
	if (!SUCCEEDED(hr)) {
		return Error("Path set failed");
	}
	return hr;		
}
       
// Location of .LNK file. Output is always full path of .LNK file
// Type is Variant so that Input can be one of the following:
//		edstDesktop		- Put on desktop
//		edstCurrent		- Put in current directory
//		edstPath		- Put in same directory as target file
//		[directory]		- Put in hardcoded path
//		[file.LNK]		- Put in hardcoded file
HRESULT CShortCut::get_Location(VARIANT * pvRet)
{
	pvRet->vt = VT_BSTR;
	pvRet->bstrVal = SysAllocString(m_bsLink);
	return S_OK;		
}
HRESULT CShortCut::put_Location(VARIANT v)
{
	USES_CONVERSION;
	TCHAR tsz[MAX_PATH];
	TCHAR * ptch = NULL;
	DWORD ctch = 0;

	// Get the file the shortcut points to for later use
	BSTR bs = NULL;
	HRESULT hr = get_Path(&bs);
	DWORD cwch = SysStringLen(bs);

	// If user passes in string, save it internally
	if (v.vt == VT_BSTR) {
		// Can't use a location that doesn't exist
		if (_taccess(W2CT(v.bstrVal), 0)) {
			return Error("Location set failed");
		}
		// Convert to a full path
		ctch = GetFullPathName(W2CT(v.bstrVal), MAX_PATH, tsz, &ptch);

		// If this is already a link file, return it
		if (_tcsicmp(tsz + ctch - 4, _T(".LNK")) == 0) {
			m_bsLink = SysAllocString(T2BSTR(tsz));
			return S_OK;

		// Make sure directory ends with backslash
		} else if (tsz[_tcslen(tsz) - 1] != '\\') {
			_tcscat(tsz, _T("\\"));
		}
	} else {
	
		// Rather than fail for invalid entry, convert to default
		if (v.vt != VT_I4) {
			HRESULT hr = VariantChangeType(&v, &v, 0, VT_I4);
			if (v.lVal > edstPath) {
				v.lVal = edstDesktop;
			}
		}

		// Create a directory from setting
		switch (v.lVal) {
		case edstCurrent:
			// Current directory
			ctch = GetCurrentDirectory(MAX_PATH, tsz);
			break;

		case edstPath:
			// Directory of shortcut target
			ctch = GetFullPathName(W2CT(bs), MAX_PATH, tsz, &ptch);
			*(ptch - 1) = _T('\0');
			break;

		case edstDesktop:
		default:
			// Desktop directory 
			GetDeskTop(tsz);
			break;
		}
		// Append backslash
		_tcscat(tsz, _T("\\"));
	}
	
	// Can't set location before path
	if (cwch == 0) {
		return Error("Must set Path first");
	}

	// Find the base name and concat it onto the directory
	for (LPWSTR pwch = bs + cwch - 1; pwch > bs; pwch--) {
		if ((*pwch == L'\\') || (*pwch == L':')) {
			break;
		}
	}
	_tcscat(tsz, W2CT(pwch + 1));
	// Cut off the extension and replace it with ".LNK"
	for (ptch = tsz + _tcslen(tsz) - 1; ptch > tsz; ptch--) {
		if (*ptch == TCHAR('.')) {
			*ptch = TCHAR(0);
			break;
		}
	}
	_tcscat(tsz, _TEXT(".LNK"));

	// Save the whole mess as a BSTR
	m_bsLink = SysAllocString(T2CW(tsz));
	return S_OK;
}         

// Startup directory for shortcut target 
HRESULT CShortCut::get_WorkingDirectory(BSTR * pbsRet)
{	
	TCHAR tsz[MAX_PATH];

	Load();
	HRESULT hr = m_pLink->GetWorkingDirectory(tsz, MAX_PATH);
	if (!SUCCEEDED(hr)) {
		*pbsRet = T2BSTR(NULL);
		return Error("WorkingDirectory get failed");
	}
	*pbsRet = T2BSTR(tsz);
	return hr;		
}
HRESULT CShortCut::put_WorkingDirectory(BSTR bs)
{	
	USES_CONVERSION;
	
	HRESULT hr = m_pLink->SetWorkingDirectory(W2CT(bs));
	if (!SUCCEEDED(hr)) {
		return Error("WorkingDirectory set failed");
	}
	return hr;		
}
    
// Arguments for shortcut target     
HRESULT CShortCut::get_Arguments(BSTR * pbsRet)
{	
	TCHAR tsz[MAX_PATH];

	Load();
	HRESULT hr = m_pLink->GetArguments(tsz, MAX_PATH);
	if (!SUCCEEDED(hr)) {
		*pbsRet = T2BSTR(NULL);
		return Error("Arguments get failed");
	}
	*pbsRet = T2BSTR(tsz);
	return hr;		
}
HRESULT CShortCut::put_Arguments(BSTR bs)
{	
	USES_CONVERSION;
	
	HRESULT hr = m_pLink->SetArguments(W2CT(bs));
	if (!SUCCEEDED(hr)) {
		return Error("Arguments set failed");
	}
	return hr;		
}
         
// Display command can be Normal, Minimized, or Maximized
HRESULT CShortCut::get_ShowCommand(long * pi)
{	

	Load();
	HRESULT hr = m_pLink->GetShowCmd((int *)pi);
	if (!SUCCEEDED(hr)) {
		*pi = -1;
		return Error("ShowCommand get failed");
	}
	return hr;		
}
HRESULT CShortCut::put_ShowCommand(long i)
{	
	// IShellLink claims to handle all SW_ constants, but
	// we'll convert these to make them work
	switch (i) {
	case SW_HIDE:				// 0
	case SW_NORMAL:				// 1
	case SW_SHOWNOACTIVATE:		// 4
	case SW_SHOW:				// 5
	case SW_SHOWNA:				// 8
	case SW_RESTORE:			// 9
	case SW_SHOWDEFAULT:		// 10
	default:
		// Convert all these to normal
		i = eswNormal;
		break;
	case SW_SHOWMINIMIZED:		// 2
	case SW_MINIMIZE:			// 6
	case SW_SHOWMINNOACTIVE:	// 7  
		// Convert all these to minimized
		i = eswMinimized;		
		break;
	case SW_MAXIMIZE:			// 3
		// Pass maximize through
		i = eswMaximized;		
		break;
	}

	HRESULT hr = m_pLink->SetShowCmd((int)i);
	if (!SUCCEEDED(hr)) {
		return Error("ShowCommand set failed");
	}
	return hr;		
}

HRESULT CShortCut::Save(short fRemember)
{
	// If no destination, assume desktop
	if (m_bsLink == NULL) {
		VARIANT v;
		v.vt = VT_I4;
		v.lVal = edstDesktop;
		put_Location(v);
	}

	// Save the object to disk
	HRESULT hr = m_pPersist->Save(m_bsLink, (BOOL)fRemember);
	if (!SUCCEEDED(hr)) {
		hr = Error("Save failed");
		return FALSE;
	}
	return hr;		
}

HRESULT CShortCut::Resolve(long hWnd, 
						   BSTR bsFile, 
						   BSTR * pbsRet)
{
	USES_CONVERSION;

	TCHAR tsz[MAX_PATH];	

	// Load from LNK file and resolve
	HRESULT hr = m_pPersist->Load(bsFile, 0);
	if (SUCCEEDED(hr)) {
		hr = m_pLink->Resolve(HWND(hWnd), SLR_ANY_MATCH);
		if (SUCCEEDED(hr)) {
			hr = m_pLink->GetPath(tsz, MAX_PATH, NULL, 0);
		}
		// Make resolve file the location
		VARIANT v;
		v.vt = VT_BSTR;
		v.bstrVal = SysAllocString(bsFile);
		hr = put_Location(v);
		*pbsRet = T2BSTR(tsz);
	} else {
		*pbsRet = T2BSTR(NULL);
	}
	
	return hr;		
}

void CShortCut::GetDeskTop(LPCTSTR ptch)
{
	BOOL f;
	HKEY hKey;
	f = RegOpenKey(HKEY_CURRENT_USER, 
		           _T("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"), 
				   &hKey);
	unsigned long iType, c;
    f = RegQueryValueEx(hKey, _T("Desktop"), NULL, &iType, NULL, &c);
    if (c != 0) {
        f = RegQueryValueEx(hKey, _T("Desktop"), NULL, &iType, LPBYTE(ptch), &c);
    }
    RegCloseKey(hKey);
}

void CShortCut::Load()
{
	// Read the object from disk
	if (m_bsLink != NULL) {
		HRESULT hr = m_pPersist->Load(m_bsLink, 0);
		if (!SUCCEEDED(hr)) {
			hr = Error("Load failed");
		}
	}
}

⌨️ 快捷键说明

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