mirror of
https://github.com/OpenRCT2/OpenRCT2
synced 2026-01-26 16:24:35 +01:00
Part of #11437: move window_setup_file_association(s) in Platform2.hpp
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include "../network/network.h"
|
||||
#include "../object/ObjectRepository.h"
|
||||
#include "../platform/Crash.h"
|
||||
#include "../platform/Platform2.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "CommandLine.hpp"
|
||||
|
||||
@@ -423,7 +424,7 @@ static exitcode_t HandleCommandRegisterShell([[maybe_unused]] CommandLineArgEnum
|
||||
|
||||
if (!_removeShell)
|
||||
{
|
||||
platform_setup_file_associations();
|
||||
Platform::SetUpFileAssociations();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
# include <windows.h>
|
||||
|
||||
// Then the rest
|
||||
# include "../Version.h"
|
||||
|
||||
# include <datetimeapi.h>
|
||||
# include <memory>
|
||||
# include <shlobj.h>
|
||||
@@ -35,6 +37,8 @@
|
||||
|
||||
# include <iterator>
|
||||
|
||||
constexpr wchar_t SOFTWARE_CLASSES[] = L"Software\\Classes";
|
||||
|
||||
namespace Platform
|
||||
{
|
||||
# ifdef __USE_SHGETKNOWNFOLDERPATH__
|
||||
@@ -347,6 +351,127 @@ namespace Platform
|
||||
return reinterpret_cast<uintptr_t>(input);
|
||||
}
|
||||
|
||||
void SetUpFileAssociations()
|
||||
{
|
||||
// Setup file extensions
|
||||
SetUpFileAssociation(".sc4", "RCT1 Scenario (.sc4)", "Play", "\"%1\"", 0);
|
||||
SetUpFileAssociation(".sc6", "RCT2 Scenario (.sc6)", "Play", "\"%1\"", 0);
|
||||
SetUpFileAssociation(".sv4", "RCT1 Saved Game (.sc4)", "Play", "\"%1\"", 0);
|
||||
SetUpFileAssociation(".sv6", "RCT2 Saved Game (.sv6)", "Play", "\"%1\"", 0);
|
||||
SetUpFileAssociation(".sv7", "RCT Modified Saved Game (.sv7)", "Play", "\"%1\"", 0);
|
||||
SetUpFileAssociation(".td4", "RCT1 Track Design (.td4)", "Install", "\"%1\"", 0);
|
||||
SetUpFileAssociation(".td6", "RCT2 Track Design (.td6)", "Install", "\"%1\"", 0);
|
||||
|
||||
// Refresh explorer
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
|
||||
}
|
||||
|
||||
static HMODULE _dllModule = nullptr;
|
||||
static HMODULE GetDLLModule()
|
||||
{
|
||||
if (_dllModule == nullptr)
|
||||
{
|
||||
_dllModule = GetModuleHandle(nullptr);
|
||||
}
|
||||
return _dllModule;
|
||||
}
|
||||
|
||||
static std::wstring get_progIdName(const std::string_view& extension)
|
||||
{
|
||||
auto progIdName = std::string(OPENRCT2_NAME) + std::string(extension);
|
||||
auto progIdNameW = String::ToWideChar(progIdName);
|
||||
return progIdNameW;
|
||||
}
|
||||
|
||||
bool SetUpFileAssociation(
|
||||
const std::string extension, const std::string fileTypeText, const std::string commandText,
|
||||
const std::string commandArgs, const uint32_t iconIndex)
|
||||
{
|
||||
wchar_t exePathW[MAX_PATH];
|
||||
wchar_t dllPathW[MAX_PATH];
|
||||
|
||||
[[maybe_unused]] int32_t printResult;
|
||||
|
||||
GetModuleFileNameW(nullptr, exePathW, static_cast<DWORD>(std::size(exePathW)));
|
||||
GetModuleFileNameW(GetDLLModule(), dllPathW, static_cast<DWORD>(std::size(dllPathW)));
|
||||
|
||||
auto extensionW = String::ToWideChar(extension);
|
||||
auto fileTypeTextW = String::ToWideChar(fileTypeText);
|
||||
auto commandTextW = String::ToWideChar(commandText);
|
||||
auto commandArgsW = String::ToWideChar(commandArgs);
|
||||
auto progIdNameW = get_progIdName(extension);
|
||||
|
||||
HKEY hKey = nullptr;
|
||||
HKEY hRootKey = nullptr;
|
||||
|
||||
// [HKEY_CURRENT_USER\Software\Classes]
|
||||
if (RegOpenKeyW(HKEY_CURRENT_USER, SOFTWARE_CLASSES, &hRootKey) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hRootKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
// [hRootKey\.ext]
|
||||
if (RegSetValueW(hRootKey, extensionW.c_str(), REG_SZ, progIdNameW.c_str(), 0) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hRootKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (RegCreateKeyW(hRootKey, progIdNameW.c_str(), &hKey) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
RegCloseKey(hRootKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.ext]
|
||||
if (RegSetValueW(hKey, nullptr, REG_SZ, fileTypeTextW.c_str(), 0) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
RegCloseKey(hRootKey);
|
||||
return false;
|
||||
}
|
||||
// [hRootKey\OpenRCT2.ext\DefaultIcon]
|
||||
wchar_t szIconW[MAX_PATH];
|
||||
printResult = swprintf_s(szIconW, MAX_PATH, L"\"%s\",%d", dllPathW, iconIndex);
|
||||
assert(printResult >= 0);
|
||||
if (RegSetValueW(hKey, L"DefaultIcon", REG_SZ, szIconW, 0) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
RegCloseKey(hRootKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.sv6\shell]
|
||||
if (RegSetValueW(hKey, L"shell", REG_SZ, L"open", 0) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
RegCloseKey(hRootKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.sv6\shell\open]
|
||||
if (RegSetValueW(hKey, L"shell\\open", REG_SZ, commandTextW.c_str(), 0) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
RegCloseKey(hRootKey);
|
||||
return false;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.sv6\shell\open\command]
|
||||
wchar_t szCommandW[MAX_PATH];
|
||||
printResult = swprintf_s(szCommandW, MAX_PATH, L"\"%s\" %s", exePathW, commandArgsW.c_str());
|
||||
assert(printResult >= 0);
|
||||
if (RegSetValueW(hKey, L"shell\\open\\command", REG_SZ, szCommandW, 0) != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
RegCloseKey(hRootKey);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HandleSpecialCommandLineArgument(const char* argument)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -43,6 +43,10 @@ namespace Platform
|
||||
|
||||
#ifdef _WIN32
|
||||
bool IsOSVersionAtLeast(uint32_t major, uint32_t minor, uint32_t build);
|
||||
void SetUpFileAssociations();
|
||||
bool SetUpFileAssociation(
|
||||
const std::string extension, const std::string fileTypeText, const std::string commandText,
|
||||
const std::string commandArgs, const uint32_t iconIndex);
|
||||
#endif
|
||||
|
||||
bool IsRunningInWine();
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
# include "../localisation/Language.h"
|
||||
# include "../rct2/RCT2.h"
|
||||
# include "../util/Util.h"
|
||||
# include "Platform2.h"
|
||||
# include "platform.h"
|
||||
|
||||
# include <algorithm>
|
||||
@@ -54,17 +55,6 @@
|
||||
# define swprintf_s(a, b, c, d, ...) swprintf(a, b, c, ##__VA_ARGS__)
|
||||
# endif
|
||||
|
||||
static HMODULE _dllModule = nullptr;
|
||||
|
||||
static HMODULE plaform_get_dll_module()
|
||||
{
|
||||
if (_dllModule == nullptr)
|
||||
{
|
||||
_dllModule = GetModuleHandle(nullptr);
|
||||
}
|
||||
return _dllModule;
|
||||
}
|
||||
|
||||
void platform_get_date_local(rct2_date* out_date)
|
||||
{
|
||||
assert(out_date != nullptr);
|
||||
@@ -551,86 +541,6 @@ static std::wstring get_progIdName(const std::string_view& extension)
|
||||
return progIdNameW;
|
||||
}
|
||||
|
||||
static bool windows_setup_file_association(
|
||||
const utf8* extension, const utf8* fileTypeText, const utf8* commandText, const utf8* commandArgs, const uint32_t iconIndex)
|
||||
{
|
||||
wchar_t exePathW[MAX_PATH];
|
||||
wchar_t dllPathW[MAX_PATH];
|
||||
|
||||
[[maybe_unused]] int32_t printResult;
|
||||
|
||||
GetModuleFileNameW(nullptr, exePathW, (DWORD)std::size(exePathW));
|
||||
GetModuleFileNameW(plaform_get_dll_module(), dllPathW, (DWORD)std::size(dllPathW));
|
||||
|
||||
auto extensionW = String::ToWideChar(extension);
|
||||
auto fileTypeTextW = String::ToWideChar(fileTypeText);
|
||||
auto commandTextW = String::ToWideChar(commandText);
|
||||
auto commandArgsW = String::ToWideChar(commandArgs);
|
||||
auto progIdNameW = get_progIdName(extension);
|
||||
|
||||
bool result = false;
|
||||
HKEY hKey = nullptr;
|
||||
HKEY hRootKey = nullptr;
|
||||
|
||||
// [HKEY_CURRENT_USER\Software\Classes]
|
||||
if (RegOpenKeyW(HKEY_CURRENT_USER, SOFTWARE_CLASSES, &hRootKey) != ERROR_SUCCESS)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// [hRootKey\.ext]
|
||||
if (RegSetValueW(hRootKey, extensionW.c_str(), REG_SZ, progIdNameW.c_str(), 0) != ERROR_SUCCESS)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (RegCreateKeyW(hRootKey, progIdNameW.c_str(), &hKey) != ERROR_SUCCESS)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.ext]
|
||||
if (RegSetValueW(hKey, nullptr, REG_SZ, fileTypeTextW.c_str(), 0) != ERROR_SUCCESS)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
// [hRootKey\OpenRCT2.ext\DefaultIcon]
|
||||
wchar_t szIconW[MAX_PATH];
|
||||
printResult = swprintf_s(szIconW, MAX_PATH, L"\"%s\",%d", dllPathW, iconIndex);
|
||||
assert(printResult >= 0);
|
||||
if (RegSetValueW(hKey, L"DefaultIcon", REG_SZ, szIconW, 0) != ERROR_SUCCESS)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.sv6\shell]
|
||||
if (RegSetValueW(hKey, L"shell", REG_SZ, L"open", 0) != ERROR_SUCCESS)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.sv6\shell\open]
|
||||
if (RegSetValueW(hKey, L"shell\\open", REG_SZ, commandTextW.c_str(), 0) != ERROR_SUCCESS)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// [hRootKey\OpenRCT2.sv6\shell\open\command]
|
||||
wchar_t szCommandW[MAX_PATH];
|
||||
printResult = swprintf_s(szCommandW, MAX_PATH, L"\"%s\" %s", exePathW, commandArgsW.c_str());
|
||||
assert(printResult >= 0);
|
||||
if (RegSetValueW(hKey, L"shell\\open\\command", REG_SZ, szCommandW, 0) != ERROR_SUCCESS)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
result = true;
|
||||
fail:
|
||||
RegCloseKey(hKey);
|
||||
RegCloseKey(hRootKey);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void windows_remove_file_association(const utf8* extension)
|
||||
{
|
||||
# if _WIN32_WINNT >= 0x0600
|
||||
@@ -650,21 +560,6 @@ static void windows_remove_file_association(const utf8* extension)
|
||||
# endif
|
||||
}
|
||||
|
||||
void platform_setup_file_associations()
|
||||
{
|
||||
// Setup file extensions
|
||||
windows_setup_file_association(".sc4", "RCT1 Scenario (.sc4)", "Play", "\"%1\"", 0);
|
||||
windows_setup_file_association(".sc6", "RCT2 Scenario (.sc6)", "Play", "\"%1\"", 0);
|
||||
windows_setup_file_association(".sv4", "RCT1 Saved Game (.sc4)", "Play", "\"%1\"", 0);
|
||||
windows_setup_file_association(".sv6", "RCT2 Saved Game (.sv6)", "Play", "\"%1\"", 0);
|
||||
windows_setup_file_association(".sv7", "RCT Modified Saved Game (.sv7)", "Play", "\"%1\"", 0);
|
||||
windows_setup_file_association(".td4", "RCT1 Track Design (.td4)", "Install", "\"%1\"", 0);
|
||||
windows_setup_file_association(".td6", "RCT2 Track Design (.td6)", "Install", "\"%1\"", 0);
|
||||
|
||||
// Refresh explorer
|
||||
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);
|
||||
}
|
||||
|
||||
void platform_remove_file_associations()
|
||||
{
|
||||
// Remove file extensions
|
||||
|
||||
@@ -151,7 +151,6 @@ void core_init();
|
||||
# undef CreateWindow
|
||||
# undef GetMessage
|
||||
|
||||
void platform_setup_file_associations();
|
||||
void platform_remove_file_associations();
|
||||
bool platform_setup_uri_protocol();
|
||||
// This function cannot be marked as 'static', even though it may seem to be,
|
||||
|
||||
Reference in New Issue
Block a user