deskflow/src/lib/platform/MSWindowsDropTarget.cpp
Chris Rizzitello ed1217e9cc
Use Deskflow Name (#7519)
* Use Deskflow Name

* Remove business-oriented options from issue templates

* Remove business-oriented workflow

* Bump version to 3.0.0 (to avoid confusion with previously used version numbers 1.x & 2.x)

* Update readme to reflect new project name and goals

* Found some more "synergy" to rename

* Rename `synlib` to `app`

* Rename `syntool` to `deskflow-legacy`

* Rename `synwinhk` to `dfwhook`

* Rename dirs from synergy to deskflow

* Rename more "Synergy" files

* Rename app bundle ID

* Fixed copyright typo

* Rename only title in serial key dialog (to be moved downstream later)

* Preserve original serial key window for moving downstream

* Restore dialogs ready for moving downstream

* Rename `QDeskflowApplication` to `DeskflowApplication` (the Q is confusing)

* Restore Volker's original project name

* Fixed mimetype

* Fixed weird grammar

* Fixed (more) weird grammar

* Broken link, restoring (but we should move all links out of source)

* Broken link, restoring (but we should move all links out of source)

* Add write permission to valgrind-analysis.yml

* Restore AUR conflicts

* Apply Clang format

* Update ChangeLog

* Back out version change

---------

Co-authored-by: Nick Bolton <nick@symless.com>
2024-09-17 20:00:25 +01:00

149 lines
3.9 KiB
C++

/*
* Deskflow -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "platform/MSWindowsDropTarget.h"
#include "base/Log.h"
#include "common/common.h"
#include <Shlobj.h>
#include <stdio.h>
void getDropData(IDataObject *pDataObject);
MSWindowsDropTarget *MSWindowsDropTarget::s_instance = NULL;
MSWindowsDropTarget::MSWindowsDropTarget() : m_refCount(1), m_allowDrop(false) {
s_instance = this;
}
MSWindowsDropTarget::~MSWindowsDropTarget() {}
MSWindowsDropTarget &MSWindowsDropTarget::instance() {
assert(s_instance != NULL);
return *s_instance;
}
HRESULT
MSWindowsDropTarget::DragEnter(
IDataObject *dataObject, DWORD keyState, POINTL point, DWORD *effect) {
// check if data object contain drop
m_allowDrop = queryDataObject(dataObject);
if (m_allowDrop) {
getDropData(dataObject);
}
*effect = DROPEFFECT_NONE;
return S_OK;
}
HRESULT
MSWindowsDropTarget::DragOver(DWORD keyState, POINTL point, DWORD *effect) {
*effect = DROPEFFECT_NONE;
return S_OK;
}
HRESULT
MSWindowsDropTarget::DragLeave(void) { return S_OK; }
HRESULT
MSWindowsDropTarget::Drop(
IDataObject *dataObject, DWORD keyState, POINTL point, DWORD *effect) {
*effect = DROPEFFECT_NONE;
return S_OK;
}
bool MSWindowsDropTarget::queryDataObject(IDataObject *dataObject) {
// check if it supports CF_HDROP using a HGLOBAL
FORMATETC fmtetc = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
return dataObject->QueryGetData(&fmtetc) == S_OK ? true : false;
}
void MSWindowsDropTarget::setDraggingFilename(char *const filename) {
m_dragFilename = filename;
}
std::string MSWindowsDropTarget::getDraggingFilename() {
return m_dragFilename;
}
void MSWindowsDropTarget::clearDraggingFilename() { m_dragFilename.clear(); }
void getDropData(IDataObject *dataObject) {
// construct a FORMATETC object
FORMATETC fmtEtc = {CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM stgMed;
// See if the dataobject contains any DROP stored as a HGLOBAL
if (dataObject->QueryGetData(&fmtEtc) == S_OK) {
if (dataObject->GetData(&fmtEtc, &stgMed) == S_OK) {
// get data here
PVOID data = GlobalLock(stgMed.hGlobal);
// data object global handler contains:
// DROPFILESfilename1 filename2 two spaces as the end
// TODO: get multiple filenames
wchar_t *wcData = (wchar_t *)((LPBYTE)data + sizeof(DROPFILES));
// convert wchar to char
char *filename = new char[wcslen(wcData) + 1];
filename[wcslen(wcData)] = '\0';
wcstombs(filename, wcData, wcslen(wcData));
MSWindowsDropTarget::instance().setDraggingFilename(filename);
GlobalUnlock(stgMed.hGlobal);
// release the data using the COM API
ReleaseStgMedium(&stgMed);
delete[] filename;
}
}
}
HRESULT __stdcall MSWindowsDropTarget::QueryInterface(
REFIID iid, void **object) {
if (iid == IID_IDropTarget || iid == IID_IUnknown) {
AddRef();
*object = this;
return S_OK;
} else {
*object = 0;
return E_NOINTERFACE;
}
}
ULONG __stdcall MSWindowsDropTarget::AddRef(void) {
return InterlockedIncrement(&m_refCount);
}
ULONG __stdcall MSWindowsDropTarget::Release(void) {
LONG count = InterlockedDecrement(&m_refCount);
if (count == 0) {
delete this;
return 0;
} else {
return count;
}
}