|
在Delphi中有一些全局对象,永远不要去构造它们的实例。其中有两个对象是以全局cXzLinux联盟 变量的方式提供的,这两个变量一个是Application(TApplication类型,包含Forms单元即cXzLinux联盟 可调用),另一个是Screen(TScreen类型,包含Forms单元即可调用)。而另外两个对象是以cXzLinux联盟 函数方式提供的,这两个对象一个是Printer(TPrinter类型,包含Printers单元就可调),cXzLinux联盟 另一个就是Clipboard(TClipboard类型,包含Clipbrd单元就可调用)。用函数而不是全局变cXzLinux联盟 量会令实际的变量存贮在单元的实现部分而不是接口部分,这样就永远不能对它赋值。cXzLinux联盟 现在介绍Clipboard的编程。cXzLinux联盟 Clipboard是由系统自动实例化的一个对象,通过该对象可以操作剪贴板,可以存取和cXzLinux联盟 清除剪贴板的内容。不过一般不显式地操作剪贴板,而是通过操作其它的控件或由系统自动cXzLinux联盟 更新剪贴板内容。如基于TCustomEdit的控件(如TEdit, TMemo,TRichEdit等)就有直接操作cXzLinux联盟 剪贴板的方法:CopyToClipboard,CutToClipboard和PasterFromClipboard。事实上在cXzLinux联盟 TCustomEdit运行时,Ctrl+C, Ctrl+X, Ctrl+V自动定义成了操作剪贴板的热键,不用cXzLinux联盟 编写任何代码。剪贴板的内容可以通过查询HasFormat获得其格式。Windows系统支持三cXzLinux联盟 种基本格式:CF_TEXT, CF_BITMAP和CF_METAFILEPICT,分别表示文本、位图和元文件图cXzLinux联盟 象,其它的格式难以预知,因为任何新的格式都需要向Windows注册新类型。Delphi就注cXzLinux联盟 册了两种类型:CF_PICTURE(TPicture类型,包括TIcon, TBitmap和TMetafile)和cXzLinux联盟 CF_COMPONENT(TComponent类型)。全部的格式可以通过Windows API的枚举函数cXzLinux联盟 CountClipboardFormats和EnumClipboardFormats测知,甚至还可以用GetClipboardFormatNamecXzLinux联盟 查出每种格式的名称。cXzLinux联盟 Clipboard的基类是TPersistent,说明Clipboard不能处理任何Windows消息。剪贴板cXzLinux联盟 是由Windows运行中的所有任务共同操作的,当有任何一个任务修改剪贴板内容时,不能cXzLinux联盟 自动通知需要监测剪贴板状态的窗口。如果工具栏中有一个粘贴的按钮,不能动态地修改cXzLinux联盟 这个按钮的活动状态。有两种方法可以解决这个问题:一个是重载主窗体的Windows消息过cXzLinux联盟 程,并在OnCreate和OnDestroy添加和注销剪贴板观察窗体链。另一个是设计一个剪贴板监cXzLinux联盟 控器部件,需要时添加到主窗体中即可。显然第二种方法较好。cXzLinux联盟 cXzLinux联盟 unit ClipMonitor;cXzLinux联盟 cXzLinux联盟 interfacecXzLinux联盟 cXzLinux联盟 usescXzLinux联盟 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,cXzLinux联盟 StdCtrls, clipbrd;cXzLinux联盟 cXzLinux联盟 typecXzLinux联盟 TClipFormat = (cfNone, cfText, cfBitmap, cfMetaFilePict,cXzLinux联盟 cfPicture, cfComponent, cfOther);cXzLinux联盟 cXzLinux联盟 TClipMonitor = class(TComponent)cXzLinux联盟 privatecXzLinux联盟 FHandle, FNextViewerHandle: THandle;cXzLinux联盟 FActive: Boolean;cXzLinux联盟 FOnChange:TNotifyEvent;cXzLinux联盟 OldWndProc, NewWndProc: Pointer;cXzLinux联盟 procedure SetActive(Value: Boolean);cXzLinux联盟 function GetFormat: TClipFormat;cXzLinux联盟 procedure SetFormat(Value: TClipFormat);cXzLinux联盟 protectedcXzLinux联盟 procedure NewWndMethod(var msg: TMessage);cXzLinux联盟 procedure Loaded; override;cXzLinux联盟 publiccXzLinux联盟 constructor Create(AOwner: TComponent); override;cXzLinux联盟 destructor Destroy; override;cXzLinux联盟 publishedcXzLinux联盟 property Active: Boolean read FActive write SetActive default False;cXzLinux联盟 property Format: TClipFormat read GetFormat write SetFormat stored False;cXzLinux联盟 property OnChange: TNotifyEvent read FOnChange write FOnChange;cXzLinux联盟 end;cXzLinux联盟 cXzLinux联盟 procedure Register;cXzLinux联盟 cXzLinux联盟 implementationcXzLinux联盟 cXzLinux联盟 procedure Register;cXzLinux联盟 begincXzLinux联盟 RegisterComponents('System', [TClipMon]);cXzLinux联盟 end;cXzLinux联盟 cXzLinux联盟 constructor TClipMon.Create(AOwner: TComponent);cXzLinux联盟 begincXzLinux联盟 if not (AOwner is TForm) thencXzLinux联盟 raise Exception.CreateFmt('''%s'' is not a Form', [AOwner.Name])cXzLinux联盟 else if AOwner = nil thencXzLinux联盟 raise Exception.Create('No Windowized Owner');cXzLinux联盟 inherited Create(AOwner);cXzLinux联盟 FHandle := (Owner as TForm).Handle;cXzLinux联盟 FNextViewerHandle := 0;cXzLinux联盟 FActive := False;cXzLinux联盟 FNextViewerHandle := SetClipboardViewer(FHandle);cXzLinux联盟 if not (csDesigning in ComponentState) then begincXzLinux联盟 NewWndProc := MakeObjectInstance(NewWndMethod);cXzLinux联盟 OldWndProc := Pointer(SetWindowLong(FHandle, GWL_WNDPROC,cXzLinux联盟 LongInt(NewWndProc)));cXzLinux联盟 end else begincXzLinux联盟 NewWndProc := nil;cXzLinux联盟 OldWndProc := nil;cXzLinux联盟 end;cXzLinux联盟 end;cXzLinux联盟 cXzLinux联盟 destructor TClipMon.Destroy;cXzLinux联盟 begincXzLinux联盟 ChangeClipboardChain(FHandle, FNextViewerHandle);cXzLinux联盟 if Assigned(NewWndProc) then begincXzLinux联盟 SetWindowLong(FHandle, GWL_WNDPROC, Longint(OldWndProc));cXzLinux联盟 FreeObjectInstance(NewWndProc);cXzLinux联盟 end;cXzLinux联盟 inherited Destroy;cXzLinux联盟 end;cXzLinux联盟 cXzLinux联盟 {设置是否允许自动剪贴板监控}cXzLinux联盟 procedure TClipMon.SetActive(Value: Boolean);cXzLinux联盟 begincXzLinux联盟 if FActive <> Value then FActive := Value;cXzLinux联盟 end;cXzLinux联盟 cXzLinux联盟 {取剪贴板格式}cXzLinux联盟 function TClipMon.GetFormat: TClipFormat;cXzLinux联盟 varcXzLinux联盟 I: Integer;cXzLinux联盟 begincXzLinux联盟 Result := cfNone;cXzLinux联盟 if Clipboard.HasFormat(CF_TEXT) then Result := cfTextcXzLinux联盟 else if Clipboard.HasFormat(CF_BITMAP) then Result := cfBitmapcXzLinux联盟 else if Clipboard.HasFormat(CF_METAFILEPICT) then Result := cfMetaFilePictcXzLinux联盟 else if Clipboard.HasFormat(CF_PICTURE) then Result := cfPicturecXzLinux联盟 else if Clipboard.HasFormat(CF_COMPONENT) then Result := cfComponentcXzLinux联盟 else for I := 0 to Clipboard.FormatCount - 1 docXzLinux联盟 if Clipboard.HasFormat(Clipboard.Formats[I]) then begincXzLinux联盟 Result := cfOther;cXzLinux联盟 Break;cXzLinux联盟 end;cXzLinux联盟 end;cXzLinux联盟 cXzLinux联盟 {伪过程,事实是剪贴板格式是只读的}cXzLinux联盟 procedure TClipMon.SetFormat(Value: TClipFormat);cXzLinux联盟 begincXzLinux联盟 end;cXzLinux联盟 cXzLinux联盟 {处理来自剪贴板观察器链的消息}cXzLinux联盟 procedure TClipMon.NewWndMethod (var msg: TMessage);cXzLinux联盟 begincXzLinux联盟 case msg.msg ofcXzLinux联盟 WM_DRAWCLIPBOARD:cXzLinux联盟 begincXzLinux联盟 Loaded;cXzLinux联盟 msg.Result := SendMessage(WM_DRAWCLIPBOARD,cXzLinux联盟 FNextViewerHandle, 0, 0);cXzLinux联盟 end;cXzLinux联盟 WM_CHANGECBCHAIN:cXzLinux联盟 if THandle(msg.wParam) = FNextViewerHandle then begincXzLinux联盟 FNextViewerHandle := msg.lParam;cXzLinux联盟 msg.Result := 0;cXzLinux联盟 end elsecXzLinux联盟 msg.Result := SendMessage(FNextViewerHandle, WM_CHANGECBCHAIN,cXzLinux联盟 msg.wParam, msg.lParam);cXzLinux联盟 elsecXzLinux联盟 msg.result := CallWindowProc(OldWndProc, FHandle, msg.msg,cXzLinux联盟 msg.WParam, msg.LParam);cXzLinux联盟 end;cXzLinux联盟 end;cXzLinux联盟 cXzLinux联盟 {部件装载完毕}cXzLinux联盟 procedure TClipMon.Loaded;cXzLinux联盟 begincXzLinux联盟 if FActive and Assigned(FOnChange) then FOnChange(Self);cXzLinux联盟 end;cXzLinux联盟 cXzLinux联盟 end.cXzLinux联盟
Linux联盟收集整理 ,转贴请标明原始链接,如有任何疑问欢迎来本站Linux论坛讨论 |
|