OSDN Git Service

Move Windows dependent code from ClipBoard.h to Clipboard.cpp
[winmerge-jp/winmerge-jp.git] / Src / Common / ClipBoard.cpp
1 /**
2  * @file  ClipBoard.cpp
3  *
4  * @brief ClipBoard helper functions implementations.
5  */
6
7 #include "pch.h"
8 #include "ClipBoard.h"
9 #include <ShlObj.h>
10
11 inline CLIPFORMAT GetClipTcharTextFormat() { return (sizeof(tchar_t) == 1 ? CF_TEXT : CF_UNICODETEXT); }
12
13 /**
14  * @brief Copies string to clipboard.
15  * @param [in] text Text to copy to clipboard.
16  * @param [in] currentWindowHandle Handle to current window.
17  * @return `true` if text copying succeeds, `false` otherwise.
18  */
19 template<>
20 bool PutToClipboard<HWND>(const String & text, HWND currentWindowHandle)
21 {
22         if (text.empty())
23                 return false;
24
25         bool bOK = false;
26         if (OpenClipboard(currentWindowHandle))
27         {
28                 EmptyClipboard();
29                 const size_t dataSiz = text.length() + 1;
30                 HGLOBAL hData = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dataSiz * sizeof(tchar_t));
31                 if (hData != nullptr)
32                 {
33                         if (tchar_t* pszData = static_cast<tchar_t*>(::GlobalLock(hData)))
34                         {
35                                 tc::tcslcpy(pszData, dataSiz, text.c_str());
36                                 GlobalUnlock(hData);
37                         }
38                         CLIPFORMAT fmt = GetClipTcharTextFormat();
39                         bOK = SetClipboardData(fmt, hData) != nullptr;
40                 }
41                 CloseClipboard();
42         }
43         return bOK;
44 }
45
46 /**
47  * @brief Retrieves the string from clipboard.
48  * @param [out] text Text copied from clipboard.
49  * @param [in] currentWindowHandle Handle to current window.
50  * @return `true` if retrieving the clipboard text succeeds, `false` otherwise.
51  */
52 bool GetFromClipboard(String & text)
53 {
54         bool bSuccess = false;
55         if (OpenClipboard(nullptr))
56         {
57                 CLIPFORMAT fmt = GetClipTcharTextFormat();
58                 HGLOBAL hData = GetClipboardData(fmt);
59                 if (hData != nullptr)
60                 {
61                         tchar_t* pszData = (tchar_t*) GlobalLock(hData);
62                         if (pszData != nullptr)
63                         {
64                                 text = pszData;
65                                 GlobalUnlock(hData);
66                                 bSuccess = true;
67                         }
68                 }
69                 CloseClipboard();
70         }
71         return bSuccess;
72 }
73
74 template<>
75 void PutFilesToClipboardInternal<HWND>(const String& strPaths, const String& strPathsSepSpc, HWND currentWindowHandle)
76 {
77         // CF_HDROP
78         HGLOBAL hDrop = GlobalAlloc(GHND, sizeof(DROPFILES) + sizeof(tchar_t) * strPaths.length());
79         if (hDrop == nullptr)
80                 return;
81         if (tchar_t* pDrop = static_cast<tchar_t*>(GlobalLock(hDrop)))
82         {
83                 DROPFILES df = { 0 };
84                 df.pFiles = sizeof(DROPFILES);
85                 df.fWide = (sizeof(tchar_t) > 1);
86                 memcpy(pDrop, &df, sizeof(DROPFILES));
87                 memcpy((BYTE*)pDrop + sizeof(DROPFILES), (const tchar_t*)strPaths.c_str(), sizeof(tchar_t) * strPaths.length());
88                 GlobalUnlock(hDrop);
89         }
90
91         // CF_DROPEFFECT
92         HGLOBAL hDropEffect = GlobalAlloc(GHND, sizeof(DWORD));
93         if (hDropEffect == nullptr)
94         {
95                 GlobalFree(hDrop);
96                 return;
97         }
98         if (DWORD* p = static_cast<DWORD*>(GlobalLock(hDropEffect)))
99         {
100                 *p = DROPEFFECT_COPY;
101                 GlobalUnlock(hDropEffect);
102         }
103
104         // CF_UNICODETEXT
105         HGLOBAL hPathnames = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, sizeof(tchar_t) * (strPathsSepSpc.length() + 1));
106         if (hPathnames == nullptr)
107         {
108                 GlobalFree(hDrop);
109                 GlobalFree(hDropEffect);
110                 return;
111         }
112         if (void* pPathnames = GlobalLock(hPathnames))
113         {
114                 memcpy((BYTE*)pPathnames, (const tchar_t*)strPathsSepSpc.c_str(), sizeof(tchar_t) * strPathsSepSpc.length());
115                 ((tchar_t*)pPathnames)[strPathsSepSpc.length()] = 0;
116                 GlobalUnlock(hPathnames);
117         }
118
119         UINT CF_DROPEFFECT = RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
120         if (::OpenClipboard(currentWindowHandle))
121         {
122                 EmptyClipboard();
123                 SetClipboardData(CF_HDROP, hDrop);
124                 SetClipboardData(CF_DROPEFFECT, hDropEffect);
125                 SetClipboardData(GetClipTcharTextFormat(), hPathnames);
126                 CloseClipboard();
127         }
128 }
129