对目标对象进行剪贴板的操作时,系统必须有相应对象的剪贴板数据格式,
如字符串的剪贴板格式为CF_TXT,位图的剪贴板格式为CF_BITMAP。
但是,我们在进行数据库的开发时,特别是在开发通讯类数据库产品时,一般需要用到在多个不同格式的字段之间同时传递数据,这就需要我们向系统定义自己特定的剪贴板数据格式,这样我们才能进行相应的操作。那么特定的剪贴板格式如何实现能?最近笔者在为单位编写人事管理程序时,实现了上述要求。
现以实现一个包含日期字段数据和字符串字段数据的剪贴板格式为例,把方法和步骤介绍如下:
首先,在delphi中新建一个项目文件project1.prg,然后在form1上,添加TDateTimePicker、TEdit ,
Tlabel和TButton控件。保存单元文件为Unit1.pas。
然后,在unit1.pas中进行代码的编辑,完整代码如下:
unit Form1;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, clipbrd, Mask, ComCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
DateTimepicker1:TDateTimePicker;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormActivate(Sender: TObject);
end;
type
TMyClipboardData = packed record
Department: string[10];
WorkTime: TDateTime;
end;
TData = class
public
MyClipboardData: TMyClipboardData;
procedure MyCopyToClipBoard;
procedure MyGetFromClipBoard;
end;
var
Form1: TForm;
clipboardhandle: word; //定义一个剪贴版句柄// const
MyClipBoardFormat='MylpszFormat';
//定义自己的剪贴数据格式名称// implementation
{$R *.DFM}
procedure TData.MyCopyToClipBoard;
const
enterdata = #13#10;
//定义回车换行符// var
Datahandle: THandle;
DataPointer: Pointer;
TempString: String[50];
begin
Datahandle := GlobalAlloc(GMEM_MOVEABLE, SizeOf(TMyClipboardData)); //首先在内存堆中给自己定义的数据结构分配内存空间// DataPointer := GlobalLock(DataHandle); //取得所分配的内存单元地址// Move(MyClipboardData, DataPointer^, SizeOf(TMyClipboardData)); //因为我们用到的是TData类,因此必须使自己的目标对象中的数自己所获得
//内存空间相连 ClipBoard.Open;
//打开剪贴版,在进行多格式数据进入剪贴版时,必须进行该操作,
//详见帮助文件win32.hlp// ClipBoard.SetAsHandle(clipboardhandle, DataHandle); //使剪贴版获得自己分配的内存空间,并且设置句柄名称为clipboardhandle// with MyClipboardData do
TempString := Department+enterdata+DateTimeToStr(WorkTime); //把不同格式的数据转换成字符串// ClipBoard.AsText := TempString; //把数据保存到剪贴版// ClipBoard.Open; //打开剪贴版后必须关闭// GlobalUnLock(Datahandle);
end;
procedure TData.MyGetFromClipBoard; //这个过程实际上是MyCopyToClipBoard的逆过程// var
Datahandle: THandle;
DataPointer: Pointer;
MemorySize: Integer;
begin
Datahandle := ClipBoard.GetAsHandle(clipboardhandle); //取得所定义的句柄名称// if Datahandle = 0 then Exit;
DataPointer := GlobalLock(Datahandle);
//取得该句柄所对应的内存空间 if SizeOf(TMyClipboardData) > GlobalSize(Datahandle) then
MemorySize := GlobalSize(Datahandle)
else
MemorySize := SizeOf(TMyClipboardData); //重新进行内存空间大小判断,防止数据出界// Move(DataPointer^, MyClipboardData, memorySize); //把数据传回自己定义的结构中// GlobalUnlock(DataHandle);
//释放剪贴版句柄// end;
procedure TForm1.Button1Click(Sender: TObject);
var
MyNewDataObj: TData; //实现自己定义类的一个实例// begin
MynewDataObj := TData.Create;
with MyNewDataObj.MyClipboardData do
begin
department:= Edit1.Text;
WorkTime := DateTimepicker1.Date;
MyNewDataObj.MyCopyToClipBoard; //实现自己多格式数据的复制// end;
MyNewDataObj.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
MyNewDataObj: TData;
begin
MynewDataObj := TData.Create;
if ClipBoard.HasFormat(clipboardhandle) then //判断在剪贴板中是否有自己定义的剪贴板句柄存在// with MynewDataObj.MyClipboardData do
begin
MyNewDataObj.MyGetFromClipBoard;
Edit1.Text := Department;
DateTimepicker1.Date := WorkTime; //把数据从自己定义的结构中传回到程序中// end;
MyNewDataObj.Free;
end;
procedure TForm1.FormActivate(Sender: TObject);
begin
clipboardhandle:= RegisterClipBoardFormat(MyClipBoardFormat);
label1.caption:='工作地点';
label2.caption:='工作时间';
Edit1.Text:='';
Button1.Caption:='复制';
Button2.Caption:='粘贴';
end;
end.
|
当程序启动时,用户分别在两个输入框中输入任意数据,按复制键。然后除去自己输入的数据,按粘贴键,数据回来了。
如果用户希望能够设计出更加复杂的剪贴板数据格式,只需要在定义好数据结构后在把他们用统一格式读入内存即可。