diff --git a/Source/Core/DolphinQt/GameList/GameList.cpp b/Source/Core/DolphinQt/GameList/GameList.cpp index 1b458bdb35..65c870b1f4 100644 --- a/Source/Core/DolphinQt/GameList/GameList.cpp +++ b/Source/Core/DolphinQt/GameList/GameList.cpp @@ -53,6 +53,20 @@ #include "UICommon/GameFile.h" +#ifdef _WIN32 +#include +#include +#include + +// This file uses some identifiers which are defined as macros in Windows headers. +// Undefine them for the intellisense parser to solve some red squiggles. +#ifdef __INTELLISENSE__ +#ifdef DeleteFile +#undef DeleteFile +#endif +#endif +#endif + GameList::GameList(QWidget* parent) : QStackedWidget(parent), m_model(this) { m_list_proxy = new ListProxyModel(this); @@ -382,6 +396,15 @@ void GameList::ShowContextMenu(const QPoint&) menu->addAction(tr("Open &Containing Folder"), this, &GameList::OpenContainingFolder); menu->addAction(tr("Delete File..."), this, &GameList::DeleteFile); +#ifdef _WIN32 + menu->addAction(tr("Add Shortcut to Desktop"), this, [this] { + if (!AddShortcutToDesktop()) + { + ModalMessageBox::critical(this, tr("Add Shortcut to Desktop"), + tr("There was an issue adding a shortcut to the desktop")); + } + }); +#endif menu->addSeparator(); @@ -631,6 +654,41 @@ void GameList::OpenGCSaveFolder() ModalMessageBox::information(this, tr("Information"), tr("No save data found.")); } +#ifdef _WIN32 +bool GameList::AddShortcutToDesktop() +{ + auto init = wil::CoInitializeEx_failfast(COINIT_APARTMENTTHREADED); + auto shell_link = wil::CoCreateInstanceNoThrow(); + if (!shell_link) + return false; + + std::wstring dolphin_path = QCoreApplication::applicationFilePath().toStdWString(); + if (FAILED(shell_link->SetPath(dolphin_path.c_str()))) + return false; + + const auto game = GetSelectedGame(); + const auto& file_path = game->GetFilePath(); + std::wstring args = UTF8ToTStr("-e \"" + file_path + "\""); + if (FAILED(shell_link->SetArguments(args.c_str()))) + return false; + + wil::unique_cotaskmem_string desktop; + if (FAILED(SHGetKnownFolderPath(FOLDERID_Desktop, KF_FLAG_NO_ALIAS, nullptr, &desktop))) + return false; + + const auto& game_name = game->GetLongName(); + std::wstring desktop_path = std::wstring(desktop.get()) + UTF8ToTStr("\\" + game_name + ".lnk"); + auto persist_file = shell_link.try_query(); + if (!persist_file) + return false; + + if (FAILED(persist_file->Save(desktop_path.c_str(), TRUE))) + return false; + + return true; +} +#endif + void GameList::DeleteFile() { ModalMessageBox confirm_dialog(this); diff --git a/Source/Core/DolphinQt/GameList/GameList.h b/Source/Core/DolphinQt/GameList/GameList.h index 8ed4c87ec8..a49ee7af1d 100644 --- a/Source/Core/DolphinQt/GameList/GameList.h +++ b/Source/Core/DolphinQt/GameList/GameList.h @@ -65,6 +65,9 @@ private: void OpenWiki(); void SetDefaultISO(); void DeleteFile(); +#ifdef _WIN32 + bool AddShortcutToDesktop(); +#endif void InstallWAD(); void UninstallWAD(); void ExportWiiSave();