Native Support for Desktop Icons #1610

This commit is contained in:
ema
2025-05-05 02:58:39 +08:00
parent 34a361e84a
commit 1bc82c8b81
3 changed files with 65 additions and 19 deletions

View File

@@ -19,9 +19,9 @@
class DOpus class DOpus
{ {
public: public:
static void PrepareMessageWindow(); static void PrepareMessageWindow();
static void GetSelected(PWCHAR buffer); static void GetSelected(PWCHAR buffer);
private: private:
static void ParseXmlBuffer(PWCHAR buffer); static void ParseXmlBuffer(PWCHAR buffer);
static LRESULT CALLBACK msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK msgWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
}; };

View File

@@ -16,6 +16,8 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h" #include "stdafx.h"
#include "strsafe.h"
#include "HelperMethods.h" #include "HelperMethods.h"
void HelperMethods::GetSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer) void HelperMethods::GetSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffer)
@@ -33,8 +35,11 @@ void HelperMethods::GetSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffe
void HelperMethods::ObtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer) void HelperMethods::ObtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer)
{ {
FORMATETC formatetc; if (!dao || !buffer)
STGMEDIUM medium = {sizeof medium}; return;
FORMATETC formatetc = {};
STGMEDIUM medium = {};
formatetc.cfFormat = CF_HDROP; formatetc.cfFormat = CF_HDROP;
formatetc.ptd = nullptr; formatetc.ptd = nullptr;
@@ -44,18 +49,62 @@ void HelperMethods::ObtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer)
medium.tymed = TYMED_HGLOBAL; medium.tymed = TYMED_HGLOBAL;
if (FAILED(dao->GetData(&formatetc, &medium))) // Try CF_HDROP first
return; if (SUCCEEDED(dao->GetData(&formatetc, &medium)))
{
HDROP hDrop = HDROP(medium.hGlobal);
int count = DragQueryFile(hDrop, 0xFFFFFFFF, nullptr, 0);
if (count >= 1)
{
WCHAR localBuffer[MAX_PATH] = { '\0' };
if (DragQueryFileW(hDrop, 0, localBuffer, MAX_PATH) > 0)
{
GetLongPathName(localBuffer, buffer, MAX_PATH_EX);
ReleaseStgMedium(&medium);
return;
}
ReleaseStgMedium(&medium);
}
}
int n = DragQueryFile(HDROP(medium.hGlobal), 0xFFFFFFFF, nullptr, 0); // If CF_HDROP fails, try CFSTR_SHELLIDLIST
// Support Desktop Icon (This PC, Recycle Bin and so on)
// https://github.com/QL-Win/QuickLook/issues/1610
static const CLIPFORMAT cfShellIDList = (CLIPFORMAT)RegisterClipboardFormatW(CFSTR_SHELLIDLIST);
formatetc.cfFormat = cfShellIDList;
if (n < 1) if (SUCCEEDED(dao->GetData(&formatetc, &medium)))
return; {
CIDA* pida = (CIDA*)GlobalLock(medium.hGlobal);
if (!pida)
{
ReleaseStgMedium(&medium);
return;
}
WCHAR localBuffer[MAX_PATH] = { '\0' }; ITEMIDLIST* pidlFolder = (ITEMIDLIST*)((BYTE*)pida + pida->aoffset[0]);
DragQueryFile(HDROP(medium.hGlobal), 0, localBuffer, MAX_PATH); ITEMIDLIST* pidlItem = (ITEMIDLIST*)((BYTE*)pida + pida->aoffset[1]);
PIDLIST_ABSOLUTE pidlFull = ILCombine(pidlFolder, pidlItem);
GlobalUnlock(medium.hGlobal);
ReleaseStgMedium(&medium);
GetLongPathName(localBuffer, buffer, MAX_PATH_EX); if (!pidlFull)
return;
// Convert to IShellItem to get canonical parsing path
CComPtr<IShellItem> shellItem;
if (SUCCEEDED(SHCreateItemFromIDList(pidlFull, IID_PPV_ARGS(&shellItem))))
{
PWSTR pszPath = nullptr;
if (SUCCEEDED(shellItem->GetDisplayName(SIGDN_DESKTOPABSOLUTEPARSING, &pszPath)))
{
StringCchCopyW(buffer, MAX_PATH, pszPath); // returns e.g., ::{645FF040-5081-101B-9F08-00AA002F954E}
CoTaskMemFree(pszPath);
}
}
ILFree(pidlFull);
}
} }
bool HelperMethods::IsListaryToolbarVisible() bool HelperMethods::IsListaryToolbarVisible()

View File

@@ -83,10 +83,7 @@ public partial class InfoPanel : UserControl
} }
else if (Path.GetPathRoot(path) == path) // is this a drive? else if (Path.GetPathRoot(path) == path) // is this a drive?
{ {
long totalSpace; FileHelper.GetDriveSpace(path, out var totalSpace, out var totalFreeSpace);
long totalFreeSpace;
FileHelper.GetDriveSpace(path, out totalSpace, out totalFreeSpace);
Dispatcher.Invoke(() => Dispatcher.Invoke(() =>
{ {