Articles   Members Online:
-Article/Tip Search
-News Group Search over 21 Million news group articles.
-Delphi/Pascal
-CBuilder/C++
-C#Builder/C#
-JBuilder/Java
-Kylix
Member Area
-Home
-Account Center
-Top 10 NEW!!
-Submit Article/Tip
-Forums Upgraded!!
-My Articles
-Edit Information
-Login/Logout
-Become a Member
-Why sign up!
-Newsletter
-Chat Online!
-Indexes NEW!!
Employment
-Build your resume
-Find a job
-Post a job
-Resume Search
Contacts
-Contacts
-Feedbacks
-Link to us
-Privacy/Disclaimer
Embarcadero
Visit Embarcadero
Embarcadero Community
JEDI
Links
How to use Clipboard access routines which use only API functions Turn on/off line numbers in source code. Switch to Orginial background IDE or DSP color Comment or reply to this aritlce/tip for discussion. Bookmark this article to my favorite article(s). Print this article
Clipboard access routines which use only API functions 27-Aug-02
Category
Win API
Language
Delphi 2.x
Views
108
User Rating
No Votes
# Votes
0
Replies
0
Publisher:
DSP, Administrator
Reference URL:
DKB
			Author: Peter Below 

Clipboard access routines which use only API functions

Answer:

Solve 1:

This unit provides clipboard access routines that do not rely on the VCL Clipbrd 
unit. That unit drags in Dialogs and Forms and a major part of the VCL as a 
consequence, not appropriate for simple console or non-form programs. This unit 
uses only API routines, the only VCL units used are Classes (for exceptions and 
streams) and SysUtils.

