123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431 |
- /** (c) Nullsoft, Inc. C O N F I D E N T I A L
- ** Filename:
- ** Project:
- ** Description:
- ** Author:
- ** Created:
- **/
- #include "main.h"
- #include "../nu/AutoWide.h"
- #include "../nu/AutoWideFn.h"
- extern "C"
- {
- extern int g_has_deleted_current;
- };
- #include "shlobj.h"
- #include "../Plugins/General/gen_ff/ff_ipc.h"
- bool refuseDrops = false;
- class DropTarget: public IDropTarget
- {
- public:
- DropTarget(int enqueue, int isshell)
- { m_enqueue = enqueue; m_isshell = isshell; }
- STDMETHODIMP QueryInterface (REFIID riid, LPVOID * ppvObj)
- {
- if (riid == IID_IDropTarget || riid == IID_IUnknown)
- {
- *ppvObj = this;
- return S_OK;
- }
- *ppvObj = NULL;
- return E_NOINTERFACE;
- }
- STDMETHODIMP_(ULONG) AddRef ()
- { return 0; }
- STDMETHODIMP_(ULONG) Release ()
- { return 0; }
- STDMETHODIMP DragEnter(IDataObject * pDataObject, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
- {
- if (pdwEffect)
- {
- if (refuseDrops && !m_isshell)
- *pdwEffect = DROPEFFECT_NONE;
- else
- *pdwEffect = DROPEFFECT_COPY;
- }
-
- return S_OK;
- }
- STDMETHODIMP DragOver(DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
- {
-
- if (pdwEffect)
- {
- if (refuseDrops && !m_isshell)
- *pdwEffect = DROPEFFECT_NONE;
- }
- return S_OK;
- }
- STDMETHODIMP DragLeave()
- {
- return 0;
- }
- STDMETHODIMP Drop(IDataObject * pDataObj, DWORD grfKeyState, POINTL pt, DWORD * pdwEffect)
- {
- POINT p = {pt.x, pt.y};
- HWND wnd;
- int pl_forceappend = 0;
- int is_main = 0;
- int is_pe = 0;
- int pe_insert = 0;
- if (m_isshell)
- {
- is_main = 1;
- wnd = hMainWindow;
- if (m_enqueue == 2)
- {
- pe_insert = !SendMessageW(hMainWindow, WM_WA_IPC, PlayList_getlength(), IPC_SHELL_ACTION_START);
- }
- }
- else
- {
- wnd = WindowFromPoint(p);
- HWND child=0;
- do
- {
- RECT r;
- GetWindowRect(wnd, &r);
- POINT offset = p;
- offset.x -= r.left;
- offset.y -= r.top;
- child = ChildWindowFromPoint(wnd, offset);
- if (child == wnd)
- child = 0;
- else if (child)
- wnd = child;
- } while (child);
- HWND par = wnd;
- HWND pledit_poopie = NULL;
- while (par && !(GetWindowLongW(par, GWL_EXSTYLE) & WS_EX_ACCEPTFILES))
- {
- par = GetParent(par);
- }
- if (par) wnd = par;
- if (wnd == hMainWindow || IsChild(hMainWindow, wnd)
- || (HWND)SendMessageW(hMainWindow, WM_WA_IPC, (WPARAM)wnd, IPC_FF_GETCONTENTWND) == hMainWindow)
- {
- is_main = 1;
- }
- else if (wnd == hPLWindow || IsChild(hPLWindow, wnd) || GetParent(hPLWindow) && IsChild(wnd, hPLWindow) ||
- (pledit_poopie = (HWND)SendMessageW(hMainWindow, WM_WA_IPC, (WPARAM)wnd, IPC_FF_GETCONTENTWND)) == hPLWindow)
- {
- is_pe = 1;
- if (pledit_poopie) pl_forceappend = 1; // if we got here because we're hosting the pledit, but not actually
- // parenting it (meaning we are windowshaded playlist)
- }
- else
- {
- EnterCriticalSection(&embedcs);
- {
- embedWindowState *p = embedwndlist;
- while (p)
- {
- if (IsChild(p->me, wnd) || (GetParent(p->me) && IsChild(wnd, p->me))) break;
- p = p->link;
- }
- if (p)
- {
- if (wnd == p->me || IsChild(wnd, p->me) || !(GetWindowLongW(wnd, GWL_EXSTYLE) & WS_EX_ACCEPTFILES)) // if this window accepts files, dont fuck it up
- {
- HWND wnd2 = FindWindowExW(p->me, NULL, NULL, NULL);
- if (!(GetWindowLongW(wnd2, GWL_EXSTYLE)&WS_EX_ACCEPTFILES)) is_main = 1;
- else
- {
- HWND h = GetParent(p->me);
- char buf[128] = {0};
- // see if we are (AVS) docked to the main (modern) window
- if (h && (h = GetParent(h)) && GetWindowTextA(h, buf, sizeof(buf)) && !_stricmp(buf, "Player Window"))
- is_main = 1;
- else wnd = wnd2;
- }
- }
- }
- else is_main = 1;
- }
- LeaveCriticalSection(&embedcs);
- }
- if (is_main) wnd = hMainWindow;
- if (is_pe) wnd = hPLWindow;
- }
- HRESULT hr = S_OK;
- if (pDataObj)
- {
- // Important: these strings need to be non-Unicode (don't compile UNICODE)
- unsigned short cp_format_url = (unsigned short)RegisterClipboardFormat(CFSTR_SHELLURL);
- //Set up format structure for the descriptor and contents
- FORMATETC format_url =
- {cp_format_url, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
- FORMATETC format_file =
- {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
- // Check for URL
- hr = pDataObj->QueryGetData(&format_url);
- if (hr == S_OK)
- {
- // Get the descriptor information
- STGMEDIUM storage = {0, 0, 0};
- hr = pDataObj->GetData(&format_url, &storage);
- char* url = (char *)GlobalLock(storage.hGlobal);
- if (url)
- {
- if (is_pe || is_main || m_isshell)
- {
- int t, lp, a;
- int del = is_main && !(GetAsyncKeyState(VK_SHIFT) & (1 << 15));
- if (del) PlayList_delete();
- else if (!is_main && !m_isshell) // playlist
- {
- RECT r;
- POINT dp;
- GetWindowRect(wnd, &r);
- dp.x = pt.x - r.left;
- dp.y = pt.y - r.top;
- if (config_pe_height == 14 || pl_forceappend) t = PlayList_getlength();
- else
- {
- t = (dp.y - 20) / pe_fontheight;
- if (t < 0) t = 0;
- else if (t > (config_pe_height - 38 - 20 - 2) / pe_fontheight) t = PlayList_getlength();
- else t += pledit_disp_offs;
- }
- a = PlayList_getlength();
- PlayList_saveend(t);
- lp = PlayList_getPosition();
- }
- if(!PathIsURLA(url))
- {
- // if it's not reported as an url, try to treat it like
- // a filepath which has been url-encoded and insert it
- // though if it fails to be converted then revert to it
- // just being added to the playlist without processing.
- char url2[FILENAME_SIZE] = {"file:///"};
- strncat(url2, url, FILENAME_SIZE);
- DWORD len = lstrlenA(url2);
- if(SUCCEEDED(PathCreateFromUrlA(url2, url2, &len, 0)))
- {
- PlayList_appendthing(AutoWideFn(url2), 0, 0);
- }
- else
- {
- PlayList_appendthing(AutoWideFn(url), 0, 0);
- }
- }
- else
- {
- PlayList_appendthing(AutoWideFn(url), 0, 0);
- }
- if (del) StartPlaying();
- else if (!is_main && !m_isshell) // playlist
- {
- PlayList_restoreend();
- if (t <= PlayList_getPosition())
- {
- PlayList_setposition(lp + PlayList_getlength() - a);
- if (!g_has_deleted_current)
- {
- PlayList_getcurrent(FileName, FileTitle, FileTitleNum);
- draw_songname(FileTitle, &ui_songposition, playing ? in_getlength() : PlayList_getcurrentlength());
- }
- }
- plEditRefresh();
- }
- }
- else // fucko: pass url to 'wnd' somehow?
- {}
- }
- GlobalUnlock(url);
- GlobalFree(url);
- }
- else
- {
- // check for file
- hr = pDataObj->QueryGetData(&format_file);
- if (hr == S_OK)
- {
- STGMEDIUM medium;
- pDataObj->GetData (&format_file, &medium);
- wchar_t temp[FILENAME_SIZE] = {0};
- if (m_enqueue)
- {
- HDROP hdrop = (HDROP)medium.hGlobal;
- int y = DragQueryFileW(hdrop, 0xffffffff, temp, FILENAME_SIZE);
- int current = PlayList_getPosition();
- for (int x = 0; x < y; x ++)
- {
- DragQueryFileW(hdrop, x, temp, FILENAME_SIZE);
- if (!pe_insert)
- PlayList_appendthing(temp, 0, 0);
- else
- {
- PlayList_insert(++current, temp);
- }
- }
- DragFinish(hdrop);
- plEditRefresh();
- }
- else
- {
- int skinLoad = -2;
- int langLoad = -2;
- RECT r;
- GetWindowRect(wnd, &r);
- LPDROPFILES d = (LPDROPFILES)GlobalLock(medium.hGlobal);
- d->pt.x = pt.x - r.left;
- if (pl_forceappend)
- d->pt.y = r.bottom - r.top;
- else d->pt.y = pt.y - r.top;
- d->fNC = FALSE;
- GlobalUnlock(d);
-
- // check for the file being a skin or language pack
- // being dropped so we can intercept and not add it
- // into the pledit but can instead prompt for install
- DragQueryFileW((HDROP)medium.hGlobal, 0, temp, FILENAME_SIZE);
- CheckSkin(temp, hMainWindow, &skinLoad);
- CheckLang(temp, hMainWindow, &langLoad);
- if(!skinLoad && !langLoad)
- {
- PostMessageW(wnd, WM_DROPFILES, (WPARAM)medium.hGlobal, 0);
- }
- }
- }
- }
- }
- if (m_isshell && (m_enqueue == 2))
- {
- SendMessageW(hMainWindow, WM_WA_IPC, PlayList_getlength(), IPC_SHELL_ACTION_END);
- }
- return S_OK;
- }
- public:
- int m_enqueue;
- int m_isshell;
- };
- static DropTarget m_target(0, 0);
- class ClassFactory : public IClassFactory
- {
- public:
- ClassFactory(int enqueue) { m_drop = new DropTarget(enqueue, 1); }
- ~ClassFactory() { delete(m_drop); }
- STDMETHODIMP QueryInterface (REFIID riid, LPVOID * ppvObj)
- {
- if (riid == IID_IClassFactory || riid == IID_IUnknown)
- {
- *ppvObj = this;
- return S_OK;
- }
- *ppvObj = NULL;
- return E_NOINTERFACE;
- }
- STDMETHODIMP_(ULONG) AddRef ()
- { return 0; }
- STDMETHODIMP_(ULONG) Release ()
- { return 0; }
- STDMETHODIMP CreateInstance(IUnknown * pUnkOuter, REFIID riid, void ** ppvObject)
- {
- if (pUnkOuter != NULL)
- {
- return CLASS_E_NOAGGREGATION;
- }
- if (riid == IID_IDropTarget || riid == IID_IUnknown)
- {
- *ppvObject = m_drop;
- return S_OK;
- }
- return E_NOINTERFACE;
- }
- STDMETHODIMP LockServer(BOOL fLock)
- {
- return S_OK;
- }
- private:
- DropTarget *m_drop;
- };
- static ClassFactory m_playCF(0);
- static ClassFactory m_enqueueCF(1);
- static ClassFactory m_enqueuePlayCF(2);
- static DWORD m_exposePlayHandle = NULL, m_exposeEnqueueHandle = NULL, m_exposeEnqueuePlayHandle = NULL;
- extern "C"
- {
- void InitDragDrops()
- {
- SetWindowLong(hMainWindow, GWL_EXSTYLE, GetWindowLongW(hMainWindow, GWL_EXSTYLE)|(WS_EX_ACCEPTFILES));
- refuseDrops = false;
- }
- void Ole_initDragDrop()
- {
- OleInitialize(NULL);
- RegisterDragDrop(hMainWindow, &m_target);
- RegisterDragDrop(hPLWindow, &m_target);
- if (hVideoWindow) RegisterDragDrop(hVideoWindow, &m_target);
- // {46986115-84D6-459c-8F95-52DD653E532E}
- static const GUID playGuid =
- { 0x46986115, 0x84D6, 0x459c, { 0x8f, 0x95, 0x52, 0xdd, 0x65, 0x3e, 0x53, 0x2e } };
- if (CoRegisterClassObject(playGuid, &m_playCF, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &m_exposePlayHandle) != S_OK)
- m_exposePlayHandle = NULL;
- // {77A366BA-2BE4-4a1e-9263-7734AA3E99A2}
- static const GUID enqueueGuid =
- { 0x77A366BA, 0x2BE4, 0x4a1e, { 0x92, 0x63, 0x77, 0x34, 0xAA, 0x3e, 0x99, 0xa2 } };
- if (CoRegisterClassObject(enqueueGuid, &m_enqueueCF, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &m_exposeEnqueueHandle) != S_OK)
- m_exposeEnqueueHandle = NULL;
- // {ED50B649-42B0-4153-9E99-54C45F6BD708}
- static const GUID enqueuePlayGuid =
- { 0xed50b649, 0x42b0, 0x4153, { 0x9e, 0x99, 0x54, 0xc4, 0x5f, 0x6b, 0xd7, 0x8 } };
- if (CoRegisterClassObject(enqueuePlayGuid, &m_enqueuePlayCF, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &m_exposeEnqueuePlayHandle) != S_OK)
- m_exposeEnqueuePlayHandle = NULL;
- }
- void UninitDragDrops()
- {
- SetWindowLong(hMainWindow, GWL_EXSTYLE, GetWindowLongW(hMainWindow, GWL_EXSTYLE)&~(WS_EX_ACCEPTFILES));
- refuseDrops = true;
- }
- void Ole_uninitDragDrop()
- {
- if (hVideoWindow) RevokeDragDrop(hVideoWindow);
- RevokeDragDrop(hPLWindow);
- RevokeDragDrop(hMainWindow);
- if (m_exposePlayHandle)
- CoRevokeClassObject(m_exposePlayHandle);
- if (m_exposeEnqueueHandle)
- CoRevokeClassObject(m_exposeEnqueueHandle);
- if (m_exposeEnqueuePlayHandle)
- CoRevokeClassObject(m_exposeEnqueuePlayHandle);
- OleUninitialize();
- }
- void *Ole_getDropTarget()
- {
- return (void *)&m_target;
- }
- };
|