22#include " stdafx.h"
33#include " Main.h"
44
5+ #include < regex>
6+ #include < filesystem>
57
68Item::~Item ()
79{
@@ -13,6 +15,40 @@ Item::~Item()
1315}
1416
1517
18+ std::wstring JoinList (std::list<std::wstring>* list, const std::wstring& sep)
19+ {
20+ std::wstring ret;
21+
22+ if ((*list).size () > 0 )
23+ ret = *(*list).begin ();
24+
25+ if ((*list).size () > 1 )
26+ {
27+ std::list<std::wstring>::iterator it = (*list).begin ();
28+ it++;
29+
30+ for (it; it != (*list).end (); it++)
31+ ret += sep + (*it);
32+ }
33+
34+ return ret;
35+ }
36+
37+
38+ std::wstring ToLower (std::wstring val)
39+ {
40+ std::transform (val.begin (), val.end (), val.begin (), tolower);
41+ return val;
42+ }
43+
44+
45+ std::wstring GetExtNoDot (std::wstring pathName)
46+ {
47+ size_t period = pathName.find_last_of (L" ." );
48+ return ToLower (pathName.substr (period + 1 ));
49+ }
50+
51+
1652BOOL FileExists (std::wstring file)
1753{
1854 if (file.length () == 0 )
@@ -23,6 +59,13 @@ BOOL FileExists(std::wstring file)
2359}
2460
2561
62+ BOOL DirectoryExist (std::wstring path)
63+ {
64+ DWORD dwAttrib = GetFileAttributes (path.c_str ());
65+ return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
66+ }
67+
68+
2669HBITMAP Create32BitHBITMAP (UINT cx, UINT cy, PBYTE* ppbBits)
2770{
2871 BITMAPINFO bmi;
@@ -97,6 +140,15 @@ HRESULT SetIcon(HMENU menu, UINT position, UINT flags, Item* item)
97140 path = szPath;
98141 }
99142
143+ // starts with
144+ if (path.rfind (L" ..\\ " , 0 ) == 0 )
145+ {
146+ WCHAR szExeDir[500 ];
147+ SHRegGetPath (HKEY_CURRENT_USER, L" Software\\ " PRODUCT_NAME, L" ExeDir" , szExeDir, NULL );
148+ std::wstring exeDir (szExeDir);
149+ path = exeDir + path;
150+ }
151+
100152 if (!FileExists (path))
101153 return S_OK;
102154
@@ -128,47 +180,6 @@ HRESULT SetIcon(HMENU menu, UINT position, UINT flags, Item* item)
128180}
129181
130182
131- std::wstring JoinList (std::list<std::wstring>* list, const std::wstring& sep)
132- {
133- std::wstring ret;
134-
135- if ((*list).size () > 0 )
136- ret = *(*list).begin ();
137-
138- if ((*list).size () > 1 )
139- {
140- std::list<std::wstring>::iterator it = (*list).begin ();
141- it++;
142-
143- for (it; it != (*list).end (); it++)
144- ret += sep + (*it);
145- }
146-
147- return ret;
148- }
149-
150-
151- std::wstring ToLower (std::wstring val)
152- {
153- std::transform (val.begin (), val.end (), val.begin (), tolower);
154- return val;
155- }
156-
157-
158- std::wstring GetExtNoDot (std::wstring pathName)
159- {
160- size_t period = pathName.find_last_of (L" ." );
161- return ToLower (pathName.substr (period + 1 ));
162- }
163-
164-
165- BOOL DirectoryExist (std::wstring path)
166- {
167- DWORD dwAttrib = GetFileAttributes (path.c_str ());
168- return (dwAttrib != INVALID_FILE_ATTRIBUTES && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
169- }
170-
171-
172183HRESULT CMain::LoadXML ()
173184{
174185 for (Item* item : g_Items)
@@ -246,6 +257,8 @@ HRESULT CMain::LoadXML()
246257 item->IconIndex = std::stoi (std::wstring (cNodeText));
247258 else if (cNodeName == L" FileTypes" )
248259 item->FileTypes = cNodeText;
260+ else if (cNodeName == L" Filter" )
261+ item->Filter = cNodeText;
249262 else if (cNodeName == L" SubMenu" )
250263 item->SubMenu = (cNodeText == L" true" ) ? true : false ;
251264 else if (cNodeName == L" Directories" )
@@ -348,6 +361,9 @@ STDMETHODIMP CMain::QueryContextMenu(
348361 bool isFile = FileExists (*g_ShellItems.begin ());
349362 bool isDirectory = !isFile && DirectoryExist (*g_ShellItems.begin ());
350363
364+ std::wstring ext = GetExtNoDot (*g_ShellItems.begin ());
365+ std::wstring path = *g_ShellItems.begin ();
366+
351367 g_EditCommandIndex = -1 ;
352368
353369 int res = InsertMenu (hmenu, uMenuIndex, MF_BYPOSITION | MF_POPUP, (UINT_PTR)subMenu, L" Open with++" );
@@ -364,10 +380,10 @@ STDMETHODIMP CMain::QueryContextMenu(
364380 for (UINT i = 0 ; i < g_Items.size (); i++)
365381 {
366382 g_Items[i]->CommandIndex = -1 ;
367- std::wstring ext = GetExtNoDot (*g_ShellItems.begin ());
368383
369384 if (isFile && g_Items[i]->FileTypes != L" " && ext != L" "
370385 && (L" " + g_Items[i]->FileTypes + L" " ).find (L" " + ext + L" " ) != std::wstring::npos
386+ && (g_Items[i]->Filter == L" " || std::regex_search (path, std::wregex (g_Items[i]->Filter )))
371387 && (!g_Items[i]->Hidden || (g_Items[i]->Hidden && isCtrlPressed)))
372388 {
373389 g_Items[i]->CommandIndex = command - uidFirstCmd;
@@ -411,7 +427,8 @@ STDMETHODIMP CMain::QueryContextMenu(
411427
412428 for (UINT i = 0 ; i < g_Items.size (); i++)
413429 {
414- if ((g_Items[i]->FileTypes == L" *.*" && isFile) || (g_Items[i]->Directories && isDirectory)
430+ if ((g_Items[i]->FileTypes == L" *.*" && isFile || g_Items[i]->Directories && isDirectory)
431+ && (g_Items[i]->Filter == L" " || std::regex_search (path, std::wregex (g_Items[i]->Filter )))
415432 && (!g_Items[i]->Hidden || (g_Items[i]->Hidden && isCtrlPressed)))
416433 {
417434 g_Items[i]->CommandIndex = command - uidFirstCmd;
@@ -503,6 +520,15 @@ STDMETHODIMP CMain::InvokeCommand(LPCMINVOKECOMMANDINFO pCmdInfo)
503520 args = value.GetBuffer ();
504521 }
505522
523+ if (args.find (L" %filename-no-ext%" ) != std::wstring::npos)
524+ {
525+ std::wstring firstFile = g_ShellItems.front ();
526+ std::filesystem::path fp (firstFile);
527+ ATL::CString value = args.c_str ();
528+ value.Replace (L" %filename-no-ext%" , fp.stem ().c_str ());
529+ args = value.GetBuffer ();
530+ }
531+
506532 std::wstring verb;
507533
508534 if (g_Items[i]->RunAsAdmin || GetKeyState (VK_SHIFT) < 0 )
@@ -520,6 +546,14 @@ STDMETHODIMP CMain::InvokeCommand(LPCMINVOKECOMMANDINFO pCmdInfo)
520546 path = szPath;
521547 }
522548
549+ WCHAR szExeDir[500 ];
550+ SHRegGetPath (HKEY_CURRENT_USER, L" Software\\ " PRODUCT_NAME, L" ExeDir" , szExeDir, NULL );
551+ std::wstring exeDir (szExeDir);
552+
553+ // starts with
554+ if (path.rfind (L" ..\\ " , 0 ) == 0 )
555+ path = exeDir + path;
556+
523557 if (args.find (var) != std::string::npos)
524558 {
525559 WCHAR szArgs[900 ];
@@ -532,12 +566,7 @@ STDMETHODIMP CMain::InvokeCommand(LPCMINVOKECOMMANDINFO pCmdInfo)
532566 std::wstring guiExe (L" OpenWithPPGUI.exe" );
533567
534568 if (guiExe == path)
535- {
536- WCHAR szExeDir[500 ];
537- SHRegGetPath (HKEY_CURRENT_USER, L" Software\\ " PRODUCT_NAME, L" ExeDir" , szExeDir, NULL );
538- std::wstring exeDir (szExeDir);
539569 path = exeDir + guiExe;
540- }
541570
542571 SHELLEXECUTEINFO info;
543572
0 commit comments