From fdee18534bc40a46d28a38cafafb43987c22a11f Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 8 Oct 2020 08:32:51 +0200 Subject: [PATCH] On Windows associate .gcode files to gcode viewer application --- src/slic3r/GUI/GUI_App.cpp | 96 ++++++++++++++++++++++++-------------- src/slic3r/GUI/GUI_App.hpp | 1 + 2 files changed, 62 insertions(+), 35 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 3c55b2bc4..4c0ae7124 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -784,6 +784,11 @@ bool GUI_App::on_init_inner() }); #if ENABLE_GCODE_VIEWER } + else { +#ifdef __WXMSW__ + associate_gcode_files(); +#endif // __WXMSW__ + } #endif // ENABLE_GCODE_VIEWER // initialize label colors and fonts @@ -2010,50 +2015,47 @@ void GUI_App::check_updates(const bool verbose) #ifdef __WXMSW__ -void GUI_App::associate_3mf_files() +static bool set_into_win_registry(HKEY hkeyHive, const wchar_t* pszVar, const wchar_t* pszValue) { // see as reference: https://stackoverflow.com/questions/20245262/c-program-needs-an-file-association + wchar_t szValueCurrent[1000]; + DWORD dwType; + DWORD dwSize = sizeof(szValueCurrent); - auto reg_set = [](HKEY hkeyHive, const wchar_t* pszVar, const wchar_t* pszValue)->bool - { - wchar_t szValueCurrent[1000]; - DWORD dwType; - DWORD dwSize = sizeof(szValueCurrent); + int iRC = ::RegGetValueW(hkeyHive, pszVar, nullptr, RRF_RT_ANY, &dwType, szValueCurrent, &dwSize); - int iRC = ::RegGetValueW(hkeyHive, pszVar, nullptr, RRF_RT_ANY, &dwType, szValueCurrent, &dwSize); + bool bDidntExist = iRC == ERROR_FILE_NOT_FOUND; - bool bDidntExist = iRC == ERROR_FILE_NOT_FOUND; + if ((iRC != ERROR_SUCCESS) && !bDidntExist) + // an error occurred + return false; - if ((iRC != ERROR_SUCCESS) && !bDidntExist) - // an error occurred + if (!bDidntExist) { + if (dwType != REG_SZ) + // invalid type return false; - if (!bDidntExist) - { - if (dwType != REG_SZ) - // invalid type - return false; + if (::wcscmp(szValueCurrent, pszValue) == 0) + // value already set + return false; + } - if (::wcscmp(szValueCurrent, pszValue) == 0) - // value already set - return false; - } - - DWORD dwDisposition; - HKEY hkey; - iRC = ::RegCreateKeyExW(hkeyHive, pszVar, 0, 0, 0, KEY_ALL_ACCESS, nullptr, &hkey, &dwDisposition); - bool ret = false; + DWORD dwDisposition; + HKEY hkey; + iRC = ::RegCreateKeyExW(hkeyHive, pszVar, 0, 0, 0, KEY_ALL_ACCESS, nullptr, &hkey, &dwDisposition); + bool ret = false; + if (iRC == ERROR_SUCCESS) { + iRC = ::RegSetValueExW(hkey, L"", 0, REG_SZ, (BYTE*)pszValue, (::wcslen(pszValue) + 1) * sizeof(wchar_t)); if (iRC == ERROR_SUCCESS) - { - iRC = ::RegSetValueExW(hkey, L"", 0, REG_SZ, (BYTE*)pszValue, (::wcslen(pszValue) + 1) * sizeof(wchar_t)); - if (iRC == ERROR_SUCCESS) - ret = true; - } + ret = true; + } - RegCloseKey(hkey); - return ret; - }; + RegCloseKey(hkey); + return ret; +} +void GUI_App::associate_3mf_files() +{ wchar_t app_path[MAX_PATH]; ::GetModuleFileNameW(nullptr, app_path, sizeof(app_path)); @@ -2067,9 +2069,33 @@ void GUI_App::associate_3mf_files() std::wstring reg_prog_id_command = reg_prog_id + L"\\Shell\\Open\\Command"; bool is_new = false; - is_new |= reg_set(HKEY_CURRENT_USER, reg_extension.c_str(), prog_id.c_str()); - is_new |= reg_set(HKEY_CURRENT_USER, reg_prog_id.c_str(), prog_desc.c_str()); - is_new |= reg_set(HKEY_CURRENT_USER, reg_prog_id_command.c_str(), prog_command.c_str()); + is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_extension.c_str(), prog_id.c_str()); + is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_prog_id.c_str(), prog_desc.c_str()); + is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_prog_id_command.c_str(), prog_command.c_str()); + + if (is_new) + // notify Windows only when any of the values gets changed + ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr); +} + +void GUI_App::associate_gcode_files() +{ + wchar_t app_path[MAX_PATH]; + ::GetModuleFileNameW(nullptr, app_path, sizeof(app_path)); + + std::wstring prog_path = L"\"" + std::wstring(app_path) + L"\""; + std::wstring prog_id = L"PrusaSlicer.GCodeViewer.1"; + std::wstring prog_desc = L"PrusaSlicerGCodeViewer"; + std::wstring prog_command = prog_path + L" \"%1\""; + std::wstring reg_base = L"Software\\Classes"; + std::wstring reg_extension = reg_base + L"\\.gcode"; + std::wstring reg_prog_id = reg_base + L"\\" + prog_id; + std::wstring reg_prog_id_command = reg_prog_id + L"\\Shell\\Open\\Command"; + + bool is_new = false; + is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_extension.c_str(), prog_id.c_str()); + is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_prog_id.c_str(), prog_desc.c_str()); + is_new |= set_into_win_registry(HKEY_CURRENT_USER, reg_prog_id_command.c_str(), prog_command.c_str()); if (is_new) // notify Windows only when any of the values gets changed diff --git a/src/slic3r/GUI/GUI_App.hpp b/src/slic3r/GUI/GUI_App.hpp index 676bc1d7e..113d8d756 100644 --- a/src/slic3r/GUI/GUI_App.hpp +++ b/src/slic3r/GUI/GUI_App.hpp @@ -316,6 +316,7 @@ private: #ifdef __WXMSW__ void associate_3mf_files(); + void associate_gcode_files(); #endif // __WXMSW__ }; DECLARE_APP(GUI_App)