3 * LICENSE: LGPL-2.1+ (https://spdx.org/licenses/LGPL-2.1+)
4 * PURPOSE: DeskLink implementation
5 * COPYRIGHT: Copyright 2019 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
10 WINE_DEFAULT_DEBUG_CHANNEL(sendmail
);
12 CDeskLinkDropHandler::CDeskLinkDropHandler()
14 InterlockedIncrement(&g_ModuleRefCnt
);
17 CDeskLinkDropHandler::~CDeskLinkDropHandler()
19 InterlockedDecrement(&g_ModuleRefCnt
);
24 CDeskLinkDropHandler::DragEnter(IDataObject
*pDataObject
, DWORD dwKeyState
,
25 POINTL pt
, DWORD
*pdwEffect
)
27 TRACE("(%p)\n", this);
29 *pdwEffect
&= DROPEFFECT_LINK
;
35 CDeskLinkDropHandler::DragOver(DWORD dwKeyState
, POINTL pt
, DWORD
*pdwEffect
)
37 TRACE("(%p)\n", this);
39 *pdwEffect
&= DROPEFFECT_LINK
;
44 STDMETHODIMP
CDeskLinkDropHandler::DragLeave()
46 TRACE("(%p)\n", this);
51 CDeskLinkDropHandler::Drop(IDataObject
*pDataObject
, DWORD dwKeyState
,
52 POINTL pt
, DWORD
*pdwEffect
)
54 TRACE("(%p)\n", this);
58 ERR("pDataObject is NULL\n");
63 fmt
.cfFormat
= RegisterClipboardFormatW(CFSTR_SHELLIDLIST
);
65 fmt
.dwAspect
= DVASPECT_CONTENT
;
67 fmt
.tymed
= TYMED_HGLOBAL
;
69 WCHAR szDir
[MAX_PATH
], szDest
[MAX_PATH
], szSrc
[MAX_PATH
];
70 SHGetSpecialFolderPathW(NULL
, szDir
, CSIDL_DESKTOPDIRECTORY
, FALSE
);
72 CComPtr
<IShellFolder
> pDesktop
;
73 HRESULT hr
= SHGetDesktopFolder(&pDesktop
);
74 if (FAILED_UNEXPECTEDLY(hr
))
78 hr
= pDataObject
->GetData(&fmt
, &medium
);
79 if (FAILED_UNEXPECTEDLY(hr
))
82 LPIDA pida
= reinterpret_cast<LPIDA
>(GlobalLock(medium
.hGlobal
));
85 ERR("Error locking global\n");
86 ReleaseStgMedium(&medium
);
90 LPBYTE pb
= reinterpret_cast<LPBYTE
>(pida
);
91 LPCITEMIDLIST pidlParent
= reinterpret_cast<LPCITEMIDLIST
>(pb
+ pida
->aoffset
[0]);
92 for (UINT i
= 1; i
<= pida
->cidl
; ++i
)
94 LPCITEMIDLIST pidlChild
= reinterpret_cast<LPCITEMIDLIST
>(pb
+ pida
->aoffset
[i
]);
96 CComHeapPtr
<ITEMIDLIST
> pidl(ILCombine(pidlParent
, pidlChild
));
99 ERR("Out of memory\n");
103 StringCbCopyW(szDest
, sizeof(szDest
), szDir
);
104 if (SHGetPathFromIDListW(pidl
, szSrc
))
107 strTitle
.Format(IDS_SHORTCUT
, PathFindFileNameW(szSrc
));
109 PathAppendW(szDest
, strTitle
);
110 PathRemoveExtensionW(szDest
);
111 StringCbCatW(szDest
, sizeof(szDest
), L
".lnk");
113 hr
= CreateShellLink(szDest
, szSrc
, NULL
, NULL
, NULL
, NULL
, -1, NULL
);
118 hr
= pDesktop
->GetDisplayNameOf(pidl
, SHGDN_INFOLDER
, &strret
);
119 if (FAILED_UNEXPECTEDLY(hr
))
122 hr
= StrRetToBufW(&strret
, pidl
, szSrc
, _countof(szSrc
));
123 if (FAILED_UNEXPECTEDLY(hr
))
127 strTitle
.Format(IDS_SHORTCUT
, szSrc
);
129 PathAppendW(szDest
, strTitle
);
130 PathRemoveExtensionW(szDest
);
131 StringCbCatW(szDest
, sizeof(szDest
), L
".lnk");
133 hr
= CreateShellLink(szDest
, NULL
, pidl
, NULL
, NULL
, NULL
, -1, NULL
);
136 if (FAILED_UNEXPECTEDLY(hr
))
140 GlobalUnlock(medium
.hGlobal
);
141 ReleaseStgMedium(&medium
);
147 STDMETHODIMP
CDeskLinkDropHandler::GetCurFile(LPOLESTR
*ppszFileName
)
149 FIXME("(%p)\n", this);
153 STDMETHODIMP
CDeskLinkDropHandler::IsDirty()
155 FIXME("(%p)\n", this);
159 STDMETHODIMP
CDeskLinkDropHandler::Load(LPCOLESTR pszFileName
, DWORD dwMode
)
164 STDMETHODIMP
CDeskLinkDropHandler::Save(LPCOLESTR pszFileName
, BOOL fRemember
)
166 FIXME("(%p)\n", this);
170 STDMETHODIMP
CDeskLinkDropHandler::SaveCompleted(LPCOLESTR pszFileName
)
172 FIXME("(%p)\n", this);
177 STDMETHODIMP
CDeskLinkDropHandler::GetClassID(CLSID
* lpClassId
)
179 TRACE("(%p)\n", this);
183 ERR("lpClassId is NULL\n");
187 *lpClassId
= CLSID_DeskLinkDropHandler
;