Skip to content

Commit

Permalink
refactor path parse and add drive support
Browse files Browse the repository at this point in the history
  • Loading branch information
ikas-mc committed Aug 28, 2024
1 parent 8664b93 commit d002647
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ enum FileType {
File = 0,
Directory = 1,
Background = 2,
Desktop = 3
Desktop = 3,
Drive = 4,
};

class BaseExplorerCommand : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IExplorerCommand, IObjectWithSite> {
Expand Down
75 changes: 52 additions & 23 deletions ContextMenuCustom/ContextMenuCustomHost/CustomExplorerCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,26 +90,38 @@ IFACEMETHODIMP CustomExplorerCommand::GetState(_In_opt_ IShellItemArray* selecti
const std::optional<uint32_t> appsUseLightTheme = wil::reg::try_get_value_dword(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize", L"AppsUseLightTheme");
if (appsUseLightTheme.has_value()) {
m_theme_type = appsUseLightTheme.value() == 0 ? ThemeType::Dark : ThemeType::Light;
}
}
DEBUG_LOG(L"CustomExplorerCommand::GetState m_theme_type={}", static_cast<int>(m_theme_type));

//
if (count > 1) {
const std::wstring currentPath;
ReadCommands(true, false, false, currentPath);
ReadCommands(true, false, false, false, currentPath);
}
else if (count == 1) {
const auto currentPath = PathHelper::getPath(selection);
ReadCommands(false, false, false, currentPath);
winrt::com_ptr<IShellItem> item;
if (SUCCEEDED(selection->GetItemAt(0, item.put()))) {
wil::unique_cotaskmem_string path;
if (SUCCEEDED(item->GetDisplayName(SIGDN_FILESYSPATH, path.put()))) {
SFGAOF attributes;
item->GetAttributes(SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_STREAM, &attributes);
const bool isDirectory = (SFGAO_FILESYSTEM & attributes) == SFGAO_FILESYSTEM && (SFGAO_FOLDER & attributes) == SFGAO_FOLDER && (SFGAO_STREAM & attributes) != SFGAO_STREAM;
const std::wstring currentPath{ path.get() };
DEBUG_LOG(L"CustomExplorerCommand::GetState isDirectory={}", isDirectory);

ReadCommands(false, isDirectory, false, false, currentPath);
}
}
}
else {
wil::com_ptr_nothrow<IShellItem> psi;
FindLocationFromSite(psi.put());
if (psi) {
//check for ( this pc background , zip... folder )
SFGAOF attributes;
const bool isFileSystemItem = psi && (psi->GetAttributes(SFGAO_FILESYSTEM, &attributes) == S_OK);
const bool isCompressed = psi && (psi->GetAttributes(SFGAO_FOLDER | SFGAO_STREAM, &attributes) == S_OK);
psi->GetAttributes(SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_STREAM, &attributes);
const bool isFileSystemItem = (SFGAO_FILESYSTEM & attributes) == SFGAO_FILESYSTEM;
const bool isCompressed = (SFGAO_FOLDER & attributes) == SFGAO_FOLDER && (SFGAO_STREAM & attributes) == SFGAO_STREAM;
DEBUG_LOG(L"CustomExplorerCommand::GetState isFileSystemItem={} ,isCompressed={}", isFileSystemItem, isCompressed);

//valid path
Expand All @@ -125,7 +137,7 @@ IFACEMETHODIMP CustomExplorerCommand::GetState(_In_opt_ IShellItemArray* selecti
DEBUG_LOG(L"CustomExplorerCommand::GetState isDesktop={}, path={}", isDesktop, desktopPath);
}

ReadCommands(false, true, isDesktop, currentPath);
ReadCommands(false, true, true, isDesktop, currentPath);
}
}
}
Expand All @@ -152,28 +164,45 @@ IFACEMETHODIMP CustomExplorerCommand::EnumSubCommands(__RPC__deref_out_opt IEnum
return customCommands->QueryInterface(IID_PPV_ARGS(enumCommands));
}

void CustomExplorerCommand::ReadCommands(bool multipleFiles, bool isBackground, bool isDesktop, const std::wstring& currentPath) {
void CustomExplorerCommand::ReadCommands(bool multipleFiles, bool isDirectory, bool isBackground, bool isDesktop, const std::wstring& currentPath) {
std::wstring ext;
std::wstring name;
bool isDirectory = false; // TODO current_path may be empty when right click on desktop. set directory as default?
if (!multipleFiles) {
PathHelper::getExt(currentPath, isDirectory, name, ext);
}

FileType fileType;
if (isDesktop) {
fileType = FileType::Desktop;
}
else if (isBackground) {
fileType = FileType::Background;

if (multipleFiles) {
fileType = FileType::File;
}
else if (isDirectory) {
fileType = FileType::Directory;
if (isDesktop) {
fileType = FileType::Desktop;
}
else if (isBackground) {
fileType = FileType::Background;
}
else {
const auto pathLength = currentPath.length();
//TODO
if (pathLength==2 || pathLength==3 && PathIsRoot(currentPath.data())) {
fileType = FileType::Drive;
}
else {
fileType = FileType::Directory;
}
}
name = PathFindFileName(currentPath.data());
}
else {
fileType = FileType::File;
name = PathFindFileName(currentPath.data());
if (!name.starts_with(L".")) {
ext = PathFindExtension(name.data());
}
if (!ext.empty()) {
std::ranges::transform(ext, ext.begin(), towlower); // TODO check
}
}
DEBUG_LOG(L"CustomExplorerCommand::ReadCommands isMultipleFiles={},isBackground={},isDesktop={},fileType={},currentPath={}", multipleFiles, isBackground, isDesktop, static_cast<int>(fileType), currentPath);

DEBUG_LOG(L"CustomExplorerCommand::ReadCommands isMultipleFiles={},isDirectory={},isBackground={},isDesktop={},fileType={},currentPath={}", multipleFiles, isDirectory, isBackground, isDesktop, static_cast<int>(fileType), currentPath);

const auto menus = ApplicationData::Current().LocalSettings().CreateContainer(L"menus", ApplicationDataCreateDisposition::Always).Values();
if (menus.Size() > 0) {
Expand Down Expand Up @@ -210,11 +239,11 @@ void CustomExplorerCommand::ReadCommands(bool multipleFiles, bool isBackground,

for (auto& file : directory_iterator{ folder }) {
DEBUG_LOG(L"CustomExplorerCommand::ReadCommands useCache={},file={}", false, file.path().c_str());

if (!file.is_regular_file() || file.path().extension() != ".json") {
continue;
}

try
{
//std::ifstream fs{ file.path() };
Expand All @@ -225,7 +254,7 @@ void CustomExplorerCommand::ReadCommands(bool multipleFiles, bool isBackground,

std::ifstream fs(file.path(), std::ios::binary);
if (!fs.is_open()) {
DEBUG_LOG(L"CustomExplorerCommand::ReadCommands read file open failed, useCache=false,file={}",file.path().c_str());
DEBUG_LOG(L"CustomExplorerCommand::ReadCommands read file open failed, useCache=false,file={}", file.path().c_str());
continue;
}
std::string contentString{ std::istreambuf_iterator<char>{ fs }, std::istreambuf_iterator<char>{} };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ CustomExplorerCommand: public BaseExplorerCommand{
IFACEMETHODIMP GetCanonicalName(_Out_ GUID* guidCommandName) override;
IFACEMETHODIMP EnumSubCommands(__RPC__deref_out_opt IEnumExplorerCommand** enumCommands) override;
IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept override;
void ReadCommands(bool multipleFiles,bool isBackground,bool isDesktop, const std::wstring& currentPath);
void ReadCommands(bool multipleFiles, bool isDirectory, bool isBackground, bool isDesktop, const std::wstring& currentPath);
HRESULT FindLocationFromSite(IShellItem** location) const noexcept;

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ bool CustomSubExplorerCommand::Accept(bool multipleFiles, FileType fileType, con
DEBUG_LOG(L"CustomSubExplorerCommand::Accept menu={}, directory=Desktop", _title);
return (_accept_directory_flag & DIRECTORY_DESKTOP) == DIRECTORY_DESKTOP;
}
//drive
else if (fileType == FileType::Drive) {
DEBUG_LOG(L"CustomSubExplorerCommand::Accept menu={}, directory=Drive", _title);
return (_accept_directory_flag & DIRECTORY_DIRECTORY) == DIRECTORY_DIRECTORY;
}

DEBUG_LOG(L"CustomSubExplorerCommand::Accept skip, menu={}", _title);
return false;
Expand Down

0 comments on commit d002647

Please sign in to comment.