Skip to content

Commit

Permalink
added Drag into List feature
Browse files Browse the repository at this point in the history
  • Loading branch information
daddel80 committed Sep 8, 2024
1 parent 439fcf3 commit 62a9f1d
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 3 deletions.
82 changes: 82 additions & 0 deletions src/DropTarget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#include "DropTarget.h"
#include "MultiReplacePanel.h"

DropTarget::DropTarget(HWND hwnd, MultiReplace* parent)
: _refCount(1), _hwnd(hwnd), _parent(parent) {}

HRESULT DropTarget::DragEnter(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) {
UNREFERENCED_PARAMETER(pDataObj);
UNREFERENCED_PARAMETER(grfKeyState);
UNREFERENCED_PARAMETER(pt);

*pdwEffect = DROPEFFECT_COPY; // Indicate that only copy operations are allowed
return S_OK;
}

HRESULT DropTarget::DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) {
UNREFERENCED_PARAMETER(grfKeyState);
UNREFERENCED_PARAMETER(pt);

*pdwEffect = DROPEFFECT_COPY; // Continue to allow only copy operations
return S_OK;
}

HRESULT DropTarget::DragLeave() {
// Handle the drag leave event with minimal overhead
return S_OK;
}

HRESULT DropTarget::Drop(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) {
UNREFERENCED_PARAMETER(grfKeyState);
UNREFERENCED_PARAMETER(pt);

try {
STGMEDIUM stgMedium;
FORMATETC formatEtc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };

// Check if the data is in file format
if (pDataObj->GetData(&formatEtc, &stgMedium) == S_OK) {
HDROP hDrop = static_cast<HDROP>(GlobalLock(stgMedium.hGlobal));
if (hDrop) {
UINT numFiles = DragQueryFile(hDrop, 0xFFFFFFFF, NULL, 0);
if (numFiles > 0) {
wchar_t filePath[MAX_PATH];
DragQueryFile(hDrop, 0, filePath, MAX_PATH);
_parent->loadListFromCsv(filePath); // Load CSV file
}
GlobalUnlock(stgMedium.hGlobal); // Unlock the global memory object
}
ReleaseStgMedium(&stgMedium); // Release the storage medium
}

*pdwEffect = DROPEFFECT_COPY; // Indicate that the operation was a copy
return S_OK;
}
catch (...) {
// Handle errors silently
*pdwEffect = DROPEFFECT_NONE;
return E_FAIL;
}
}

HRESULT DropTarget::QueryInterface(REFIID riid, void** ppvObject) {
if (riid == IID_IUnknown || riid == IID_IDropTarget) {
*ppvObject = this;
AddRef();
return S_OK;
}
*ppvObject = nullptr;
return E_NOINTERFACE;
}

ULONG DropTarget::AddRef() {
return InterlockedIncrement(&_refCount);
}

ULONG DropTarget::Release() {
ULONG count = InterlockedDecrement(&_refCount);
if (count == 0) {
delete this;
}
return count;
}
31 changes: 31 additions & 0 deletions src/DropTarget.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef DROP_TARGET_H
#define DROP_TARGET_H

#include <Windows.h>
#include <shlobj.h> // Include for IDropTarget and other shell functions

class MultiReplace; // Forward declaration to avoid circular dependency

class DropTarget : public IDropTarget {
public:
DropTarget(HWND hwnd, MultiReplace* parent);
virtual ~DropTarget() {}

// Implement all IDropTarget methods
HRESULT STDMETHODCALLTYPE DragEnter(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) override;
HRESULT STDMETHODCALLTYPE DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) override;
HRESULT STDMETHODCALLTYPE DragLeave() override;
HRESULT STDMETHODCALLTYPE Drop(IDataObject* pDataObj, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) override;

// IUnknown methods
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject) override;
ULONG STDMETHODCALLTYPE AddRef() override;
ULONG STDMETHODCALLTYPE Release() override;

private:
LONG _refCount;
HWND _hwnd;
MultiReplace* _parent;
};

#endif // DROP_TARGET_H
47 changes: 45 additions & 2 deletions src/MultiReplacePanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,18 @@ void MultiReplace::initializeListView() {
ListView_SetExtendedListViewStyle(_replaceListView, LVS_EX_FULLROWSELECT | LVS_EX_SUBITEMIMAGES);
}

void MultiReplace::initializeDragAndDrop() {
dropTarget = new DropTarget(_replaceListView, this); // Create an instance of DropTarget
HRESULT hr = ::RegisterDragDrop(_replaceListView, dropTarget); // Register the ListView as a drop target

if (FAILED(hr)) {
// Safely release the DropTarget instance to avoid memory leaks
delete dropTarget;
dropTarget = nullptr; // Set to nullptr to prevent any unintended usage
}
}


