diff options
| author | Aldrik Ramaekers <aldrikboy@gmail.com> | 2024-03-12 21:45:35 +0100 |
|---|---|---|
| committer | Aldrik Ramaekers <aldrikboy@gmail.com> | 2024-03-12 21:45:35 +0100 |
| commit | e72c327a84d1937c05cc14a5e2ab232584e2cb9d (patch) | |
| tree | 96d58fa0f0065c577bcc87bc094498d2348b3ca3 /src/windows/DropManager.h | |
| parent | e4d2929604792b135cbf8dad22179a5dec60e365 (diff) | |
dragdrop file work
Diffstat (limited to 'src/windows/DropManager.h')
| -rw-r--r-- | src/windows/DropManager.h | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/src/windows/DropManager.h b/src/windows/DropManager.h new file mode 100644 index 0000000..32b6922 --- /dev/null +++ b/src/windows/DropManager.h @@ -0,0 +1,106 @@ +#pragma once + +#include "platform.h" + +#include <oleidl.h> + +// create a class inheriting from IDropTarget +class DropManager : public IDropTarget +{ +public: + //--- implement the IUnknown parts + // you could do this the proper way with InterlockedIncrement etc, + // but I've left out stuff that's not exactly necessary for brevity + ULONG AddRef() { return 1; } + ULONG Release() { return 0; } + + // we handle drop targets, let others know + HRESULT QueryInterface(REFIID riid, void **ppvObject) + { + if (riid == IID_IDropTarget) + { + *ppvObject = this; // or static_cast<IUnknown*> if preferred + // AddRef() if doing things properly + // but then you should probably handle IID_IUnknown as well; + return S_OK; + } + + *ppvObject = NULL; + return E_NOINTERFACE; + }; + + + //--- implement the IDropTarget parts + + // occurs when we drag files into our applications view + HRESULT DragEnter(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) + { + // TODO: check whether we can handle this type of object at all and set *pdwEffect &= DROPEFFECT_NONE if not; + + // do something useful to flag to our application that files have been dragged from the OS into our application + //... + dragdrop_data.is_dragging_file = true; + + // trigger MouseDown for button 1 within ImGui + //... + + *pdwEffect &= DROPEFFECT_COPY; + return S_OK; + } + + // occurs when we drag files out from our applications view + HRESULT DragLeave() { + dragdrop_data.is_dragging_file = false; + return S_OK; + } + + // occurs when we drag the mouse over our applications view whilst carrying files (post Enter, pre Leave) + HRESULT DragOver(DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) + { + // trigger MouseMove within ImGui, position is within pt.x and pt.y + // grfKeyState contains flags for control, alt, shift etc + //... + + *pdwEffect &= DROPEFFECT_COPY; + return S_OK; + } + + // occurs when we release the mouse button to finish the drag-drop operation + HRESULT Drop(IDataObject *pDataObj, DWORD grfKeyState, POINTL pt, DWORD *pdwEffect) + { + dragdrop_data.is_dragging_file = false; + // grfKeyState contains flags for control, alt, shift etc + + // render the data into stgm using the data description in fmte + FORMATETC fmte = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM stgm; + + if (SUCCEEDED(pDataObj->GetData(&fmte, &stgm))) + { + HDROP hdrop = (HDROP)stgm.hGlobal; // or reinterpret_cast<HDROP> if preferred + UINT file_count = DragQueryFile(hdrop, 0xFFFFFFFF, NULL, 0); + + // We only accept 1 file for now.. + for (UINT i = 0; i < 1; i++) + { + TCHAR szFile[MAX_PATH]; + UINT cch = DragQueryFile(hdrop, i, szFile, MAX_PATH); + if (cch > 0 && cch < MAX_PATH) + { + WideCharToMultiByte(CP_UTF8,0,szFile,-1,(LPSTR)dragdrop_data.path, MAX_INPUT_LENGTH, NULL, NULL); + } + } + + // we have to release the data when we're done with it + ReleaseStgMedium(&stgm); + + dragdrop_data.did_drop = true; + } + + // trigger MouseUp for button 1 within ImGui + //... + + *pdwEffect &= DROPEFFECT_COPY; + return S_OK; + } +};
\ No newline at end of file |