1   {Clipboard access routines using only API functions
2   Author: Dr. Peter Below
3   Version 1.0 created 5 Juli 2000
4   Current revision 1.0
5   Last modified: 5 Juli 2000}
6   
7   unit APIClipboard;
8   
9   interface
10  
11  uses
12    Windows, Classes;
13  
14  procedure StringToClipboard(const S: string);
15  function ClipboardAsString: string;
16  procedure CopyDataToClipboard(fmt: DWORD; const data; datasize: Integer;
17    emptyClipboardFirst: Boolean = true);
18  procedure CopyDataFromClipboard(fmt: DWORD; S: TStream);
19  function ClipboardHasFormat(fmt: DWORD): Boolean;
20  
21  implementation
22  
23  uses
24    Sysutils;
25  
26  type
27    {This is an internal exception class used by the unit=APIClipboard }
28    EclipboardError = class(Exception)
29    public
30      constructor Create(const msg: string);
31    end;
32  
33  resourcestring
34    eSystemOutOfMemory = 'could not allocate memory for clipboard data.';
35    eLockfailed = 'could not lock global memory handle.';
36    eSetDataFailed = 'could not copy data block to clipboard.';
37    eCannotOpenClipboard = 'could not open the clipboard.';
38    eErrorTemplate = 'APIClipboard: %s'#13#10 + 'System error code: %d'#13#10
39      + 'System error message: %s';
40  
41    {EClipboardError.Create - Creates a new EclipboardError object
42  
43    Param msg is the string to embed into the error message
44    Precondition: none
45    Postcondition: none
46  
47    Description:
48    Composes an error message that contains the passed message and the API error code
49    and matching error message. The CreateFmt constructor inherited from the basic    
50  Exception class is used to do the work.
51  
52    Created 5.7.2000 by P. Below}
53  
54  constructor EClipboardError.Create(const msg: string);
55  begin
56    CreateFmt(eErrorTemplate, [msg, GetLastError, SysErrorMessage(GetLastError)]);
57  end;
58  
59  {DataToClipboard - Copies a block of memory to the clipboard in a given format
60  
61  Param fmt is the clipboard format to use
62  Param data is an untyped const parameter that addresses the data to copy
63  Param datasize is the size of the data, in bytes
64  
65  Precondition:
66  The clipboard is already open. If not an EClipboardError will result. This 
67  precondition cannot be asserted, unfortunately.
68  
69  Postcondition:
70  Any previously exisiting data of this format will have been replaced by the new 
71  data, unless datasize was 0 or we run into an exception. In this case the clipboard 
72  will be unchanged.
73  
74  Description:
75  Uses API methods to allocate and lock a global memory block of approproate size,
76  copies the data to it and submits the block to the clipboard. Any error on the way 
77  will raise an EClipboardError exception.
78  
79  Created 5.7.2000 by P. Below}
80  
81  procedure DataToClipboard(fmt: DWORD; const data; datasize: Integer);
82  var
83    hMem: THandle;
84    pMem: Pointer;
85  begin
86    if datasize <= 0 then
87      Exit;
88    hMem := GlobalAlloc(GMEM_MOVEABLE or GMEM_SHARE or GMEM_ZEROINIT, datasize);
89    if hmem = 0 then
90      raise EclipboardError.Create(eSystemOutOfMemory);
91    pMem := GlobalLock(hMem);
92    if pMem = nil then
93    begin
94      GlobalFree(hMem);
95      raise EclipboardError.Create(eLockFailed);
96    end;
97    Move(data, pMem^, datasize);
98    GlobalUnlock(hMem);
99    if SetClipboardData(fmt, hMem) = 0 then
100     raise EClipboarderror(eSetDataFailed);
101   {Note: API docs are unclear as to whether the memory block has to be freed in 
102 case of   failure. Since failure is unlikely here lets blithly ignore this issue 
103 for now.}
104 end;
105 
106 {DataFromClipboard - Copies data from the clipboard into a stream
107 
108 Param fmt is the clipboard format to look for
109 Param S is the stream to copy to
110 precondition:  S <> nil
111 postcondition: If data was copied the streams position will have moved
112 
113 Description:
114 Tries to get a memory block for the requested clipboard format. Nothing further is 
115 done if this fails (because the format is not available or the clipboard is not 
116 open, we treat neither as error here), otherwise the memory handle is locked and 
117 the data copied into the stream. Note that we cannot determine the actual size of 
118 the data originally copied to the clipboard, only the allocated size of the memory 
119 block! Since GlobalAlloc works with a granularity of 32 bytes the block may be 
120 larger than required for the data and thus the stream may contain some spurious 
121 bytes at the end. There is no guarantee that these bytes will be 0. If the memory 
122 handle obtained from the clipboard cannot be locked we raise an (see 
123 class=EClipboardError) exception.
124 
125 Created 5.7.2000 by P. Below}
126 
127 procedure DataFromClipboard(fmt: DWORD; S: TStream);
128 var
129   hMem: THandle;
130   pMem: Pointer;
131   datasize: DWORD;
132 begin
133   Assert(Assigned(S));
134   hMem := GetClipboardData(fmt);
135   if hMem <> 0 then
136   begin
137     datasize := GlobalSize(hMem);
138     if datasize > 0 then
139     begin
140       pMem := GlobalLock(hMem);
141       if pMem = nil then
142         raise EclipboardError.Create(eLockFailed);
143       try
144         S.WriteBuffer(pMem^, datasize);
145       finally
146         GlobalUnlock(hMem);
147       end;
148     end;
149   end;
150 end;
151 
152 {CopyDataToClipboard - Copies a block of memory to the clipboard in a given format
153 
154 Param fmt is the clipboard format to use Param data is an untyped const parameter 
155 that addresses the data to copy Param datasize is the size of the data, in bytes 
156 Param emptyClipboardFirst determines if the clipboard should be emptied, true by 
157 default
158 
159 Precondition:
160 The clipboard must not be open already
161 
162 Postcondition:
163 If emptyClipboardFirst is true all prior data will be cleared from the clipboard, 
164 even if
165 datasize is <= 0. The clipboard is closed again.
166 
167 Description:
168 Tries to open the clipboard, empties it if required and then tries to copy the 
169 passed data to the clipboard. This operation is a NOP if datasize <= 0. If the 
170 clipboard cannot be opened a (see class=EClipboardError) is raised.
171 
172 Created 5.7.2000 by P. Below}
173 
174 procedure CopyDataToClipboard(fmt: DWORD; const data; datasize: Integer;
175   emptyClipboardFirst: Boolean = true);
176 begin
177   if OpenClipboard(0) then
178   try
179     if emptyClipboardFirst then
180       EmptyClipboard;
181     DataToClipboard(fmt, data, datasize);
182   finally
183     CloseClipboard;
184   end
185   else
186     raise EclipboardError.Create(eCannotOpenClipboard);
187 end;
188 
189 {StringToClipboard - Copies a string to clipboard in CF_TEXT clipboard format
190 
191 Param S is the string to copy, it may be empty.
192 
193 Precondition:
194 The clipboard must not be open already.
195 
196 Postcondition:
197 Any prior clipboard content will be cleared, but only if S was not empty. The 
198 clipboard is closed again.
199 
200 Description:
201 Hands the brunt of the work off to (See routine=CopyDataToClipboard), but only if S 
202 was not empty. Otherwise nothing is done at all.
203 
204 Created 5.7.2000 by P. Below}
205 
206 procedure StringToClipboard(const S: string);
207 begin
208   if Length(S) > 0 then
209     CopyDataToClipboard(CF_TEXT, S[1], Length(S) + 1);
210 end;
211 
212 {CopyDataFromClipboard - Copies data from the clipboard into a stream
213 
214 Param fmt is the clipboard format to look for
215 Param S is the stream to copy to
216 
217 Precondition:
218 S <> nil
219 The clipboard must not be open already.
220 
221 Postcondition:
222 If data was copied the streams position will have moved. The clipboard is closed 
223 again.
224 
225 Description:
226 Tries to open the clipboard, and then tries to copy the data to the passed stream. 
227 This operation is a NOP if the clipboard does not contain data in the requested 
228 format. If the clipboard cannot be opened a (see class=EClipboardError) is raised.
229 
230 Created 5.7.2000 by P. Below}
231 
232 procedure CopyDataFromClipboard(fmt: DWORD; S: TStream);
233 begin
234   Assert(Assigned(S));
235   if OpenClipboard(0) then
236   try
237     DataFromClipboard(fmt, S);
238   finally
239     CloseClipboard;
240   end
241   else
242     raise EclipboardError.Create(eCannotOpenClipboard);
243 end;
244 
245 {ClipboardAsString - Returns any text contained on the clipboard. Returns the 
246 clipboards content if it contained something in CF_TEXT format, or an empty string.
247 
248 Precondition: The clipboard must not be already open
249 Postcondition: The clipboard is closed.
250 
251 Description:
252 If the clipboard contains data in CF_TEXT format it is copied to a temp memory 
253 stream,
254 zero-terminated for good measure and copied into the result string.
255 
256 Created 5.7.2000 by P. Below}
257 
258 function ClipboardAsString: string;
259 const
260   nullchar: Char = #0;
261 var
262   ms: TMemoryStream;
263 begin
264   if not IsClipboardFormatAvailable(CF_TEXT) then
265     Result := EmptyStr
266   else
267   begin
268     ms := TMemoryStream.Create;
269     try
270       CopyDataFromClipboard(CF_TEXT, ms);
271       ms.Seek(0, soFromEnd);
272       ms.WriteBuffer(nullChar, Sizeof(nullchar));
273       Result := Pchar(ms.Memory);
274     finally
275       ms.Free;
276     end;
277   end;
278 end;
279 
280 {ClipboardHasFormat - Checks if the clipboard contains data in the specified format
281 
282 Param fmt is the format to check for. Returns true if the clipboard contains data 
283 in this format, false otherwise
284 
285 Precondition:  none
286 Postcondition: none
287 
288 Description:
289 This is a simple wrapper around an API function.
290 
291 Created 5.7.2000 by P. Below}
292 
293 function ClipboardHasFormat(fmt: DWORD): Boolean;
294 begin
295   Result := IsClipboardFormatAvailable(fmt);
296 end;
297 
298 end.



Solve 2:

299 uses
300   Windows, SysUtils;
301 
302 procedure SetClipboardText(const S: string);
303 var
304   H: THandle;
305 begin
306   if not OpenClipboard(0) then
307     RaiseLastWin32Error;
308   try
309     if not EmptyClipboard then
310       RaiseLastWin32Error;
311     H := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, Length(S) + 1);
312     if H = 0 then
313       RaiseLastWin32Error;
314     StrPCopy(GlobalLock(H), S);
315     GlobalUnlock(H);
316     SetClipboardData(CF_TEXT, H);
317   finally
318     CloseClipboard;
319   end;
320 end;


			
Vote: How useful do you find this Article/Tip?
Bad Excellent
1 2 3 4 5 6 7 8 9 10

 

Advertisement
Share this page
Advertisement
Download from Google

Copyright © Mendozi Enterprises LLC