From 7132d5ac691ac59d2d6ac801c57c7da43c42003b Mon Sep 17 00:00:00 2001 From: Dreamoochy Date: Sun, 25 Feb 2024 15:52:41 +0300 Subject: [PATCH] Added Multi Commander support --- .../QuickLook.Native32/MultiCommander.cpp | 98 +++++++++++++++++++ .../QuickLook.Native32/MultiCommander.h | 37 +++++++ 2 files changed, 135 insertions(+) create mode 100644 QuickLook.Native/QuickLook.Native32/MultiCommander.cpp create mode 100644 QuickLook.Native/QuickLook.Native32/MultiCommander.h diff --git a/QuickLook.Native/QuickLook.Native32/MultiCommander.cpp b/QuickLook.Native/QuickLook.Native32/MultiCommander.cpp new file mode 100644 index 0000000..025250f --- /dev/null +++ b/QuickLook.Native/QuickLook.Native32/MultiCommander.cpp @@ -0,0 +1,98 @@ +// This file is part of QuickLook program. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "stdafx.h" +#include "MultiCommander.h" + +HWND MultiCommander::hMsgWnd = nullptr; +HANDLE MultiCommander::hGetResultEvent = nullptr; +PCHAR MultiCommander::pCurrentItemPath = nullptr; + +void MultiCommander::GetSelected(PWCHAR buffer) +{ + if (false == PrepareMessageWindow()) { + return; + } + + COPYDATASTRUCT cds; + cds.dwData = MULTICMD_CPF_GETCURITEMFULL | MULTICMD_CPF_SOURCE; + cds.cbData = 0; + cds.lpData = nullptr; + + ResetEvent(hGetResultEvent); + + auto ret = SendMessage( + FindWindow(MULTICMD_CLASS, nullptr), + WM_COPYDATA, + reinterpret_cast(hMsgWnd), + reinterpret_cast(&cds) + ); + + if (!ret || WAIT_OBJECT_0 != WaitForSingleObject(hGetResultEvent, 2000)) { + return; + } + + auto path = reinterpret_cast(pCurrentItemPath); + wcscpy_s(buffer, wcslen(path) + 1, path); + + delete[] pCurrentItemPath; + pCurrentItemPath = nullptr; +} + +bool MultiCommander::PrepareMessageWindow() +{ + if (nullptr == hMsgWnd) { + WNDCLASSEX wx = {}; + + wx.cbSize = sizeof(WNDCLASSEX); + wx.lpfnWndProc = msgWindowProc; + wx.lpszClassName = MULTICMD_MSGWINDOW_CLASS; + + if (RegisterClassEx(&wx)) + hMsgWnd = CreateWindowEx(0, MULTICMD_MSGWINDOW_CLASS, L"", 0, 0, 0, 0, 0, HWND_MESSAGE, nullptr, nullptr, nullptr); + + if (nullptr == hMsgWnd) { + return false; + } + } + + if (nullptr == hGetResultEvent) { + hGetResultEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr); + } + + return (nullptr != hGetResultEvent); +} + +LRESULT CALLBACK MultiCommander::msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_COPYDATA: + { + delete[] pCurrentItemPath; + + auto cds = reinterpret_cast(lParam); + auto buf = static_cast(cds->lpData); + + pCurrentItemPath = new CHAR[cds->cbData + 1]{ '\0' }; + memcpy(pCurrentItemPath, buf, cds->cbData); + + SetEvent(hGetResultEvent); + return 0; + } + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } +} diff --git a/QuickLook.Native/QuickLook.Native32/MultiCommander.h b/QuickLook.Native/QuickLook.Native32/MultiCommander.h new file mode 100644 index 0000000..44074f3 --- /dev/null +++ b/QuickLook.Native/QuickLook.Native32/MultiCommander.h @@ -0,0 +1,37 @@ +// This file is part of QuickLook program. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#pragma once + +#define MULTICMD_CPF_GETCURITEMFULL 0x00000010L // Get full path of current item (file or folder) in focus +#define MULTICMD_CPF_SOURCE 0x00000400L // Go to the new path in the source panel side + +#define MULTICMD_CLASS L"MultiCommander MainWnd" +#define MULTICMD_MSGWINDOW_CLASS L"QuickLook.Native.MultiCmd.MsgWindow" + +class MultiCommander +{ +public: + static void GetSelected(PWCHAR buffer); + static bool PrepareMessageWindow(); + MultiCommander() = delete; +private: + static HWND hMsgWnd; + static HANDLE hGetResultEvent; + static PCHAR pCurrentItemPath; + + static LRESULT CALLBACK msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); +}; +