#include "pch.h"
#include "ClipBoard.h"
+#include <ShlObj.h>
+
+inline CLIPFORMAT GetClipTcharTextFormat() { return (sizeof(tchar_t) == 1 ? CF_TEXT : CF_UNICODETEXT); }
/**
* @brief Copies string to clipboard.
* @param [in] currentWindowHandle Handle to current window.
* @return `true` if text copying succeeds, `false` otherwise.
*/
-bool PutToClipboard(const String & text, HWND currentWindowHandle)
+template<>
+bool PutToClipboard<HWND>(const String & text, HWND currentWindowHandle)
{
if (text.empty())
return false;
* @param [in] currentWindowHandle Handle to current window.
* @return `true` if retrieving the clipboard text succeeds, `false` otherwise.
*/
-bool GetFromClipboard(String & text, HWND currentWindowHandle)
+bool GetFromClipboard(String & text)
{
bool bSuccess = false;
- if (OpenClipboard(currentWindowHandle))
+ if (OpenClipboard(nullptr))
{
CLIPFORMAT fmt = GetClipTcharTextFormat();
HGLOBAL hData = GetClipboardData(fmt);
}
return bSuccess;
}
+
+template<>
+void PutFilesToClipboardInternal<HWND>(const String& strPaths, const String& strPathsSepSpc, HWND currentWindowHandle)
+{
+ // CF_HDROP
+ HGLOBAL hDrop = GlobalAlloc(GHND, sizeof(DROPFILES) + sizeof(tchar_t) * strPaths.length());
+ if (hDrop == nullptr)
+ return;
+ if (tchar_t* pDrop = static_cast<tchar_t*>(GlobalLock(hDrop)))
+ {
+ DROPFILES df = { 0 };
+ df.pFiles = sizeof(DROPFILES);
+ df.fWide = (sizeof(tchar_t) > 1);
+ memcpy(pDrop, &df, sizeof(DROPFILES));
+ memcpy((BYTE*)pDrop + sizeof(DROPFILES), (const tchar_t*)strPaths.c_str(), sizeof(tchar_t) * strPaths.length());
+ GlobalUnlock(hDrop);
+ }
+
+ // CF_DROPEFFECT
+ HGLOBAL hDropEffect = GlobalAlloc(GHND, sizeof(DWORD));
+ if (hDropEffect == nullptr)
+ {
+ GlobalFree(hDrop);
+ return;
+ }
+ if (DWORD* p = static_cast<DWORD*>(GlobalLock(hDropEffect)))
+ {
+ *p = DROPEFFECT_COPY;
+ GlobalUnlock(hDropEffect);
+ }
+
+ // CF_UNICODETEXT
+ HGLOBAL hPathnames = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(tchar_t) * (strPathsSepSpc.length() + 1));
+ if (hPathnames == nullptr)
+ {
+ GlobalFree(hDrop);
+ GlobalFree(hDropEffect);
+ return;
+ }
+ if (void* pPathnames = GlobalLock(hPathnames))
+ {
+ memcpy((BYTE*)pPathnames, (const tchar_t*)strPathsSepSpc.c_str(), sizeof(tchar_t) * strPathsSepSpc.length());
+ ((tchar_t*)pPathnames)[strPathsSepSpc.length()] = 0;
+ GlobalUnlock(hPathnames);
+ }
+
+ UINT CF_DROPEFFECT = RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
+ if (::OpenClipboard(currentWindowHandle))
+ {
+ EmptyClipboard();
+ SetClipboardData(CF_HDROP, hDrop);
+ SetClipboardData(CF_DROPEFFECT, hDropEffect);
+ SetClipboardData(GetClipTcharTextFormat(), hPathnames);
+ CloseClipboard();
+ }
+}
+
*/
#pragma once
-#include <windows.h>
#include "UnicodeString.h"
-inline CLIPFORMAT GetClipTcharTextFormat() { return (sizeof(tchar_t) == 1 ? CF_TEXT : CF_UNICODETEXT); }
+template<typename WindowHandle>
+bool PutToClipboard(const String & text, WindowHandle currentWindowHandle);
+bool GetFromClipboard(String & text);
+template<typename WindowHandle>
+void PutFilesToClipboardInternal(const String& strPaths, const String& strPathsSepSpc, WindowHandle currentWindowHandle);
-bool PutToClipboard(const String & text, HWND currentWindowHandle);
-bool GetFromClipboard(String & text, HWND currentWindowHandle);
-
-template<class Container>
-void PutFilesToClipboard(const Container& list, HWND currentWindowHandle)
+template<class Container, typename WindowHandle>
+void PutFilesToClipboard(const Container& list, WindowHandle currentWindowHandle)
{
+ constexpr size_t MaxPathFull = 32767;
String strPaths, strPathsSepSpc;
- strPaths.reserve(list.size() * MAX_PATH_FULL);
- strPathsSepSpc.reserve(list.size() * MAX_PATH_FULL);
+ strPaths.reserve(list.size() * MaxPathFull);
+ strPathsSepSpc.reserve(list.size() * MaxPathFull);
for (Container::const_iterator it = list.begin(); it != list.end(); ++it)
{
strPaths += _T('\0');
strPathsSepSpc = strutils::trim_ws_end(strPathsSepSpc);
- // CF_HDROP
- HGLOBAL hDrop = GlobalAlloc(GHND, sizeof(DROPFILES) + sizeof(tchar_t) * strPaths.length());
- if (hDrop == nullptr)
- return;
- if (tchar_t *pDrop = static_cast<tchar_t *>(GlobalLock(hDrop)))
- {
- DROPFILES df = {0};
- df.pFiles = sizeof(DROPFILES);
- df.fWide = (sizeof(tchar_t) > 1);
- memcpy(pDrop, &df, sizeof(DROPFILES));
- memcpy((BYTE *)pDrop + sizeof(DROPFILES), (const tchar_t*)strPaths.c_str(), sizeof(tchar_t) * strPaths.length());
- GlobalUnlock(hDrop);
- }
-
- // CF_DROPEFFECT
- HGLOBAL hDropEffect = GlobalAlloc(GHND, sizeof(DWORD));
- if (hDropEffect == nullptr)
- {
- GlobalFree(hDrop);
- return;
- }
- if (DWORD *p = static_cast<DWORD *>(GlobalLock(hDropEffect)))
- {
- *p = DROPEFFECT_COPY;
- GlobalUnlock(hDropEffect);
- }
-
- // CF_UNICODETEXT
- HGLOBAL hPathnames = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(tchar_t) * (strPathsSepSpc.length() + 1));
- if (hPathnames == nullptr)
- {
- GlobalFree(hDrop);
- GlobalFree(hDropEffect);
- return;
- }
- if (void *pPathnames = GlobalLock(hPathnames))
- {
- memcpy((BYTE *)pPathnames, (const tchar_t*)strPathsSepSpc.c_str(), sizeof(tchar_t) * strPathsSepSpc.length());
- ((tchar_t *)pPathnames)[strPathsSepSpc.length()] = 0;
- GlobalUnlock(hPathnames);
- }
-
- UINT CF_DROPEFFECT = RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
- if (::OpenClipboard(AfxGetMainWnd()->GetSafeHwnd()))
- {
- EmptyClipboard();
- SetClipboardData(CF_HDROP, hDrop);
- SetClipboardData(CF_DROPEFFECT, hDropEffect);
- SetClipboardData(GetClipTcharTextFormat(), hPathnames);
- CloseClipboard();
- }
+ PutFilesToClipboardInternal(strPaths, strPathsSepSpc, currentWindowHandle);
}