Skip to content

Commit

Permalink
Merge pull request #1002 from cjee21/shell-ext
Browse files Browse the repository at this point in the history
ShellExt: Option for separate instance
  • Loading branch information
JeromeMartinez authored Jan 16, 2025
2 parents 95a5818 + 937b722 commit a55a7a0
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 30 deletions.
8 changes: 8 additions & 0 deletions Source/GUI/Qt/prefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Preferences::Preferences(QSettings* settings, Core* C, QWidget *parent) :
ui->closeAllBeforeOpen->setChecked(settings->value("closeBeforeOpen",true).toBool());
ui->comboBox_defaultview->setCurrentIndex(settings->value("defaultView",VIEW_EASY).toInt());
ui->shellExtension->setChecked(settings->value("shellExtension",true).toBool());
ui->shellExtension_separateInstance->setChecked(settings->value("shellExtension_separateInstance",false).toBool());
ui->informVersion->setChecked(settings->value("informVersion",false).toBool());
ui->informTimestamp->setChecked(settings->value("informTimestamp",false).toBool());
ui->displayCaptions->setCurrentIndex(settings->value("displayCaptions",1).toInt());
Expand All @@ -60,6 +61,12 @@ Preferences::Preferences(QSettings* settings, Core* C, QWidget *parent) :
ui->checkForNewVersion->setVisible(false);
#endif

#ifndef _WIN32 // Shell extension not yet implemented for non-Windows
ui->shellExtension->setVisible(false);
ui->shellExtension_separateInstance->setVisible(false);
#endif
ui->shellInfoTip->setVisible(false); // InfoTip not yet implemented

