📄 shortcut.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 + -