mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-11 17:59:17 +00:00
Run code cleanup
This commit is contained in:
@@ -34,111 +34,111 @@ PCHAR pXmlBuffer;
|
|||||||
|
|
||||||
void DOpus::GetSelected(PWCHAR buffer)
|
void DOpus::GetSelected(PWCHAR buffer)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* CPU Disasm
|
* CPU Disasm
|
||||||
* 6A44B588 |. 68 A839526A PUSH OFFSET 6A5239A8 ; /WindowName = "Directory Opus"
|
* 6A44B588 |. 68 A839526A PUSH OFFSET 6A5239A8 ; /WindowName = "Directory Opus"
|
||||||
* 6A44B58D |. 68 6459526A PUSH OFFSET 6A525964 ; |ClassName = "DOpus.ParentWindow"
|
* 6A44B58D |. 68 6459526A PUSH OFFSET 6A525964 ; |ClassName = "DOpus.ParentWindow"
|
||||||
* 6A44B592 |. 894424 40 MOV DWORD PTR SS:[ESP+40],EAX ; |
|
* 6A44B592 |. 894424 40 MOV DWORD PTR SS:[ESP+40],EAX ; |
|
||||||
* 6A44B596 |. C74424 30 140 MOV DWORD PTR SS:[ESP+30],14 ; |
|
* 6A44B596 |. C74424 30 140 MOV DWORD PTR SS:[ESP+30],14 ; |
|
||||||
* 6A44B59E |. FFD7 CALL EDI ; \USER32.FindWindowW
|
* 6A44B59E |. FFD7 CALL EDI ; \USER32.FindWindowW
|
||||||
* ...
|
* ...
|
||||||
* 00BC2E9B |. 50 PUSH EAX ; /lParam = 12FE80C -> 15 ;
|
* 00BC2E9B |. 50 PUSH EAX ; /lParam = 12FE80C -> 15 ;
|
||||||
* 00BC2E9C |. 57 PUSH EDI ; |wParam ; class = dopusrt.getinfo
|
* 00BC2E9C |. 57 PUSH EDI ; |wParam ; class = dopusrt.getinfo
|
||||||
* 00BC2E9D |. 6A 4A PUSH 4A ; |Msg = WM_COPYDATA
|
* 00BC2E9D |. 6A 4A PUSH 4A ; |Msg = WM_COPYDATA
|
||||||
* 00BC2E9F |. FF75 FC PUSH DWORD PTR SS:[LOCAL.1] ; |hWnd => [LOCAL.1] ; class = DOpus.ParentWindow, text = Directory Opus
|
* 00BC2E9F |. FF75 FC PUSH DWORD PTR SS:[LOCAL.1] ; |hWnd => [LOCAL.1] ; class = DOpus.ParentWindow, text = Directory Opus
|
||||||
* 00BC2EA2 |. FF15 0802C000 CALL DWORD PTR DS:[<&USER32.SendMessageW ; \USER32.SendMessageW
|
* 00BC2EA2 |. FF15 0802C000 CALL DWORD PTR DS:[<&USER32.SendMessageW ; \USER32.SendMessageW
|
||||||
*
|
*
|
||||||
* CPU Stack
|
* CPU Stack
|
||||||
* 012FE80C |00000015
|
* 012FE80C |00000015
|
||||||
* 012FE810 |00000010
|
* 012FE810 |00000010
|
||||||
* 012FE814 |013A26C0 ; UNICODE "listsel"
|
* 012FE814 |013A26C0 ; UNICODE "listsel"
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (hMsgWnd == nullptr)
|
if (hMsgWnd == nullptr)
|
||||||
PrepareMessageWindow();
|
PrepareMessageWindow();
|
||||||
if (hMsgWnd == nullptr)
|
if (hMsgWnd == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PWCHAR data = DOPUS_IPC_LP_DATA;
|
PWCHAR data = DOPUS_IPC_LP_DATA;
|
||||||
COPYDATASTRUCT cds;
|
COPYDATASTRUCT cds;
|
||||||
cds.dwData = DOPUS_IPC_LP_INFO;
|
cds.dwData = DOPUS_IPC_LP_INFO;
|
||||||
cds.cbData = static_cast<DWORD>(wcslen(data) + 1) * sizeof WCHAR;
|
cds.cbData = static_cast<DWORD>(wcslen(data) + 1) * sizeof WCHAR;
|
||||||
cds.lpData = data;
|
cds.lpData = data;
|
||||||
|
|
||||||
auto ret = SendMessage(FindWindow(DOPUS_CLASS, DOPUS_NAME), WM_COPYDATA, reinterpret_cast<WPARAM>(hMsgWnd),
|
auto ret = SendMessage(FindWindow(DOPUS_CLASS, DOPUS_NAME), WM_COPYDATA, reinterpret_cast<WPARAM>(hMsgWnd),
|
||||||
reinterpret_cast<LPARAM>(&cds));
|
reinterpret_cast<LPARAM>(&cds));
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WaitForSingleObject(hGetResultEvent, 2000);
|
WaitForSingleObject(hGetResultEvent, 2000);
|
||||||
|
|
||||||
ParseXmlBuffer(buffer);
|
ParseXmlBuffer(buffer);
|
||||||
|
|
||||||
delete[] pXmlBuffer;
|
delete[] pXmlBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DOpus::ParseXmlBuffer(PWCHAR buffer)
|
void DOpus::ParseXmlBuffer(PWCHAR buffer)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* <?xml version="1.0" encoding="UTF-8"?>
|
* <?xml version="1.0" encoding="UTF-8"?>
|
||||||
* <results command="listsel" result="1">
|
* <results command="listsel" result="1">
|
||||||
* <items display_path="C:\folder" lister="0x707f6" path="C:\folder" tab="0xb0844">
|
* <items display_path="C:\folder" lister="0x707f6" path="C:\folder" tab="0xb0844">
|
||||||
* <item id="11" name="1.jpg" path="C:\folder\1.jpg" type="0" />
|
* <item id="11" name="1.jpg" path="C:\folder\1.jpg" type="0" />
|
||||||
* <item id="12" name="2.zip" path="C:\folder\2.zip" type="1" />
|
* <item id="12" name="2.zip" path="C:\folder\2.zip" type="1" />
|
||||||
* ...
|
* ...
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using namespace rapidxml;
|
using namespace rapidxml;
|
||||||
|
|
||||||
xml_document<> doc;
|
xml_document<> doc;
|
||||||
doc.parse<0>(pXmlBuffer);
|
doc.parse<0>(pXmlBuffer);
|
||||||
|
|
||||||
auto results = doc.first_node("results");
|
auto results = doc.first_node("results");
|
||||||
auto items = results->first_node("items");
|
auto items = results->first_node("items");
|
||||||
for (auto item = items->first_node("item"); item; item = item->next_sibling("item"))
|
for (auto item = items->first_node("item"); item; item = item->next_sibling("item"))
|
||||||
{
|
{
|
||||||
auto path = item->first_attribute("path")->value();
|
auto path = item->first_attribute("path")->value();
|
||||||
|
|
||||||
auto size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, nullptr, 0);
|
auto size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, nullptr, 0);
|
||||||
auto b = new WCHAR[size];
|
auto b = new WCHAR[size];
|
||||||
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, b, size);
|
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, path, -1, b, size);
|
||||||
|
|
||||||
wcscpy_s(buffer, wcslen(b) + 1, b); // DOpus supports Long Path
|
wcscpy_s(buffer, wcslen(b) + 1, b); // DOpus supports Long Path
|
||||||
|
|
||||||
delete[] b;
|
delete[] b;
|
||||||
return; // we now cares only the first result
|
return; // we now cares only the first result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DOpus::PrepareMessageWindow()
|
void DOpus::PrepareMessageWindow()
|
||||||
{
|
{
|
||||||
WNDCLASSEX wx = {sizeof wx};
|
WNDCLASSEX wx = {sizeof wx};
|
||||||
wx.cbSize = sizeof(WNDCLASSEX);
|
wx.cbSize = sizeof(WNDCLASSEX);
|
||||||
wx.lpfnWndProc = msgWindowProc;
|
wx.lpfnWndProc = msgWindowProc;
|
||||||
wx.lpszClassName = MSGWINDOW_CLASS;
|
wx.lpszClassName = MSGWINDOW_CLASS;
|
||||||
|
|
||||||
if (RegisterClassEx(&wx))
|
if (RegisterClassEx(&wx))
|
||||||
hMsgWnd = CreateWindowEx(0, MSGWINDOW_CLASS, L"", 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr);
|
hMsgWnd = CreateWindowEx(0, MSGWINDOW_CLASS, L"", 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
hGetResultEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
hGetResultEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK DOpus::msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK DOpus::msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case WM_COPYDATA:
|
case WM_COPYDATA:
|
||||||
{
|
{
|
||||||
auto cds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
|
auto cds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
|
||||||
auto buf = static_cast<PCHAR>(cds->lpData);
|
auto buf = static_cast<PCHAR>(cds->lpData);
|
||||||
|
|
||||||
pXmlBuffer = new CHAR[cds->cbData + 1]{'\0'};
|
pXmlBuffer = new CHAR[cds->cbData + 1]{'\0'};
|
||||||
memcpy(pXmlBuffer, buf, cds->cbData);
|
memcpy(pXmlBuffer, buf, cds->cbData);
|
||||||
|
|
||||||
SetEvent(hGetResultEvent);
|
SetEvent(hGetResultEvent);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -34,122 +34,122 @@ static WCHAR filePathBuffer[MAX_PATH] = {'\0'};
|
|||||||
|
|
||||||
void DialogHook::GetSelected(PWCHAR buffer)
|
void DialogHook::GetSelected(PWCHAR buffer)
|
||||||
{
|
{
|
||||||
if (HelperMethods::IsUWP())
|
if (HelperMethods::IsUWP())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto hwndfg = GetForegroundWindow();
|
auto hwndfg = GetForegroundWindow();
|
||||||
DWORD pid = 0;
|
DWORD pid = 0;
|
||||||
auto tid = GetWindowThreadProcessId(hwndfg, &pid);
|
auto tid = GetWindowThreadProcessId(hwndfg, &pid);
|
||||||
|
|
||||||
auto hProc = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid);
|
auto hProc = OpenProcess(PROCESS_QUERY_INFORMATION, false, pid);
|
||||||
if (hProc == nullptr)
|
if (hProc == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (WM_HOOK_NOTIFY == 0)
|
if (WM_HOOK_NOTIFY == 0)
|
||||||
WM_HOOK_NOTIFY = RegisterWindowMessage(L"WM_QUICKLOOK_HOOK_NOTIFY_MSG");
|
WM_HOOK_NOTIFY = RegisterWindowMessage(L"WM_QUICKLOOK_HOOK_NOTIFY_MSG");
|
||||||
|
|
||||||
BOOL isTargetWoW64 = false;
|
BOOL isTargetWoW64 = false;
|
||||||
if (!IsWow64Process(hProc, &isTargetWoW64))
|
if (!IsWow64Process(hProc, &isTargetWoW64))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CloseHandle(hProc);
|
CloseHandle(hProc);
|
||||||
|
|
||||||
BOOL isSelfWoW64 = false;
|
BOOL isSelfWoW64 = false;
|
||||||
if (!IsWow64Process(GetCurrentProcess(), &isSelfWoW64))
|
if (!IsWow64Process(GetCurrentProcess(), &isSelfWoW64))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// if QuickLook is 64bit and target is 32bit, obtain result from the helper
|
// if QuickLook is 64bit and target is 32bit, obtain result from the helper
|
||||||
if (isTargetWoW64 && !isSelfWoW64)
|
if (isTargetWoW64 && !isSelfWoW64)
|
||||||
{
|
{
|
||||||
GetSelectedFromWoW64HookHelper(buffer);
|
GetSelectedFromWoW64HookHelper(buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ghHook != nullptr)
|
if (ghHook != nullptr)
|
||||||
UnhookWindowsHookEx(ghHook);
|
UnhookWindowsHookEx(ghHook);
|
||||||
ghHook = SetWindowsHookEx(WH_CALLWNDPROC, static_cast<HOOKPROC>(MsgHookProc), ModuleFromAddress(MsgHookProc), tid);
|
ghHook = SetWindowsHookEx(WH_CALLWNDPROC, static_cast<HOOKPROC>(MsgHookProc), ModuleFromAddress(MsgHookProc), tid);
|
||||||
if (ghHook == nullptr)
|
if (ghHook == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SendMessage(hwndfg, WM_HOOK_NOTIFY, 0, 0);
|
SendMessage(hwndfg, WM_HOOK_NOTIFY, 0, 0);
|
||||||
|
|
||||||
GetLongPathName(filePathBuffer, buffer, MAX_PATH_EX);
|
GetLongPathName(filePathBuffer, buffer, MAX_PATH_EX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogHook::getSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer)
|
void DialogHook::getSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer)
|
||||||
{
|
{
|
||||||
CComPtr<IShellView> psv;
|
CComPtr<IShellView> psv;
|
||||||
if (FAILED(psb->QueryActiveShellView(&psv)))
|
if (FAILED(psb->QueryActiveShellView(&psv)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CComPtr<IDataObject> dao;
|
CComPtr<IDataObject> dao;
|
||||||
if (FAILED(psv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, reinterpret_cast<void**>(&dao))))
|
if (FAILED(psv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, reinterpret_cast<void**>(&dao))))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
return HelperMethods::ObtainFirstItem(dao, buffer);
|
return HelperMethods::ObtainFirstItem(dao, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DialogHook::GetSelectedFromWoW64HookHelper(PWCHAR buffer)
|
void DialogHook::GetSelectedFromWoW64HookHelper(PWCHAR buffer)
|
||||||
{
|
{
|
||||||
if (!WoW64HookHelper::CheckStatus())
|
if (!WoW64HookHelper::CheckStatus())
|
||||||
if (!WoW64HookHelper::Launch())
|
if (!WoW64HookHelper::Launch())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto hHelperWnd = FindWindowEx(HWND_MESSAGE, nullptr, WoW64HookHelper::GetMsgWindowClassName(), nullptr);
|
auto hHelperWnd = FindWindowEx(HWND_MESSAGE, nullptr, WoW64HookHelper::GetMsgWindowClassName(), nullptr);
|
||||||
if (hHelperWnd == nullptr)
|
if (hHelperWnd == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, MAX_PATH * sizeof WCHAR,
|
auto hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE, 0, MAX_PATH * sizeof WCHAR,
|
||||||
SHARED_MEM_NAME);
|
SHARED_MEM_NAME);
|
||||||
if (hMapFile == nullptr)
|
if (hMapFile == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto sharedBuffer = static_cast<PWCHAR>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, MAX_PATH * sizeof WCHAR));
|
auto sharedBuffer = static_cast<PWCHAR>(MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, MAX_PATH * sizeof WCHAR));
|
||||||
if (sharedBuffer == nullptr)
|
if (sharedBuffer == nullptr)
|
||||||
{
|
{
|
||||||
CloseHandle(hMapFile);
|
CloseHandle(hMapFile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendMessage(hHelperWnd, WM_HOOK_NOTIFY, 0, 0);
|
SendMessage(hHelperWnd, WM_HOOK_NOTIFY, 0, 0);
|
||||||
|
|
||||||
// the sharedBuffer should now ready
|
// the sharedBuffer should now ready
|
||||||
GetLongPathName(sharedBuffer, buffer, MAX_PATH_EX);
|
GetLongPathName(sharedBuffer, buffer, MAX_PATH_EX);
|
||||||
|
|
||||||
UnmapViewOfFile(sharedBuffer);
|
UnmapViewOfFile(sharedBuffer);
|
||||||
CloseHandle(hMapFile);
|
CloseHandle(hMapFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
HMODULE DialogHook::ModuleFromAddress(PVOID pv)
|
HMODULE DialogHook::ModuleFromAddress(PVOID pv)
|
||||||
{
|
{
|
||||||
MEMORY_BASIC_INFORMATION mbi;
|
MEMORY_BASIC_INFORMATION mbi;
|
||||||
return VirtualQuery(pv, &mbi, sizeof mbi) != 0 ? static_cast<HMODULE>(mbi.AllocationBase) : nullptr;
|
return VirtualQuery(pv, &mbi, sizeof mbi) != 0 ? static_cast<HMODULE>(mbi.AllocationBase) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT DialogHook::MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
LRESULT DialogHook::MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
if (nCode < 0)
|
if (nCode < 0)
|
||||||
goto CONTINUE;
|
goto CONTINUE;
|
||||||
|
|
||||||
auto pMSG = reinterpret_cast<CWPSTRUCT*>(lParam);
|
auto pMSG = reinterpret_cast<CWPSTRUCT*>(lParam);
|
||||||
|
|
||||||
// only response to WM_HOOK_NOTIFY
|
// only response to WM_HOOK_NOTIFY
|
||||||
if (pMSG->message != WM_HOOK_NOTIFY)
|
if (pMSG->message != WM_HOOK_NOTIFY)
|
||||||
goto CONTINUE;
|
goto CONTINUE;
|
||||||
|
|
||||||
UnhookWindowsHookEx(ghHook);
|
UnhookWindowsHookEx(ghHook);
|
||||||
ghHook = nullptr;
|
ghHook = nullptr;
|
||||||
|
|
||||||
// get current selected item
|
// get current selected item
|
||||||
auto psb = reinterpret_cast<IShellBrowser*>(SendMessage(GetForegroundWindow(), WM_USER + 7, 0, 0));
|
auto psb = reinterpret_cast<IShellBrowser*>(SendMessage(GetForegroundWindow(), WM_USER + 7, 0, 0));
|
||||||
if (psb == nullptr)
|
if (psb == nullptr)
|
||||||
goto CONTINUE;
|
goto CONTINUE;
|
||||||
|
|
||||||
getSelectedInternal(psb, filePathBuffer);
|
getSelectedInternal(psb, filePathBuffer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
CONTINUE:
|
CONTINUE:
|
||||||
return CallNextHookEx(ghHook, nCode, wParam, lParam);
|
return CallNextHookEx(ghHook, nCode, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
@@ -19,11 +19,11 @@
|
|||||||
class DialogHook
|
class DialogHook
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void GetSelected(PWCHAR buffer);
|
static void GetSelected(PWCHAR buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void getSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer);
|
static void getSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer);
|
||||||
static void GetSelectedFromWoW64HookHelper(PWCHAR buffer);
|
static void GetSelectedFromWoW64HookHelper(PWCHAR buffer);
|
||||||
static HMODULE ModuleFromAddress(PVOID pv);
|
static HMODULE ModuleFromAddress(PVOID pv);
|
||||||
static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam);
|
static LRESULT CALLBACK MsgHookProc(int nCode, WPARAM wParam, LPARAM lParam);
|
||||||
};
|
};
|
||||||
|
@@ -27,18 +27,18 @@
|
|||||||
EXPORT void Init()
|
EXPORT void Init()
|
||||||
{
|
{
|
||||||
#ifdef WIN64
|
#ifdef WIN64
|
||||||
WoW64HookHelper::Launch();
|
WoW64HookHelper::Launch();
|
||||||
#endif
|
#endif
|
||||||
DOpus::PrepareMessageWindow();
|
DOpus::PrepareMessageWindow();
|
||||||
MultiCommander::PrepareMessageWindow();
|
MultiCommander::PrepareMessageWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT Shell32::FocusedWindowType GetFocusedWindowType()
|
EXPORT Shell32::FocusedWindowType GetFocusedWindowType()
|
||||||
{
|
{
|
||||||
return Shell32::GetFocusedWindowType();
|
return Shell32::GetFocusedWindowType();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT void GetCurrentSelection(PWCHAR buffer)
|
EXPORT void GetCurrentSelection(PWCHAR buffer)
|
||||||
{
|
{
|
||||||
Shell32::GetCurrentSelection(buffer);
|
Shell32::GetCurrentSelection(buffer);
|
||||||
}
|
}
|
||||||
|
@@ -20,66 +20,66 @@
|
|||||||
|
|
||||||
void Everything::GetSelected(PWCHAR buffer)
|
void Everything::GetSelected(PWCHAR buffer)
|
||||||
{
|
{
|
||||||
auto hWinFG = GetForegroundWindow();
|
auto hWinFG = GetForegroundWindow();
|
||||||
|
|
||||||
// Everything v1.5 IPC via hidden window.
|
// Everything v1.5 IPC via hidden window.
|
||||||
HWND hWinI = FindWindowExW(hWinFG, NULL, EVERYTHING_IPC_HIDDEN_WIN_CLASS, NULL);
|
HWND hWinI = FindWindowExW(hWinFG, NULL, EVERYTHING_IPC_HIDDEN_WIN_CLASS, NULL);
|
||||||
|
|
||||||
if (hWinI != nullptr) {
|
if (hWinI != nullptr) {
|
||||||
int pLength = GetWindowTextLength(hWinI);
|
int pLength = GetWindowTextLength(hWinI);
|
||||||
wchar_t* pText = new wchar_t[pLength + 1];
|
wchar_t* pText = new wchar_t[pLength + 1];
|
||||||
GetWindowText(hWinI, pText, pLength + 1);
|
GetWindowText(hWinI, pText, pLength + 1);
|
||||||
wcsncpy_s(buffer, MAX_PATH_EX, pText, pLength);
|
wcsncpy_s(buffer, MAX_PATH_EX, pText, pLength);
|
||||||
return; // Success. Clipboard access unnecessary.
|
return; // Success. Clipboard access unnecessary.
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND hWin = FindWindowW(EVERYTHING_IPC_WINDOW_CLASS, NULL);
|
HWND hWin = FindWindowW(EVERYTHING_IPC_WINDOW_CLASS, NULL);
|
||||||
|
|
||||||
if (hWin != nullptr) {
|
if (hWin != nullptr) {
|
||||||
// Everything IPC Clipboard
|
// Everything IPC Clipboard
|
||||||
SendMessageW(
|
SendMessageW(
|
||||||
hWin,
|
hWin,
|
||||||
WM_COMMAND,
|
WM_COMMAND,
|
||||||
MAKEWPARAM(EVERYTHING_IPC_COPY_TO_CLIPBOARD, 0),
|
MAKEWPARAM(EVERYTHING_IPC_COPY_TO_CLIPBOARD, 0),
|
||||||
0);
|
0);
|
||||||
|
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
|
|
||||||
if (!OpenClipboard(nullptr))
|
if (!OpenClipboard(nullptr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto hData = GetClipboardData(CF_UNICODETEXT);
|
auto hData = GetClipboardData(CF_UNICODETEXT);
|
||||||
if (hData == nullptr)
|
if (hData == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto pText = static_cast<PWCHAR>(GlobalLock(hData));
|
auto pText = static_cast<PWCHAR>(GlobalLock(hData));
|
||||||
if (pText == nullptr)
|
if (pText == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto p = wcsstr(pText, L"\r\n");
|
auto p = wcsstr(pText, L"\r\n");
|
||||||
auto l = p == nullptr ? wcslen(pText) : p - pText;
|
auto l = p == nullptr ? wcslen(pText) : p - pText;
|
||||||
wcsncpy_s(buffer, MAX_PATH_EX, pText, l); // Everything supports Long Path
|
wcsncpy_s(buffer, MAX_PATH_EX, pText, l); // Everything supports Long Path
|
||||||
|
|
||||||
GlobalUnlock(hData);
|
GlobalUnlock(hData);
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Everything::MatchClass(PWCHAR classBuffer)
|
bool Everything::MatchClass(PWCHAR classBuffer)
|
||||||
{
|
{
|
||||||
WCHAR sMatchC[256] = { '\0' };
|
WCHAR sMatchC[256] = { '\0' };
|
||||||
WCHAR sMatchS[256] = EVERYTHING_IPC_WINDOW_CLASS;
|
WCHAR sMatchS[256] = EVERYTHING_IPC_WINDOW_CLASS;
|
||||||
size_t iLen = wcslen(sMatchS);
|
size_t iLen = wcslen(sMatchS);
|
||||||
wcsncpy_s(sMatchC, classBuffer, iLen);
|
wcsncpy_s(sMatchC, classBuffer, iLen);
|
||||||
return (0 == wcscmp(sMatchC, sMatchS));
|
return (0 == wcscmp(sMatchC, sMatchS));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Everything::backupClipboard()
|
void Everything::backupClipboard()
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
void Everything::restoreClipboard()
|
void Everything::restoreClipboard()
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
@@ -15,18 +15,18 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#define EVERYTHING_IPC_HIDDEN_WIN_CLASS L"EVERYTHING_RESULT_LIST_FOCUS"
|
#define EVERYTHING_IPC_HIDDEN_WIN_CLASS L"EVERYTHING_RESULT_LIST_FOCUS"
|
||||||
#define EVERYTHING_IPC_WINDOW_CLASS L"EVERYTHING"
|
#define EVERYTHING_IPC_WINDOW_CLASS L"EVERYTHING"
|
||||||
#define EVERYTHING_IPC_COPY_TO_CLIPBOARD 41007
|
#define EVERYTHING_IPC_COPY_TO_CLIPBOARD 41007
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
class Everything
|
class Everything
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void GetSelected(PWCHAR buffer);
|
static void GetSelected(PWCHAR buffer);
|
||||||
static bool MatchClass(PWCHAR classBuffer);
|
static bool MatchClass(PWCHAR classBuffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void backupClipboard();
|
static void backupClipboard();
|
||||||
static void restoreClipboard();
|
static void restoreClipboard();
|
||||||
};
|
};
|
||||||
|
@@ -20,114 +20,114 @@
|
|||||||
|
|
||||||
void HelperMethods::GetSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer)
|
void HelperMethods::GetSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer)
|
||||||
{
|
{
|
||||||
CComPtr<IShellView> psv;
|
CComPtr<IShellView> psv;
|
||||||
if (FAILED(psb->QueryActiveShellView(&psv)))
|
if (FAILED(psb->QueryActiveShellView(&psv)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CComPtr<IDataObject> dao;
|
CComPtr<IDataObject> dao;
|
||||||
if (FAILED(psv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, reinterpret_cast<void**>(&dao))))
|
if (FAILED(psv->GetItemObject(SVGIO_SELECTION, IID_IDataObject, reinterpret_cast<void**>(&dao))))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
return ObtainFirstItem(dao, buffer);
|
return ObtainFirstItem(dao, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HelperMethods::ObtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer)
|
void HelperMethods::ObtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer)
|
||||||
{
|
{
|
||||||
FORMATETC formatetc;
|
FORMATETC formatetc;
|
||||||
STGMEDIUM medium = {sizeof medium};
|
STGMEDIUM medium = {sizeof medium};
|
||||||
|
|
||||||
formatetc.cfFormat = CF_HDROP;
|
formatetc.cfFormat = CF_HDROP;
|
||||||
formatetc.ptd = nullptr;
|
formatetc.ptd = nullptr;
|
||||||
formatetc.dwAspect = DVASPECT_CONTENT;
|
formatetc.dwAspect = DVASPECT_CONTENT;
|
||||||
formatetc.lindex = -1;
|
formatetc.lindex = -1;
|
||||||
formatetc.tymed = TYMED_HGLOBAL;
|
formatetc.tymed = TYMED_HGLOBAL;
|
||||||
|
|
||||||
medium.tymed = TYMED_HGLOBAL;
|
medium.tymed = TYMED_HGLOBAL;
|
||||||
|
|
||||||
if (FAILED(dao->GetData(&formatetc, &medium)))
|
if (FAILED(dao->GetData(&formatetc, &medium)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int n = DragQueryFile(HDROP(medium.hGlobal), 0xFFFFFFFF, nullptr, 0);
|
int n = DragQueryFile(HDROP(medium.hGlobal), 0xFFFFFFFF, nullptr, 0);
|
||||||
|
|
||||||
if (n < 1)
|
if (n < 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WCHAR localBuffer[MAX_PATH] = { '\0' };
|
WCHAR localBuffer[MAX_PATH] = { '\0' };
|
||||||
DragQueryFile(HDROP(medium.hGlobal), 0, localBuffer, MAX_PATH);
|
DragQueryFile(HDROP(medium.hGlobal), 0, localBuffer, MAX_PATH);
|
||||||
|
|
||||||
GetLongPathName(localBuffer, buffer, MAX_PATH_EX);
|
GetLongPathName(localBuffer, buffer, MAX_PATH_EX);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HelperMethods::IsListaryToolbarVisible()
|
bool HelperMethods::IsListaryToolbarVisible()
|
||||||
{
|
{
|
||||||
auto CALLBACK findListaryWindowProc = [](__in HWND hwnd, __in LPARAM lParam)-> BOOL
|
auto CALLBACK findListaryWindowProc = [](__in HWND hwnd, __in LPARAM lParam)-> BOOL
|
||||||
{
|
{
|
||||||
WCHAR classBuffer[MAX_PATH] = {'\0'};
|
WCHAR classBuffer[MAX_PATH] = {'\0'};
|
||||||
if (FAILED(GetClassName(hwnd, classBuffer, MAX_PATH)))
|
if (FAILED(GetClassName(hwnd, classBuffer, MAX_PATH)))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (wcsncmp(classBuffer, L"Listary_WidgetWin_", 18) == 0)
|
if (wcsncmp(classBuffer, L"Listary_WidgetWin_", 18) == 0)
|
||||||
{
|
{
|
||||||
if (IsWindowVisible(hwnd))
|
if (IsWindowVisible(hwnd))
|
||||||
{
|
{
|
||||||
*reinterpret_cast<bool*>(lParam) = true;
|
*reinterpret_cast<bool*>(lParam) = true;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto found = false;
|
auto found = false;
|
||||||
EnumWindows(findListaryWindowProc, reinterpret_cast<LPARAM>(&found));
|
EnumWindows(findListaryWindowProc, reinterpret_cast<LPARAM>(&found));
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Windows 10 1909 replaced the search box in the File Explorer by a UWP control.
|
// Windows 10 1909 replaced the search box in the File Explorer by a UWP control.
|
||||||
// gti.flags is always 0 for UWP applications.
|
// gti.flags is always 0 for UWP applications.
|
||||||
bool HelperMethods::IsExplorerSearchBoxFocused()
|
bool HelperMethods::IsExplorerSearchBoxFocused()
|
||||||
{
|
{
|
||||||
auto* hwnd = GetFocusedControl();
|
auto* hwnd = GetFocusedControl();
|
||||||
|
|
||||||
WCHAR classBuffer[MAX_PATH] = { '\0' };
|
WCHAR classBuffer[MAX_PATH] = { '\0' };
|
||||||
if (FAILED(GetClassName(hwnd, classBuffer, MAX_PATH)))
|
if (FAILED(GetClassName(hwnd, classBuffer, MAX_PATH)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return wcscmp(classBuffer, L"Windows.UI.Core.CoreWindow") == 0;
|
return wcscmp(classBuffer, L"Windows.UI.Core.CoreWindow") == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HelperMethods::IsCursorActivated(HWND hwnd)
|
bool HelperMethods::IsCursorActivated(HWND hwnd)
|
||||||
{
|
{
|
||||||
auto tId = GetWindowThreadProcessId(hwnd, nullptr);
|
auto tId = GetWindowThreadProcessId(hwnd, nullptr);
|
||||||
|
|
||||||
GUITHREADINFO gti = { sizeof gti };
|
GUITHREADINFO gti = { sizeof gti };
|
||||||
GetGUIThreadInfo(tId, >i);
|
GetGUIThreadInfo(tId, >i);
|
||||||
|
|
||||||
return gti.flags || gti.hwndCaret || IsListaryToolbarVisible();
|
return gti.flags || gti.hwndCaret || IsListaryToolbarVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HelperMethods::IsUWP()
|
bool HelperMethods::IsUWP()
|
||||||
{
|
{
|
||||||
auto pGCPFN = decltype(&GetCurrentPackageFullName)(
|
auto pGCPFN = decltype(&GetCurrentPackageFullName)(
|
||||||
GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetCurrentPackageFullName"));
|
GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetCurrentPackageFullName"));
|
||||||
|
|
||||||
if (!pGCPFN)
|
if (!pGCPFN)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
UINT32 pn = 0;
|
UINT32 pn = 0;
|
||||||
return pGCPFN(&pn, nullptr) == ERROR_INSUFFICIENT_BUFFER;
|
return pGCPFN(&pn, nullptr) == ERROR_INSUFFICIENT_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND HelperMethods::GetFocusedControl()
|
HWND HelperMethods::GetFocusedControl()
|
||||||
{
|
{
|
||||||
auto tid = GetWindowThreadProcessId(GetForegroundWindow(), nullptr);
|
auto tid = GetWindowThreadProcessId(GetForegroundWindow(), nullptr);
|
||||||
|
|
||||||
if (0 == AttachThreadInput(GetCurrentThreadId(), tid, TRUE))
|
if (0 == AttachThreadInput(GetCurrentThreadId(), tid, TRUE))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto* hwnd = GetFocus();
|
auto* hwnd = GetFocus();
|
||||||
|
|
||||||
AttachThreadInput(GetCurrentThreadId(), tid, FALSE);
|
AttachThreadInput(GetCurrentThreadId(), tid, FALSE);
|
||||||
|
|
||||||
return hwnd;
|
return hwnd;
|
||||||
}
|
}
|
||||||
|
@@ -19,13 +19,13 @@
|
|||||||
class HelperMethods
|
class HelperMethods
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void GetSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer);
|
static void GetSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer);
|
||||||
static void ObtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer);
|
static void ObtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer);
|
||||||
static bool IsCursorActivated(HWND hwndfg);
|
static bool IsCursorActivated(HWND hwndfg);
|
||||||
static bool IsExplorerSearchBoxFocused();
|
static bool IsExplorerSearchBoxFocused();
|
||||||
static bool HelperMethods::IsUWP();
|
static bool HelperMethods::IsUWP();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool IsListaryToolbarVisible();
|
static bool IsListaryToolbarVisible();
|
||||||
static HWND GetFocusedControl();
|
static HWND GetFocusedControl();
|
||||||
};
|
};
|
||||||
|
@@ -27,9 +27,9 @@ void MultiCommander::GetSelected(PWCHAR buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
COPYDATASTRUCT cds;
|
COPYDATASTRUCT cds;
|
||||||
cds.dwData = MULTICMD_CPF_GETCURITEMFULL | MULTICMD_CPF_SOURCE;
|
cds.dwData = MULTICMD_CPF_GETCURITEMFULL | MULTICMD_CPF_SOURCE;
|
||||||
cds.cbData = 0;
|
cds.cbData = 0;
|
||||||
cds.lpData = nullptr;
|
cds.lpData = nullptr;
|
||||||
|
|
||||||
ResetEvent(hGetResultEvent);
|
ResetEvent(hGetResultEvent);
|
||||||
|
|
||||||
@@ -37,12 +37,12 @@ void MultiCommander::GetSelected(PWCHAR buffer)
|
|||||||
FindWindow(MULTICMD_CLASS, nullptr),
|
FindWindow(MULTICMD_CLASS, nullptr),
|
||||||
WM_COPYDATA,
|
WM_COPYDATA,
|
||||||
reinterpret_cast<WPARAM>(hMsgWnd),
|
reinterpret_cast<WPARAM>(hMsgWnd),
|
||||||
reinterpret_cast<LPARAM>(&cds)
|
reinterpret_cast<LPARAM>(&cds)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!ret || WAIT_OBJECT_0 != WaitForSingleObject(hGetResultEvent, 2000)) {
|
if (!ret || WAIT_OBJECT_0 != WaitForSingleObject(hGetResultEvent, 2000)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto path = reinterpret_cast<PWCHAR>(pCurrentItemPath);
|
auto path = reinterpret_cast<PWCHAR>(pCurrentItemPath);
|
||||||
wcscpy_s(buffer, wcslen(path) + 1, path);
|
wcscpy_s(buffer, wcslen(path) + 1, path);
|
||||||
@@ -78,21 +78,21 @@ bool MultiCommander::PrepareMessageWindow()
|
|||||||
LRESULT CALLBACK MultiCommander::msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK MultiCommander::msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
switch (uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
case WM_COPYDATA:
|
case WM_COPYDATA:
|
||||||
{
|
{
|
||||||
delete[] pCurrentItemPath;
|
delete[] pCurrentItemPath;
|
||||||
|
|
||||||
auto cds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
|
auto cds = reinterpret_cast<PCOPYDATASTRUCT>(lParam);
|
||||||
auto buf = static_cast<PCHAR>(cds->lpData);
|
auto buf = static_cast<PCHAR>(cds->lpData);
|
||||||
|
|
||||||
pCurrentItemPath = new CHAR[cds->cbData + 1]{ '\0' };
|
pCurrentItemPath = new CHAR[cds->cbData + 1]{ '\0' };
|
||||||
memcpy(pCurrentItemPath, buf, cds->cbData);
|
memcpy(pCurrentItemPath, buf, cds->cbData);
|
||||||
|
|
||||||
SetEvent(hGetResultEvent);
|
SetEvent(hGetResultEvent);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,13 +24,13 @@
|
|||||||
class MultiCommander
|
class MultiCommander
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void GetSelected(PWCHAR buffer);
|
static void GetSelected(PWCHAR buffer);
|
||||||
static bool PrepareMessageWindow();
|
static bool PrepareMessageWindow();
|
||||||
MultiCommander() = delete;
|
MultiCommander() = delete;
|
||||||
private:
|
private:
|
||||||
static HWND hMsgWnd;
|
static HWND hMsgWnd;
|
||||||
static HANDLE hGetResultEvent;
|
static HANDLE hGetResultEvent;
|
||||||
static PCHAR pCurrentItemPath;
|
static PCHAR pCurrentItemPath;
|
||||||
|
|
||||||
static LRESULT CALLBACK msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
static LRESULT CALLBACK msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||||
};
|
};
|
||||||
|
@@ -28,157 +28,157 @@ using namespace std;
|
|||||||
|
|
||||||
Shell32::FocusedWindowType Shell32::GetFocusedWindowType()
|
Shell32::FocusedWindowType Shell32::GetFocusedWindowType()
|
||||||
{
|
{
|
||||||
auto hwndfg = GetForegroundWindow();
|
auto hwndfg = GetForegroundWindow();
|
||||||
|
|
||||||
if (HelperMethods::IsCursorActivated(hwndfg))
|
if (HelperMethods::IsCursorActivated(hwndfg))
|
||||||
return INVALID;
|
return INVALID;
|
||||||
|
|
||||||
WCHAR classBuffer[MAX_PATH] = { '\0' };
|
WCHAR classBuffer[MAX_PATH] = { '\0' };
|
||||||
if (FAILED(GetClassName(hwndfg, classBuffer, MAX_PATH)))
|
if (FAILED(GetClassName(hwndfg, classBuffer, MAX_PATH)))
|
||||||
return INVALID;
|
return INVALID;
|
||||||
|
|
||||||
if (wcscmp(classBuffer, MULTICMD_CLASS) == 0)
|
if (wcscmp(classBuffer, MULTICMD_CLASS) == 0)
|
||||||
{
|
{
|
||||||
return MULTICOMMANDER;
|
return MULTICOMMANDER;
|
||||||
}
|
}
|
||||||
if (wcscmp(classBuffer, L"dopus.lister") == 0)
|
if (wcscmp(classBuffer, L"dopus.lister") == 0)
|
||||||
{
|
{
|
||||||
return DOPUS;
|
return DOPUS;
|
||||||
}
|
}
|
||||||
if (Everything::MatchClass(classBuffer))
|
if (Everything::MatchClass(classBuffer))
|
||||||
{
|
{
|
||||||
return EVERYTHING;
|
return EVERYTHING;
|
||||||
}
|
}
|
||||||
if (wcscmp(classBuffer, L"WorkerW") == 0 || wcscmp(classBuffer, L"Progman") == 0)
|
if (wcscmp(classBuffer, L"WorkerW") == 0 || wcscmp(classBuffer, L"Progman") == 0)
|
||||||
{
|
{
|
||||||
if (FindWindowEx(hwndfg, nullptr, L"SHELLDLL_DefView", nullptr) != nullptr)
|
if (FindWindowEx(hwndfg, nullptr, L"SHELLDLL_DefView", nullptr) != nullptr)
|
||||||
{
|
{
|
||||||
return DESKTOP;
|
return DESKTOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (wcscmp(classBuffer, L"ExploreWClass") == 0 || wcscmp(classBuffer, L"CabinetWClass") == 0)
|
if (wcscmp(classBuffer, L"ExploreWClass") == 0 || wcscmp(classBuffer, L"CabinetWClass") == 0)
|
||||||
{
|
{
|
||||||
if (!HelperMethods::IsExplorerSearchBoxFocused())
|
if (!HelperMethods::IsExplorerSearchBoxFocused())
|
||||||
{
|
{
|
||||||
return EXPLORER;
|
return EXPLORER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (wcscmp(classBuffer, L"#32770") == 0)
|
if (wcscmp(classBuffer, L"#32770") == 0)
|
||||||
{
|
{
|
||||||
if (FindWindowEx(hwndfg, nullptr, L"DUIViewWndClassName", nullptr) != nullptr)
|
if (FindWindowEx(hwndfg, nullptr, L"DUIViewWndClassName", nullptr) != nullptr)
|
||||||
{
|
{
|
||||||
if (!HelperMethods::IsExplorerSearchBoxFocused())
|
if (!HelperMethods::IsExplorerSearchBoxFocused())
|
||||||
{
|
{
|
||||||
return DIALOG;
|
return DIALOG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return INVALID;
|
return INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shell32::GetCurrentSelection(PWCHAR buffer)
|
void Shell32::GetCurrentSelection(PWCHAR buffer)
|
||||||
{
|
{
|
||||||
switch (GetFocusedWindowType())
|
switch (GetFocusedWindowType())
|
||||||
{
|
{
|
||||||
case DESKTOP:
|
case DESKTOP:
|
||||||
getSelectedFromDesktop(buffer);
|
getSelectedFromDesktop(buffer);
|
||||||
break;
|
break;
|
||||||
case EXPLORER:
|
case EXPLORER:
|
||||||
getSelectedFromExplorer(buffer);
|
getSelectedFromExplorer(buffer);
|
||||||
break;
|
break;
|
||||||
case DIALOG:
|
case DIALOG:
|
||||||
DialogHook::GetSelected(buffer);
|
DialogHook::GetSelected(buffer);
|
||||||
break;
|
break;
|
||||||
case EVERYTHING:
|
case EVERYTHING:
|
||||||
Everything::GetSelected(buffer);
|
Everything::GetSelected(buffer);
|
||||||
break;
|
break;
|
||||||
case DOPUS:
|
case DOPUS:
|
||||||
DOpus::GetSelected(buffer);
|
DOpus::GetSelected(buffer);
|
||||||
break;
|
break;
|
||||||
case MULTICOMMANDER:
|
case MULTICOMMANDER:
|
||||||
MultiCommander::GetSelected(buffer);
|
MultiCommander::GetSelected(buffer);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shell32::getSelectedFromExplorer(PWCHAR buffer)
|
void Shell32::getSelectedFromExplorer(PWCHAR buffer)
|
||||||
{
|
{
|
||||||
CoInitialize(nullptr);
|
CoInitialize(nullptr);
|
||||||
|
|
||||||
CComPtr<IShellWindows> psw;
|
CComPtr<IShellWindows> psw;
|
||||||
if (FAILED(psw.CoCreateInstance(CLSID_ShellWindows)))
|
if (FAILED(psw.CoCreateInstance(CLSID_ShellWindows)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto hwndfgw = GetForegroundWindow();
|
auto hwndfgw = GetForegroundWindow();
|
||||||
auto hwndfgt = FindWindowEx(hwndfgw, nullptr, L"ShellTabWindowClass", nullptr);
|
auto hwndfgt = FindWindowEx(hwndfgw, nullptr, L"ShellTabWindowClass", nullptr);
|
||||||
|
|
||||||
auto count = 0L;
|
auto count = 0L;
|
||||||
psw->get_Count(&count);
|
psw->get_Count(&count);
|
||||||
|
|
||||||
for (auto i = 0; i < count; i++)
|
for (auto i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
VARIANT vi;
|
VARIANT vi;
|
||||||
VariantInit(&vi);
|
VariantInit(&vi);
|
||||||
V_VT(&vi) = VT_I4;
|
V_VT(&vi) = VT_I4;
|
||||||
V_I4(&vi) = i;
|
V_I4(&vi) = i;
|
||||||
|
|
||||||
CComPtr<IDispatch> pdisp;
|
CComPtr<IDispatch> pdisp;
|
||||||
if (S_OK != psw->Item(vi, &pdisp))
|
if (S_OK != psw->Item(vi, &pdisp))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CComPtr<IServiceProvider> psp;
|
CComPtr<IServiceProvider> psp;
|
||||||
if (FAILED(pdisp->QueryInterface(IID_IServiceProvider, reinterpret_cast<void**>(&psp))))
|
if (FAILED(pdisp->QueryInterface(IID_IServiceProvider, reinterpret_cast<void**>(&psp))))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CComPtr<IShellBrowser> psb;
|
CComPtr<IShellBrowser> psb;
|
||||||
if (FAILED(psp->QueryService(IID_IShellBrowser, IID_IShellBrowser, reinterpret_cast<LPVOID*>(&psb))))
|
if (FAILED(psp->QueryService(IID_IShellBrowser, IID_IShellBrowser, reinterpret_cast<LPVOID*>(&psb))))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
HWND phwnd;
|
HWND phwnd;
|
||||||
if (FAILED(psb->GetWindow(&phwnd)))
|
if (FAILED(psb->GetWindow(&phwnd)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (hwndfgw != phwnd && (hwndfgt != nullptr && hwndfgt != phwnd))
|
if (hwndfgw != phwnd && (hwndfgt != nullptr && hwndfgt != phwnd))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (HelperMethods::IsCursorActivated(0))
|
if (HelperMethods::IsCursorActivated(0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
HelperMethods::GetSelectedInternal(psb, buffer);
|
HelperMethods::GetSelectedInternal(psb, buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shell32::getSelectedFromDesktop(PWCHAR buffer)
|
void Shell32::getSelectedFromDesktop(PWCHAR buffer)
|
||||||
{
|
{
|
||||||
CoInitialize(nullptr);
|
CoInitialize(nullptr);
|
||||||
|
|
||||||
CComPtr<IShellWindows> psw;
|
CComPtr<IShellWindows> psw;
|
||||||
CComPtr<IWebBrowserApp> pwba;
|
CComPtr<IWebBrowserApp> pwba;
|
||||||
|
|
||||||
if (FAILED(psw.CoCreateInstance(CLSID_ShellWindows)))
|
if (FAILED(psw.CoCreateInstance(CLSID_ShellWindows)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VARIANT pvarLoc;
|
VARIANT pvarLoc;
|
||||||
VariantInit(&pvarLoc);
|
VariantInit(&pvarLoc);
|
||||||
long phwnd;
|
long phwnd;
|
||||||
if (FAILED(psw->FindWindowSW(&pvarLoc, &pvarLoc, SWC_DESKTOP, &phwnd, SWFO_NEEDDISPATCH, reinterpret_cast<IDispatch**>(
|
if (FAILED(psw->FindWindowSW(&pvarLoc, &pvarLoc, SWC_DESKTOP, &phwnd, SWFO_NEEDDISPATCH, reinterpret_cast<IDispatch**>(
|
||||||
&pwba))))
|
&pwba))))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (HelperMethods::IsCursorActivated(reinterpret_cast<HWND>(LongToHandle(phwnd))))
|
if (HelperMethods::IsCursorActivated(reinterpret_cast<HWND>(LongToHandle(phwnd))))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CComPtr<IServiceProvider> psp;
|
CComPtr<IServiceProvider> psp;
|
||||||
if (FAILED(pwba->QueryInterface(IID_IServiceProvider, reinterpret_cast<void**>(&psp))))
|
if (FAILED(pwba->QueryInterface(IID_IServiceProvider, reinterpret_cast<void**>(&psp))))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CComPtr<IShellBrowser> psb;
|
CComPtr<IShellBrowser> psb;
|
||||||
if (FAILED(psp->QueryService(IID_IShellBrowser, IID_IShellBrowser, reinterpret_cast<LPVOID*>(&psb))))
|
if (FAILED(psp->QueryService(IID_IShellBrowser, IID_IShellBrowser, reinterpret_cast<LPVOID*>(&psb))))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
HelperMethods::GetSelectedInternal(psb, buffer);
|
HelperMethods::GetSelectedInternal(psb, buffer);
|
||||||
}
|
}
|
||||||
|
@@ -22,21 +22,21 @@
|
|||||||
class Shell32
|
class Shell32
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum FocusedWindowType
|
enum FocusedWindowType
|
||||||
{
|
{
|
||||||
INVALID,
|
INVALID,
|
||||||
DESKTOP,
|
DESKTOP,
|
||||||
EXPLORER,
|
EXPLORER,
|
||||||
DIALOG,
|
DIALOG,
|
||||||
EVERYTHING,
|
EVERYTHING,
|
||||||
DOPUS,
|
DOPUS,
|
||||||
MULTICOMMANDER,
|
MULTICOMMANDER,
|
||||||
};
|
};
|
||||||
|
|
||||||
static FocusedWindowType GetFocusedWindowType();
|
static FocusedWindowType GetFocusedWindowType();
|
||||||
static void GetCurrentSelection(PWCHAR buffer);
|
static void GetCurrentSelection(PWCHAR buffer);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void getSelectedFromDesktop(PWCHAR buffer);
|
static void getSelectedFromDesktop(PWCHAR buffer);
|
||||||
static void getSelectedFromExplorer(PWCHAR buffer);
|
static void getSelectedFromExplorer(PWCHAR buffer);
|
||||||
};
|
};
|
||||||
|
@@ -27,54 +27,54 @@ HANDLE hJob = nullptr;
|
|||||||
|
|
||||||
bool WoW64HookHelper::CheckStatus()
|
bool WoW64HookHelper::CheckStatus()
|
||||||
{
|
{
|
||||||
DWORD running = -1;
|
DWORD running = -1;
|
||||||
GetExitCodeProcess(hHelper, &running);
|
GetExitCodeProcess(hHelper, &running);
|
||||||
return running == STILL_ACTIVE;
|
return running == STILL_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WoW64HookHelper::Launch()
|
bool WoW64HookHelper::Launch()
|
||||||
{
|
{
|
||||||
#ifndef WIN64
|
#ifndef WIN64
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (HelperMethods::IsUWP())
|
if (HelperMethods::IsUWP())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (CheckStatus())
|
if (CheckStatus())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
createJob();
|
createJob();
|
||||||
|
|
||||||
WCHAR fullPath[MAX_PATH] = {'\0'};
|
WCHAR fullPath[MAX_PATH] = {'\0'};
|
||||||
GetModuleFileName(nullptr, fullPath, MAX_PATH - 1);
|
GetModuleFileName(nullptr, fullPath, MAX_PATH - 1);
|
||||||
auto p = wcsrchr(fullPath, L'\\');
|
auto p = wcsrchr(fullPath, L'\\');
|
||||||
memcpy(p, HELPER_FILE, wcslen(HELPER_FILE) * sizeof WCHAR);
|
memcpy(p, HELPER_FILE, wcslen(HELPER_FILE) * sizeof WCHAR);
|
||||||
|
|
||||||
STARTUPINFO si = {sizeof si};
|
STARTUPINFO si = {sizeof si};
|
||||||
PROCESS_INFORMATION pi = {nullptr};
|
PROCESS_INFORMATION pi = {nullptr};
|
||||||
si.cb = sizeof si;
|
si.cb = sizeof si;
|
||||||
|
|
||||||
CreateProcess(fullPath, RUN_ARG, nullptr, nullptr, false, 0, nullptr, nullptr, &si, &pi);
|
CreateProcess(fullPath, RUN_ARG, nullptr, nullptr, false, 0, nullptr, nullptr, &si, &pi);
|
||||||
hHelper = pi.hProcess;
|
hHelper = pi.hProcess;
|
||||||
|
|
||||||
AssignProcessToJobObject(hJob, hHelper);
|
AssignProcessToJobObject(hJob, hHelper);
|
||||||
|
|
||||||
return CheckStatus();
|
return CheckStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WoW64HookHelper::createJob()
|
void WoW64HookHelper::createJob()
|
||||||
{
|
{
|
||||||
if (hJob != nullptr)
|
if (hJob != nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hJob = CreateJobObject(nullptr, nullptr);
|
hJob = CreateJobObject(nullptr, nullptr);
|
||||||
|
|
||||||
JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation = {sizeof BasicLimitInformation};
|
JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation = {sizeof BasicLimitInformation};
|
||||||
BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION lpJobObjectInfo = {sizeof lpJobObjectInfo};
|
JOBOBJECT_EXTENDED_LIMIT_INFORMATION lpJobObjectInfo = {sizeof lpJobObjectInfo};
|
||||||
lpJobObjectInfo.BasicLimitInformation = BasicLimitInformation;
|
lpJobObjectInfo.BasicLimitInformation = BasicLimitInformation;
|
||||||
|
|
||||||
SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &lpJobObjectInfo,
|
SetInformationJobObject(hJob, JobObjectExtendedLimitInformation, &lpJobObjectInfo,
|
||||||
sizeof JOBOBJECT_EXTENDED_LIMIT_INFORMATION);
|
sizeof JOBOBJECT_EXTENDED_LIMIT_INFORMATION);
|
||||||
}
|
}
|
||||||
|
@@ -22,14 +22,14 @@
|
|||||||
class WoW64HookHelper
|
class WoW64HookHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static PWCHAR GetMsgWindowClassName()
|
static PWCHAR GetMsgWindowClassName()
|
||||||
{
|
{
|
||||||
return L"QUICKLOOK_WOW64HOOKHELPER_MSG_CLASS";
|
return L"QUICKLOOK_WOW64HOOKHELPER_MSG_CLASS";
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool CheckStatus();
|
static bool CheckStatus();
|
||||||
static bool Launch();
|
static bool Launch();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void createJob();
|
static void createJob();
|
||||||
};
|
};
|
||||||
|
@@ -20,14 +20,14 @@
|
|||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||||
{
|
{
|
||||||
switch (ul_reason_for_call)
|
switch (ul_reason_for_call)
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -38,67 +38,67 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
|
|||||||
_In_ LPWSTR lpCmdLine,
|
_In_ LPWSTR lpCmdLine,
|
||||||
_In_ int nCmdShow)
|
_In_ int nCmdShow)
|
||||||
{
|
{
|
||||||
// do not run when double-clicking
|
// do not run when double-clicking
|
||||||
if (wcsstr(GetCommandLine(), RUN_ARG) == nullptr)
|
if (wcsstr(GetCommandLine(), RUN_ARG) == nullptr)
|
||||||
{
|
{
|
||||||
MessageBox(nullptr, L"This executable is not designed to launch directly.", L"QuickLook.WoW64HookHelper", 0);
|
MessageBox(nullptr, L"This executable is not designed to launch directly.", L"QuickLook.WoW64HookHelper", 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pDll = LoadLibrary(L"QuickLook.Native32.dll");
|
pDll = LoadLibrary(L"QuickLook.Native32.dll");
|
||||||
pGCS = reinterpret_cast<PGCS>(GetProcAddress(pDll, "GetCurrentSelection"));
|
pGCS = reinterpret_cast<PGCS>(GetProcAddress(pDll, "GetCurrentSelection"));
|
||||||
|
|
||||||
WM_HOOK_NOTIFY = RegisterWindowMessage(L"WM_QUICKLOOK_HOOK_NOTIFY_MSG");
|
WM_HOOK_NOTIFY = RegisterWindowMessage(L"WM_QUICKLOOK_HOOK_NOTIFY_MSG");
|
||||||
|
|
||||||
WNDCLASS wc = {};
|
WNDCLASS wc = {};
|
||||||
wc.lpfnWndProc = WndProc;
|
wc.lpfnWndProc = WndProc;
|
||||||
wc.lpszClassName = MSG_WINDOW_CLASS;
|
wc.lpszClassName = MSG_WINDOW_CLASS;
|
||||||
if (!RegisterClass(&wc))
|
if (!RegisterClass(&wc))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
hMsgWindow = CreateWindow(MSG_WINDOW_CLASS, nullptr, 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr);
|
hMsgWindow = CreateWindow(MSG_WINDOW_CLASS, nullptr, 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr);
|
||||||
if (hMsgWindow == nullptr)
|
if (hMsgWindow == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
MSG msg;
|
MSG msg;
|
||||||
while (GetMessage(&msg, nullptr, 0, 0) > 0)
|
while (GetMessage(&msg, nullptr, 0, 0) > 0)
|
||||||
{
|
{
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
return msg.wParam;
|
return msg.wParam;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
if (msg == WM_HOOK_NOTIFY)
|
if (msg == WM_HOOK_NOTIFY)
|
||||||
{
|
{
|
||||||
GetCurrentSelection();
|
GetCurrentSelection();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetCurrentSelection()
|
void GetCurrentSelection()
|
||||||
{
|
{
|
||||||
// This function runs inside the target process. Some of them may already support Long Path.
|
// This function runs inside the target process. Some of them may already support Long Path.
|
||||||
// Therefore, we must assume all of them support Long Path to avoid buffer overflow.
|
// Therefore, we must assume all of them support Long Path to avoid buffer overflow.
|
||||||
WCHAR dllBuffer[MAX_PATH_EX] = {'\0'};
|
WCHAR dllBuffer[MAX_PATH_EX] = {'\0'};
|
||||||
pGCS(dllBuffer);
|
pGCS(dllBuffer);
|
||||||
|
|
||||||
auto hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, SHARED_MEM_NAME);
|
auto hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, SHARED_MEM_NAME);
|
||||||
if (hMapFile == nullptr)
|
if (hMapFile == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto buffer = static_cast<PWCHAR>(MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 0));
|
auto buffer = static_cast<PWCHAR>(MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 0));
|
||||||
if (buffer == nullptr)
|
if (buffer == nullptr)
|
||||||
{
|
{
|
||||||
CloseHandle(hMapFile);
|
CloseHandle(hMapFile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wcscpy_s(buffer, wcslen(dllBuffer) + 1, dllBuffer);
|
wcscpy_s(buffer, wcslen(dllBuffer) + 1, dllBuffer);
|
||||||
|
|
||||||
UnmapViewOfFile(buffer);
|
UnmapViewOfFile(buffer);
|
||||||
CloseHandle(hMapFile);
|
CloseHandle(hMapFile);
|
||||||
}
|
}
|
||||||
|
@@ -62,6 +62,6 @@ internal class FocusMonitor
|
|||||||
|
|
||||||
internal static FocusMonitor GetInstance()
|
internal static FocusMonitor GetInstance()
|
||||||
{
|
{
|
||||||
return _instance ?? (_instance = new FocusMonitor());
|
return _instance ??= new FocusMonitor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -43,11 +43,11 @@ internal class KeystrokeDispatcher : IDisposable
|
|||||||
{
|
{
|
||||||
InstallKeyHook(KeyDownEventHandler, KeyUpEventHandler);
|
InstallKeyHook(KeyDownEventHandler, KeyUpEventHandler);
|
||||||
|
|
||||||
_validKeys = new HashSet<Keys>(
|
_validKeys =
|
||||||
[
|
[
|
||||||
Keys.Up, Keys.Down, Keys.Left, Keys.Right,
|
Keys.Up, Keys.Down, Keys.Left, Keys.Right,
|
||||||
Keys.Enter, Keys.Space, Keys.Escape
|
Keys.Enter, Keys.Space, Keys.Escape
|
||||||
]);
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
@@ -83,7 +83,7 @@ internal static class QuickLook
|
|||||||
|
|
||||||
internal static string GetCurrentSelection()
|
internal static string GetCurrentSelection()
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder(MaxPath);
|
StringBuilder sb = new(MaxPath);
|
||||||
// communicate with COM in a separate STA thread
|
// communicate with COM in a separate STA thread
|
||||||
var thread = new Thread(() =>
|
var thread = new Thread(() =>
|
||||||
{
|
{
|
||||||
@@ -107,7 +107,7 @@ internal static class QuickLook
|
|||||||
// We got a quoted string which breaks ResolveShortcut
|
// We got a quoted string which breaks ResolveShortcut
|
||||||
sb = sb.Replace("\"", string.Empty, 0, 1).Replace("\"", string.Empty, sb.Length - 1, 1);
|
sb = sb.Replace("\"", string.Empty, 0, 1).Replace("\"", string.Empty, sb.Length - 1, 1);
|
||||||
}
|
}
|
||||||
return ResolveShortcut(sb?.ToString() ?? String.Empty);
|
return ResolveShortcut(sb?.ToString() ?? string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string ResolveShortcut(string path)
|
private static string ResolveShortcut(string path)
|
||||||
|
Reference in New Issue
Block a user