#if defined(_WIN32) && defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP) //Setup UI for winRT
ui->rememberToolBarPosition->setVisible(false);
ui->rememberGeometry->setVisible(false);
Expand Down Expand Up @@ -115,6 +122,7 @@ void Preferences::saveSettings() {
settings->setValue("rememberToolBarPosition",ui->rememberToolBarPosition->isChecked());
settings->setValue("rememberGeometry",ui->rememberGeometry->isChecked());
settings->setValue("shellExtension",ui->shellExtension->isChecked());
settings->setValue("shellExtension_separateInstance",ui->shellExtension_separateInstance->isChecked());
settings->setValue("informVersion",ui->informVersion->isChecked());
settings->setValue("informTimestamp",ui->informTimestamp->isChecked());
settings->setValue("displayCaptions",ui->displayCaptions->currentIndex());
Expand Down
70 changes: 42 additions & 28 deletions Source/GUI/Qt/prefs.ui
Original file line number Diff line number Diff line change
Expand Up @@ -120,32 +120,50 @@
<property name="sizeConstraint">
<enum>QLayout::SizeConstraint::SetFixedSize</enum>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Default View</string>
<item row="0" column="1">
<widget class="QComboBox" name="comboBox_defaultview">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<property name="leftMargin">
<number>25</number>
</property>
<item>
<widget class="QCheckBox" name="shellExtension_separateInstance">
<property name="text">
<string>Open each item in a separate instance</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="shellInfoTip">
<property name="text">
<string>Shell InfoTip</string>
</property>
</widget>
</item>
<item row="4" column="0">
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
<item row="2" column="0">
<widget class="QCheckBox" name="shellExtension">
<property name="text">
<string>Shell extension</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Default View</string>
</property>
</spacer>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkForNewVersion">
Expand All @@ -154,22 +172,18 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="shellExtension">
<property name="text">
<string>Shell extension</string>
<item row="5" column="0">
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Orientation::Vertical</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBox_defaultview">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</widget>
</spacer>
</item>
</layout>
</widget>
Expand Down
31 changes: 31 additions & 0 deletions Source/GUI/VCL/GUI_Preferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,18 @@ void __fastcall TPreferencesF::Language_EditClick(TObject *Sender)
void __fastcall TPreferencesF::OKClick(TObject *Sender)
{
Prefs->Config.Save();
if (CB_InscrireShell_SeparateInstance->Visible) {
TRegistry* Reg = new TRegistry(KEY_WRITE);
try {
if (Reg->OpenKey(__T("Software\\MediaArea\\MediaInfo"), true)) {
if (CB_InscrireShell_SeparateInstance->Checked)
Reg->WriteInteger("ShellExtension_SeparateInstance", 1);
else
Reg->DeleteValue("ShellExtension_SeparateInstance");
}
} catch (...) {}
delete Reg;
}
}

//---------------------------------------------------------------------------
Expand Down Expand Up @@ -691,6 +703,25 @@ void __fastcall TPreferencesF::GUI_Configure()
Tree->FullExpand();
Page->ActivePage=Setup;

//Enable separate instance option if modern shell extension is installed
TRegistry* Reg = new TRegistry;
try {
Reg->RootKey = HKEY_CLASSES_ROOT;
if (Reg->OpenKeyReadOnly(__T("PackagedCom\\ClassIndex\\{20669675-B281-4C4F-94FB-CB6FD3995545}"))) {
CB_InscrireShell_SeparateInstance->Visible=true;
Reg->RootKey = HKEY_CURRENT_USER;
if (Reg->OpenKeyReadOnly(__T("Software\\MediaArea\\MediaInfo"))) {
if (Reg->ValueExists("ShellExtension_SeparateInstance"))
CB_InscrireShell_SeparateInstance->Checked=Reg->ReadInteger("ShellExtension_SeparateInstance");
}
}
} catch (...) {}
delete Reg;

//Move InfoTip option up to prevent blank space if there is a space
if (!CB_InscrireShell_SeparateInstance->Visible)
CB_InfoTip->Top=CB_InscrireShell_Folder->Top+CB_InscrireShell_Folder->Height*0.9;

//Translation
//Title
Caption=Prefs->Translate(__T("Preferences")).c_str();
Expand Down
12 changes: 11 additions & 1 deletion Source/GUI/VCL/GUI_Preferences.dfm
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ object PreferencesF: TPreferencesF
end
object CB_InfoTip: TCheckBox
Left = 2
Top = 104
Top = 120
Width = 655
Height = 18
Caption =
Expand Down Expand Up @@ -176,6 +176,16 @@ object PreferencesF: TPreferencesF
TabOrder = 4
OnClick = CB_InscrireShell_FolderClick
end
object CB_InscrireShell_SeparateInstance: TCheckBox
Left = 18
Top = 104
Width = 639
Height = 17
Caption = 'Open each item in a separate instance'
TabOrder = 8
Visible = False
OnClick = CB_InscrireShell_FolderClick
end
end
object Setup_Advanced: TTabSheet
Caption = 'Advanced'
Expand Down
1 change: 1 addition & 0 deletions Source/GUI/VCL/GUI_Preferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class TPreferencesF : public TForm
TCheckBox *CB_InscrireShell;
TCheckBox *CB_InscrireShell_Folder;
TCheckBox *Advanced_LegacyStreamDisplay;
TCheckBox *CB_InscrireShell_SeparateInstance;
void __fastcall General_Language_SelChange(TObject *Sender);
void __fastcall General_Output_SelChange(TObject *Sender);
void __fastcall Custom_EditClick(TObject *Sender);
Expand Down
58 changes: 57 additions & 1 deletion Source/WindowsShellExtension/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,8 +552,64 @@ struct ExplorerCommandHandler : public winrt::implements<ExplorerCommandHandler,
module_path = module_path.remove_filename();
module_path /= exe_filename;

// Option for separate instance
bool separate_instance{ false };
try {
#ifdef MEDIAINFO_QT
if (RegGetBool(HKEY_CURRENT_USER, L"Software\\MediaArea.net\\MediaInfo", L"shellExtension_separateInstance"))
#else
if (RegGetDword(HKEY_CURRENT_USER, L"Software\\MediaArea\\MediaInfo", L"ShellExtension_SeparateInstance"))
#endif // MEDIAINFO_QT
{
separate_instance = true;
}
}
catch (...) {
// Error reading reg, default same instance
}
if (separate_instance) {
// Invoke application, one instance per item
for (DWORD i = 0; i < count; ++i) {
winrt::com_ptr<IShellItem> item;
auto result = items->GetItemAt(i, item.put());
if (SUCCEEDED(result)) {
wil::unique_cotaskmem_string path;
result = item->GetDisplayName(SIGDN_FILESYSPATH, &path);
if (SUCCEEDED(result)) {
std::filesystem::path filepath{ path.get() };
// Resolve shortcuts
if (filepath.extension().string().compare(".url") == 0) {
std::string url;
if (ExtractUrlFromShortcut(filepath, url))
filepath = url;
}
if (filepath.extension().string().compare(".lnk") == 0) {
WCHAR target_path[MAX_PATH];
if (SUCCEEDED(ResolveIt(nullptr, filepath.wstring().c_str(), target_path, sizeof(target_path))))
filepath = target_path;
}
auto command{ wil::str_printf<std::wstring>(LR"-("%s" %s)-", module_path.c_str(), QuoteForCommandLineArg(filepath.wstring()).c_str()) };
wil::unique_process_information process_info;
STARTUPINFOW startup_info = { sizeof(startup_info) };
RETURN_IF_WIN32_BOOL_FALSE(CreateProcessW(
nullptr,
command.data(),
nullptr /* lpProcessAttributes */,
nullptr /* lpThreadAttributes */,
false /* bInheritHandles */,
CREATE_NO_WINDOW,
nullptr,
nullptr,
&startup_info,
&process_info));
}
}
}
return S_OK;
}

// Prepare cmd line string to invoke application ("path\to\application.exe" "path\to\firstitem" "path\to\nextitem" ...)
auto command = wil::str_printf<std::wstring>(LR"-("%s")-", module_path.c_str()); // Path to application.exe
auto command{ wil::str_printf<std::wstring>(LR"-("%s")-", module_path.c_str()) }; // Path to application.exe
// Add multiple selected files/folders to cmd line as parameters
for (DWORD i = 0; i < count; ++i) {
winrt::com_ptr<IShellItem> item;
Expand Down

0 comments on commit a55a7a0

Please sign in to comment.