Windows: Fix "Create desktop icon" functionality

All it needed was to suffix the filename with .lnk correctly.
This commit is contained in:
Henrik Rydgård 2023-08-18 10:42:50 +02:00
parent b2fbe1d8e9
commit 01f07c9f9c
4 changed files with 25 additions and 16 deletions

View File

@ -166,7 +166,13 @@ void GameScreen::CreateViews() {
rightColumnItems->Add(AddOtherChoice(new Choice(ga->T("Delete Game"))))->OnClick.Handle(this, &GameScreen::OnDeleteGame);
if (System_GetPropertyBool(SYSPROP_CAN_CREATE_SHORTCUT)) {
rightColumnItems->Add(AddOtherChoice(new Choice(ga->T("Create Shortcut"))))->OnClick.Handle(this, &GameScreen::OnCreateShortcut);
rightColumnItems->Add(AddOtherChoice(new Choice(ga->T("Create Shortcut"))))->OnClick.Add([=](UI::EventParams &e) {
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(NULL, gamePath_, 0);
if (info) {
System_CreateGameShortcut(gamePath_, info->GetTitle());
}
return UI::EVENT_DONE;
});
}
if (isRecentGame(gamePath_)) {
rightColumnItems->Add(AddOtherChoice(new Choice(ga->T("Remove From Recent"))))->OnClick.Handle(this, &GameScreen::OnRemoveFromRecent);
@ -414,14 +420,6 @@ void GameScreen::CallbackDeleteGame(bool yes) {
}
}
UI::EventReturn GameScreen::OnCreateShortcut(UI::EventParams &e) {
std::shared_ptr<GameInfo> info = g_gameInfoCache->GetInfo(NULL, gamePath_, 0);
if (info) {
System_CreateGameShortcut(gamePath_, info->GetTitle());
}
return UI::EVENT_DONE;
}
bool GameScreen::isRecentGame(const Path &gamePath) {
if (g_Config.iMaxRecent <= 0)
return false;

View File

@ -56,7 +56,6 @@ private:
UI::EventReturn OnDeleteSaveData(UI::EventParams &e);
UI::EventReturn OnDeleteGame(UI::EventParams &e);
UI::EventReturn OnSwitchBack(UI::EventParams &e);
UI::EventReturn OnCreateShortcut(UI::EventParams &e);
UI::EventReturn OnRemoveFromRecent(UI::EventParams &e);
UI::EventReturn OnShowInFolder(UI::EventParams &e);
UI::EventReturn OnCreateConfig(UI::EventParams &e);

View File

@ -192,6 +192,7 @@ HRESULT CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszArguments, LPCWSTR lpszPathL
psl->SetPath(lpszPathObj);
psl->SetArguments(lpszArguments);
psl->SetDescription(lpszDesc);
// psl->SetIconLocation(..)
// Query IShellLink for the IPersistFile interface, used for saving the
// shortcut in persistent storage.
@ -210,12 +211,8 @@ HRESULT CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszArguments, LPCWSTR lpszPathL
}
bool CreateDesktopShortcut(const std::string &argumentPath, std::string gameTitle) {
// TODO: not working correctly
return false;
// Get the desktop folder
// TODO: Not long path safe.
wchar_t *pathbuf = new wchar_t[MAX_PATH + gameTitle.size() + 100];
wchar_t *pathbuf = new wchar_t[4096];
SHGetFolderPath(0, CSIDL_DESKTOPDIRECTORY, NULL, SHGFP_TYPE_CURRENT, pathbuf);
// Sanitize the game title for banned characters.
@ -231,6 +228,7 @@ bool CreateDesktopShortcut(const std::string &argumentPath, std::string gameTitl
wcscat(pathbuf, L"\\");
wcscat(pathbuf, ConvertUTF8ToWString(gameTitle).c_str());
wcscat(pathbuf, L".lnk");
std::wstring moduleFilename;
size_t sz;
@ -241,7 +239,20 @@ bool CreateDesktopShortcut(const std::string &argumentPath, std::string gameTitl
} while (sz >= moduleFilename.size());
moduleFilename.resize(sz);
CreateLink(moduleFilename.c_str(), ConvertUTF8ToWString(argumentPath).c_str(), pathbuf, ConvertUTF8ToWString(gameTitle).c_str());
// Need to flip the slashes in the filename.
std::string sanitizedArgument = argumentPath;
for (size_t i = 0; i < sanitizedArgument.size(); i++) {
if (sanitizedArgument[i] == '/') {
sanitizedArgument[i] = '\\';
}
}
sanitizedArgument = "\"" + sanitizedArgument + "\"";
CreateLink(moduleFilename.c_str(), ConvertUTF8ToWString(sanitizedArgument).c_str(), pathbuf, ConvertUTF8ToWString(gameTitle).c_str());
// TODO: Also extract the game icon and convert to .ico, put it somewhere under Memstick, and set it.
delete[] pathbuf;
return false;

View File

@ -365,6 +365,7 @@ bool System_GetPropertyBool(SystemProperty prop) {
case SYSPROP_HAS_FOLDER_BROWSER:
case SYSPROP_HAS_OPEN_DIRECTORY:
case SYSPROP_HAS_TEXT_INPUT_DIALOG:
case SYSPROP_CAN_CREATE_SHORTCUT:
return true;
case SYSPROP_HAS_IMAGE_BROWSER:
return true;