16
16
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17
17
18
18
#include " stdafx.h"
19
+ #include " strsafe.h"
20
+
19
21
#include " HelperMethods.h"
20
22
21
23
void HelperMethods::GetSelectedInternal (CComPtr<IShellBrowser> psb, PWCHAR buffer)
@@ -33,8 +35,11 @@ void HelperMethods::GetSelectedInternal(CComPtr<IShellBrowser> psb, PWCHAR buffe
33
35
34
36
void HelperMethods::ObtainFirstItem (CComPtr<IDataObject> dao, PWCHAR buffer)
35
37
{
36
- FORMATETC formatetc;
37
- STGMEDIUM medium = {sizeof medium};
38
+ if (!dao || !buffer)
39
+ return ;
40
+
41
+ FORMATETC formatetc = {};
42
+ STGMEDIUM medium = {};
38
43
39
44
formatetc.cfFormat = CF_HDROP;
40
45
formatetc.ptd = nullptr ;
@@ -44,18 +49,62 @@ void HelperMethods::ObtainFirstItem(CComPtr<IDataObject> dao, PWCHAR buffer)
44
49
45
50
medium.tymed = TYMED_HGLOBAL;
46
51
47
- if (FAILED (dao->GetData (&formatetc, &medium)))
48
- return ;
52
+ // Try CF_HDROP first
53
+ if (SUCCEEDED (dao->GetData (&formatetc, &medium)))
54
+ {
55
+ HDROP hDrop = HDROP (medium.hGlobal );
56
+ int count = DragQueryFile (hDrop, 0xFFFFFFFF , nullptr , 0 );
57
+ if (count >= 1 )
58
+ {
59
+ WCHAR localBuffer[MAX_PATH] = { ' \0 ' };
60
+ if (DragQueryFileW (hDrop, 0 , localBuffer, MAX_PATH) > 0 )
61
+ {
62
+ GetLongPathName (localBuffer, buffer, MAX_PATH_EX);
63
+ ReleaseStgMedium (&medium);
64
+ return ;
65
+ }
66
+ ReleaseStgMedium (&medium);
67
+ }
68
+ }
49
69
50
- int n = DragQueryFile (HDROP (medium.hGlobal ), 0xFFFFFFFF , nullptr , 0 );
70
+ // If CF_HDROP fails, try CFSTR_SHELLIDLIST
71
+ // Support Desktop Icon (This PC, Recycle Bin and so on)
72
+ // https://github.com/QL-Win/QuickLook/issues/1610
73
+ static const CLIPFORMAT cfShellIDList = (CLIPFORMAT)RegisterClipboardFormatW (CFSTR_SHELLIDLIST);
74
+ formatetc.cfFormat = cfShellIDList;
51
75
52
- if (n < 1 )
53
- return ;
76
+ if (SUCCEEDED (dao->GetData (&formatetc, &medium)))
77
+ {
78
+ CIDA* pida = (CIDA*)GlobalLock (medium.hGlobal );
79
+ if (!pida)
80
+ {
81
+ ReleaseStgMedium (&medium);
82
+ return ;
83
+ }
84
+
85
+ ITEMIDLIST* pidlFolder = (ITEMIDLIST*)((BYTE*)pida + pida->aoffset [0 ]);
86
+ ITEMIDLIST* pidlItem = (ITEMIDLIST*)((BYTE*)pida + pida->aoffset [1 ]);
87
+ PIDLIST_ABSOLUTE pidlFull = ILCombine (pidlFolder, pidlItem);
88
+ GlobalUnlock (medium.hGlobal );
89
+ ReleaseStgMedium (&medium);
90
+
91
+ if (!pidlFull)
92
+ return ;
93
+
94
+ // Convert to IShellItem to get canonical parsing path
95
+ CComPtr<IShellItem> shellItem;
96
+ if (SUCCEEDED (SHCreateItemFromIDList (pidlFull, IID_PPV_ARGS (&shellItem))))
97
+ {
98
+ PWSTR pszPath = nullptr ;
99
+ if (SUCCEEDED (shellItem->GetDisplayName (SIGDN_DESKTOPABSOLUTEPARSING, &pszPath)))
100
+ {
101
+ StringCchCopyW (buffer, MAX_PATH, pszPath); // returns e.g., ::{645FF040-5081-101B-9F08-00AA002F954E}
102
+ CoTaskMemFree (pszPath);
103
+ }
104
+ }
54
105
55
- WCHAR localBuffer[MAX_PATH] = { ' \0 ' };
56
- DragQueryFile (HDROP (medium.hGlobal ), 0 , localBuffer, MAX_PATH);
57
-
58
- GetLongPathName (localBuffer, buffer, MAX_PATH_EX);
106
+ ILFree (pidlFull);
107
+ }
59
108
}
60
109
61
110
bool HelperMethods::IsListaryToolbarVisible ()
0 commit comments