如何用C++与WinAPI调用创建快捷方式的标准对话框
实现调用Windows标准创建快捷方式对话框
你已经可以通过C++结合WinAPI直接创建快捷方式,现有代码如下:
#include "windows.h" #include "winnls.h" #include "shobjidl.h" #include "objbase.h" #include "objidl.h" #include "shlguid.h" #include <iostream> HRESULT CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc) { HRESULT hres; IShellLink* psl; // 获取IShellLink接口指针,需确保已调用CoInitialize hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; // 设置快捷方式目标路径和描述 psl->SetPath(lpszPathObj); psl->SetDescription(lpszDesc); // 查询IPersistFile接口,用于保存快捷方式 hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); if (SUCCEEDED(hres)) { WCHAR wsz[MAX_PATH]; // 转换为Unicode字符串 MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH); // 保存快捷方式 hres = ppf->Save(wsz, TRUE); ppf->Release(); } psl->Release(); } return hres; } int main() { CoInitialize(NULL); std::wstring sourceFile = L"C:\\path\\to\\source\\file.txt"; std::string linkName = "C:\\path\\to\\file.lnk"; std::cout << CreateLink(sourceFile.c_str(), linkName.c_str(), L""); CoUninitialize(); return 0; }
一、弹出系统「新建快捷方式」向导对话框
这个对话框就是资源管理器中「新建→快捷方式」的引导界面,会让用户输入目标路径、快捷方式名称,最终自动完成创建。实现代码如下:
#include "windows.h" #include "shobjidl.h" #include "objbase.h" int main() { HRESULT hr = CoInitialize(NULL); if (SUCCEEDED(hr)) { // 创建IShellLink接口实例 IShellLink* pShellLink = nullptr; hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&pShellLink); if (SUCCEEDED(hr)) { // 获取IContextMenu接口 IContextMenu* pContextMenu = nullptr; hr = pShellLink->QueryInterface(IID_IContextMenu, (void**)&pContextMenu); if (SUCCEEDED(hr)) { // 触发新建快捷方式命令 CMINVOKECOMMANDINFOEX info = {0}; info.cbSize = sizeof(CMINVOKECOMMANDINFOEX); info.fMask = CMIC_MASK_DEFAULT; info.lpVerb = L"new"; info.hwnd = GetDesktopWindow(); hr = pContextMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)&info); pContextMenu->Release(); } pShellLink->Release(); } CoUninitialize(); } return 0; }
二、弹出标准保存对话框选择快捷方式路径
如果需要先让用户选择快捷方式的保存位置和名称,再用现有代码创建,可以使用以下两种实现:
方法1:使用SHSaveFileDialog(推荐,支持高DPI,Vista及以上系统)
#include "windows.h" #include "shobjidl.h" #include "objbase.h" #include <iostream> // 复用已有的CreateLink函数 HRESULT CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc); int main() { CoInitialize(NULL); std::wstring targetPath = L"C:\\path\\to\\source\\file.txt"; // 创建保存文件对话框 IFileSaveDialog* pSaveDialog = nullptr; HRESULT hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, IID_IFileSaveDialog, (void**)&pSaveDialog); if (SUCCEEDED(hr)) { // 设置对话框标题和默认文件名 pSaveDialog->SetTitle(L"保存快捷方式"); pSaveDialog->SetFileName(L"新建快捷方式"); // 设置仅显示.lnk文件 COMDLG_FILTERSPEC filterSpec[] = { {L"快捷方式文件 (*.lnk)", L"*.lnk"} }; pSaveDialog->SetFileTypes(ARRAYSIZE(filterSpec), filterSpec); pSaveDialog->SetFileTypeIndex(1); // 显示对话框 hr = pSaveDialog->Show(GetDesktopWindow()); if (SUCCEEDED(hr)) { // 获取用户选择的路径 IShellItem* pItem = nullptr; hr = pSaveDialog->GetResult(&pItem); if (SUCCEEDED(hr)) { PWSTR pszPath = nullptr; hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszPath); if (SUCCEEDED(hr)) { char szMultiBytePath[MAX_PATH] = {0}; WideCharToMultiByte(CP_ACP, 0, pszPath, -1, szMultiBytePath, MAX_PATH, NULL, NULL); CreateLink(targetPath.c_str(), szMultiBytePath, L"自定义快捷方式描述"); CoTaskMemFree(pszPath); } pItem->Release(); } } pSaveDialog->Release(); } CoUninitialize(); return 0; } // 粘贴已有的CreateLink函数实现 HRESULT CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc) { HRESULT hres; IShellLink* psl; hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; psl->SetPath(lpszPathObj); psl->SetDescription(lpszDesc); hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); if (SUCCEEDED(hres)) { WCHAR wsz[MAX_PATH]; MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH); hres = ppf->Save(wsz, TRUE); ppf->Release(); } psl->Release(); } return hres; }
方法2:使用GetSaveFileName(兼容Windows XP及更早系统)
#include "windows.h" #include <iostream> // 复用已有的CreateLink函数 HRESULT CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc); int main() { CoInitialize(NULL); std::wstring targetPath = L"C:\\path\\to\\source\\file.txt"; char szLinkPath[MAX_PATH] = {0}; OPENFILENAMEA ofn = {0}; ofn.lStructSize = sizeof(OPENFILENAMEA); ofn.hwndOwner = GetDesktopWindow(); ofn.lpstrFilter = "快捷方式文件 (*.lnk)\0*.lnk\0所有文件 (*.*)\0*.*\0"; ofn.lpstrFile = szLinkPath; ofn.nMaxFile = MAX_PATH; ofn.lpstrTitle = "保存快捷方式"; ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT; ofn.lpstrDefExt = "lnk"; if (GetSaveFileNameA(&ofn)) { CreateLink(targetPath.c_str(), szLinkPath, L"自定义快捷方式描述"); } CoUninitialize(); return 0; } // 粘贴已有的CreateLink函数实现 HRESULT CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc) { HRESULT hres; IShellLink* psl; hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); if (SUCCEEDED(hres)) { IPersistFile* ppf; psl->SetPath(lpszPathObj); psl->SetDescription(lpszDesc); hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); if (SUCCEEDED(hres)) { WCHAR wsz[MAX_PATH]; MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH); hres = ppf->Save(wsz, TRUE); ppf->Release(); } psl->Release(); } return hres; }
内容的提问来源于stack exchange,提问作者Joe J
相关产品推荐
相关产品推荐

