4 Работа с буфером обмена.
7 Copyright (c) 1996 Eugene Roshal
8 Copyright (c) 2000 Far Group
11 Redistribution and use in source and binary forms, with or without
12 modification, are permitted provided that the following conditions
14 1. Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16 2. Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in the
18 documentation and/or other materials provided with the distribution.
19 3. The name of the authors may not be used to endorse or promote products
20 derived from this software without specific prior written permission.
22 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "headers.hpp"
36 #include "clipboard.hpp"
37 #include "console.hpp"
39 static const wchar_t FAR_VerticalBlock_Unicode
[] = L
"FAR_VerticalBlock_Unicode";
41 /* ------------------------------------------------------------ */
42 // CF_OEMTEXT CF_TEXT CF_UNICODETEXT CF_HDROP
43 HGLOBAL
Clipboard::hInternalClipboard
[5] = {0};
44 UINT
Clipboard::uInternalClipboardFormat
[5] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
46 bool Clipboard::UseInternalClipboard
= false;
47 bool Clipboard::InternalClipboardOpen
= false;
49 // Sets UseInternalClipboard to State, and returns previous state
50 bool Clipboard::SetUseInternalClipboardState(bool State
)
52 bool OldState
= UseInternalClipboard
;
53 UseInternalClipboard
= State
;
57 bool Clipboard::GetUseInternalClipboardState()
59 return UseInternalClipboard
;
62 UINT
Clipboard::RegisterFormat(LPCWSTR lpszFormat
)
64 if (UseInternalClipboard
) {
65 if (!StrCmp(lpszFormat
, FAR_VerticalBlock_Unicode
)) {
72 return WINPORT(RegisterClipboardFormat
)(lpszFormat
);
75 BOOL
Clipboard::Open()
77 if (UseInternalClipboard
) {
78 if (!InternalClipboardOpen
) {
79 InternalClipboardOpen
= true;
86 return WINPORT(OpenClipboard
)(NULL
); // Console.GetWindow());
89 BOOL
Clipboard::Close()
91 if (UseInternalClipboard
) {
92 if (InternalClipboardOpen
) {
93 InternalClipboardOpen
= false;
100 return WINPORT(CloseClipboard
)();
103 BOOL
Clipboard::Empty()
105 if (UseInternalClipboard
) {
106 if (InternalClipboardOpen
) {
107 for (size_t I
= 0; I
< ARRAYSIZE(hInternalClipboard
); ++I
) {
108 if (hInternalClipboard
[I
]) {
109 WINPORT(ClipboardFree
)(hInternalClipboard
[I
]);
110 hInternalClipboard
[I
] = 0;
111 uInternalClipboardFormat
[I
] = 0xFFFF;
121 return WINPORT(EmptyClipboard
)();
124 HANDLE
Clipboard::GetData(UINT uFormat
)
126 if (UseInternalClipboard
) {
127 if (InternalClipboardOpen
&& uFormat
!= 0xFFFF) {
128 for (size_t I
= 0; I
< ARRAYSIZE(hInternalClipboard
); ++I
) {
129 if (uInternalClipboardFormat
[I
] == uFormat
) {
130 return hInternalClipboard
[I
];
135 return (HANDLE
) nullptr;
138 return WINPORT(GetClipboardData
)(uFormat
);
141 HANDLE
Clipboard::SetData(UINT uFormat
, HANDLE hMem
)
143 if (UseInternalClipboard
) {
144 if (InternalClipboardOpen
) {
145 for (size_t I
= 0; I
< ARRAYSIZE(hInternalClipboard
); ++I
) {
146 if (!hInternalClipboard
[I
]) {
147 hInternalClipboard
[I
] = hMem
;
148 uInternalClipboardFormat
[I
] = uFormat
;
154 return (HANDLE
) nullptr;
157 return WINPORT(SetClipboardData
)(uFormat
, hMem
);
160 bool Clipboard::IsFormatAvailable(UINT Format
)
162 if (UseInternalClipboard
) {
163 for (size_t I
= 0; I
< ARRAYSIZE(hInternalClipboard
); ++I
) {
164 if (uInternalClipboardFormat
[I
] != 0xFFFF && uInternalClipboardFormat
[I
] == Format
) {
172 return WINPORT(IsClipboardFormatAvailable
)(Format
) != FALSE
;
175 // Перед вставкой производится очистка буфера
176 bool Clipboard::Copy(const wchar_t *Data
, bool IsVertical
)
180 if (!AddData(CF_UNICODETEXT
, Data
, (wcslen(Data
) + 1) * sizeof(wchar_t))) {
185 UINT FormatType
= RegisterFormat(FAR_VerticalBlock_Unicode
);
187 AddData(FormatType
, "\0\0\0\0", 4);
194 bool Clipboard::AddData(UINT FormatType
, const void *Data
, size_t Size
)
199 void *CData
= WINPORT(ClipboardAlloc
)(Size
);
204 memcpy(CData
, Data
, Size
);
205 if (!SetData(FormatType
, (HANDLE
)CData
)) {
206 WINPORT(ClipboardFree
)(CData
);
213 // max - без учета символа конца строки!
214 // max = -1 - there is no limit!
215 wchar_t *Clipboard::Paste(bool &IsVertical
, int MaxChars
)
217 PVOID ClipData
= GetData(CF_UNICODETEXT
);
223 wcsnlen((const wchar_t *)ClipData
, WINPORT(ClipboardSize
)(ClipData
) / sizeof(wchar_t));
225 if (MaxChars
>= 0 && CharsCount
< (size_t)MaxChars
)
226 CharsCount
= (size_t)MaxChars
;
228 wchar_t *ClipText
= (wchar_t *)malloc((CharsCount
+ 1) * sizeof(wchar_t));
230 wmemcpy(ClipText
, (const wchar_t *)ClipData
, CharsCount
);
231 ClipText
[CharsCount
] = 0;
236 if (wcsstr(ClipText
, NATIVE_EOLW
)) {
237 UINT FormatType
= RegisterFormat(FAR_VerticalBlock_Unicode
);
238 if (FormatType
&& IsFormatAvailable(FormatType
)) {
246 wchar_t *Clipboard::Paste()
249 return Paste(IsVertical
);
252 /* ------------------------------------------------------------ */
253 int WINAPI
CopyToClipboard(const wchar_t *Data
)
260 BOOL ret
= clip
.Copy(Data
);
267 wchar_t *PasteFromClipboardEx(int MaxChars
)
275 wchar_t *ClipText
= clip
.Paste(IsVertical
, MaxChars
);
282 wchar_t *WINAPI
PasteFromClipboard()
284 return PasteFromClipboardEx();
287 BOOL
EmptyInternalClipboard()
289 bool OldState
= Clipboard::SetUseInternalClipboardState(true);
296 BOOL ret
= clip
.Empty();
300 Clipboard::SetUseInternalClipboardState(OldState
);