void MultiReplace::moveAndResizeControls() {
// IDs of controls to be moved or resized
const int controlIds[] = {
Expand Down Expand Up @@ -1658,6 +1670,7 @@ INT_PTR CALLBACK MultiReplace::run_dlgProc(UINT message, WPARAM wParam, LPARAM l
initializePluginStyle();
initializeCtrlMap();
initializeListView();
initializeDragAndDrop();
loadSettings();
updateButtonVisibilityBasedOnMode();
updateStatisticsColumnButtonIcon();
Expand Down Expand Up @@ -1709,15 +1722,45 @@ INT_PTR CALLBACK MultiReplace::run_dlgProc(UINT message, WPARAM wParam, LPARAM l
if (_replaceListView && originalListViewProc) {
SetWindowLongPtr(_replaceListView, GWLP_WNDPROC, (LONG_PTR)originalListViewProc);
}
saveSettings();

saveSettings(); // Save any settings before destroying

// Unregister Drag-and-Drop
if (dropTarget) {
RevokeDragDrop(_replaceListView);
delete dropTarget;
dropTarget = nullptr;
}

if (hwndEdit) {
DestroyWindow(hwndEdit);
}

DeleteObject(_hFont);
DestroyWindow(_hSelf);

// Close the debug window if open
if (hDebugWnd != NULL) {
RECT rect;
if (GetWindowRect(hDebugWnd, &rect)) {
debugWindowPosition.x = rect.left;
debugWindowPosition.y = rect.top;
debugWindowPositionSet = true;
debugWindowSize.cx = rect.right - rect.left;
debugWindowSize.cy = rect.bottom - rect.top;
debugWindowSizeSet = true;
}
PostMessage(hDebugWnd, WM_CLOSE, 0, 0);
hDebugWnd = NULL; // Reset the handle after closing
}

DestroyWindow(_hSelf); // Destroy the main window

// Post a quit message to ensure the application terminates cleanly
PostQuitMessage(0);
}
break;


case WM_SIZE:
{
if (isWindowOpen) {
Expand Down
6 changes: 5 additions & 1 deletion src/MultiReplacePanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "StaticDialog/StaticDialog.h"
#include "StaticDialog/resource.h"
#include "PluginInterface.h"
#include "DropTarget.h"

#include <string>
#include <vector>
Expand Down Expand Up @@ -299,6 +300,10 @@ class MultiReplace : public StaticDialog

static std::vector<LogEntry> logChanges;

// Drag-and-Drop functionality
DropTarget* dropTarget; // Pointer to DropTarget instance
void loadListFromCsv(const std::wstring& filePath); // used in DropTarget.cpp
void initializeDragAndDrop();

protected:
virtual INT_PTR CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) override;
Expand Down Expand Up @@ -551,7 +556,6 @@ class MultiReplace : public StaticDialog
bool saveListToCsvSilent(const std::wstring& filePath, const std::vector<ReplaceItemData>& list);
void saveListToCsv(const std::wstring& filePath, const std::vector<ReplaceItemData>& list);
void loadListFromCsvSilent(const std::wstring& filePath, std::vector<ReplaceItemData>& list);
void loadListFromCsv(const std::wstring& filePath);
std::wstring escapeCsvValue(const std::wstring& value);
std::wstring unescapeCsvValue(const std::wstring& value);

Expand Down
2 changes: 2 additions & 0 deletions vs.proj/MultiReplace.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\AboutDialog.h" />
<ClInclude Include="..\src\DropTarget.h" />
<ClInclude Include="..\src\lua\lapi.h" />
<ClInclude Include="..\src\lua\lauxlib.h" />
<ClInclude Include="..\src\lua\lcode.h" />
Expand Down Expand Up @@ -63,6 +64,7 @@
<ClInclude Include="..\src\StaticDialog\StaticDialog.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\DropTarget.cpp" />
<ClCompile Include="..\src\language_mapping.cpp" />
<ClCompile Include="..\src\lua\lapi.c">
<AdditionalOptions>/w %(AdditionalOptions)</AdditionalOptions>
Expand Down
2 changes: 2 additions & 0 deletions vs.proj/MultiReplace.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
</ClCompile>
<ClCompile Include="..\src\StaticDialog\StaticDialog.cpp" />
<ClCompile Include="..\src\language_mapping.cpp" />
<ClCompile Include="..\src\DropTarget.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\src\AboutDialog.h" />
Expand Down Expand Up @@ -201,6 +202,7 @@
</ClInclude>
<ClInclude Include="..\src\StaticDialog\resource.h" />
<ClInclude Include="..\src\StaticDialog\StaticDialog.h" />
<ClInclude Include="..\src\DropTarget.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\src\MultiReplace.rc" />
Expand Down

0 comments on commit 62a9f1d

Please sign in to comment.