判断是否为中文 procedure TForm1.Button1Click(Sender: TObject);var CutLengthOfLine{ 被处理字符串的总长度 }, i, j: integer; sLine{ 被处理的源字符串 }: string; sCuted{ 按固定长度分割出来的部分字符串 }: string; iCutLength{ 按固定长度分割出来的部分字符串的长度 }: integer; bIsDBCS{ 是否是汉字的前半字节 }: boolean;beginif edit1.text='' then beginexit;end; CutLengthOfLine:=strtoint(edit1.text); if CutLengthOfLine < 2 then begin showmessage('CutLengthOfLine 必须大于等于 2 !'); Exit; end; Memo2.Lines.Clear; for i := 0 to Memo1.Lines.Count - 1 do begin sLine := Memo1.Lines[i]; if Length(sLine) = 0 then Memo2.Lines.Add(#13+#10) else repeat //开始处理字符串 iCutLength := CutLengthOfLine; sCuted := Copy(sLine, 1, iCutLength);//从头取出 iCutLength 长的字符串 bIsDBCS := False;//先假设没有半个字符串 for j := 1 to iCutLength do //从头到尾逐个检查,至于为什么?//原作者是这样解释的//1. 为什麽不直接抓最後一个字元判断? 因为中文字的 Trail-byte, 其内码也可能落在 Lead-byte// 的内码区间内.//2. 为什麽不直接抓最後两个字元来判断? 因为前一个字的 Trail-byte 加上後一个字的 Lead-byte,// 可能又是一个中文字. begin if bIsDBCS then //如果上一个字节是汉字的前半部分 bIsDBCS := False //则此时本字节是汉字的后半部分, //所以将是否前半个汉字检测标志设为假 else if Windows.IsDBCSLeadByte(byte(sCuted[j])) then bIsDBCS := True;//否则检查本字节,并根据结果设置标志 end; //end of for//如果最后一个字节的上一个字节是汉字的前半部分,则结束时//检测标志为假, if bIsDBCS then Dec(iCutLength);//如果最后一个字节是汉字的前半部分, 则少截取一个字符,避免乱码 Memo2.Lines.Add(Copy(sLine, 1, iCutLength)); sLine := Copy(sLine, iCutLength + 1, Length(sLine) - iCutLength);//拷贝出下一部分固定长度的字符串,循环处理 until Length(sLine) <= 0; end;memo2.setfocus;memo2.selstart:=0;memo2.SelLength:=0;end;
在Delphi中有一些全局对象,永远不要去构造它们的实例。其中有两个对象是以全局 变量的方式提供的,这两个变量一个是Application(TApplication类型,包含Forms单元即 可调用),另一个是Screen(TScreen类型,包含Forms单元即可调用)。而另外两个对象是以 函数方式提供的,这两个对象一个是Printer(TPrinter类型,包含Printers单元就可调), 另一个就是Clipboard(TClipboard类型,包含Clipbrd单元就可调用)。用函数而不是全局变 量会令实际的变量存贮在单元的实现部分而不是接口部分,这样就永远不能对它赋值。 现在介绍Clipboard的编程。 Clipboard是由系统自动实例化的一个对象,通过该对象可以操作剪贴板,可以存取和 清除剪贴板的内容。不过一般不显式地操作剪贴板,而是通过操作其它的控件或由系统自动 更新剪贴板内容。如基于TCustomEdit的控件(如TEdit, TMemo,TRichEdit等)就有直接操作 剪贴板的方法:CopyToClipboard,CutToClipboard和PasterFromClipboard。事实上在 TCustomEdit运行时,Ctrl+C, Ctrl+X, Ctrl+V自动定义成了操作剪贴板的热键,不用 编写任何代码。剪贴板的内容可以通过查询HasFormat获得其格式。Windows系统支持三 种基本格式:CF_TEXT, CF_BITMAP和CF_METAFILEPICT,分别表示文本、位图和元文件图 象,其它的格式难以预知,因为任何新的格式都需要向Windows注册新类型。Delphi就注 册了两种类型:CF_PICTURE(TPicture类型,包括TIcon, TBitmap和TMetafile)和 CF_COMPONENT(TComponent类型)。全部的格式可以通过Windows API的枚举函数 CountClipboardFormats和EnumClipboardFormats测知,甚至还可以用GetClipboardFormatName 查出每种格式的名称。 Clipboard的基类是TPersistent,说明Clipboard不能处理任何Windows消息。剪贴板 是由Windows运行中的所有任务共同操作的,当有任何一个任务修改剪贴板内容时,不能 自动通知需要监测剪贴板状态的窗口。如果工具栏中有一个粘贴的按钮,不能动态地修改 这个按钮的活动状态。有两种方法可以解决这个问题:一个是重载主窗体的Windows消息过 程,并在OnCreate和OnDestroy添加和注销剪贴板观察窗体链。另一个是设计一个剪贴板监 控器部件,需要时添加到主窗体中即可。显然第二种方法较好。unit ClipMonitor;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, clipbrd;type TClipFormat = (cfNone, cfText, cfBitmap, cfMetaFilePict, cfPicture, cfComponent, cfOther); TClipMonitor = class(TComponent) private FHandle, FNextViewerHandle: THandle; FActive: Boolean; FOnChange:TNotifyEvent; OldWndProc, NewWndProc: Pointer; procedure SetActive(Value: Boolean); function GetFormat: TClipFormat; procedure SetFormat(Value: TClipFormat); protected procedure NewWndMethod(var msg: TMessage); procedure Loaded; override; public constructor Create(AOwner: TComponent); override; destructor Destroy; override; published property Active: Boolean read FActive write SetActive default False; property Format: TClipFormat read GetFormat write SetFormat stored False; property OnChange: TNotifyEvent read FOnChange write FOnChange; end;procedure Register;implementationprocedure Register; begin RegisterComponents('System', [TClipMon]); end;constructor TClipMon.Create(AOwner: TComponent); begin if not (AOwner is TForm) then raise Exception.CreateFmt('''%s'' is not a Form', [AOwner.Name]) else if AOwner = nil then raise Exception.Create('No Windowized Owner'); inherited Create(AOwner); FHandle := (Owner as TForm).Handle; FNextViewerHandle := 0; FActive := False; FNextViewerHandle := SetClipboardViewer(FHandle); if not (csDesigning in ComponentState) then begin NewWndProc := MakeObjectInstance(NewWndMethod); OldWndProc := Pointer(SetWindowLong(FHandle, GWL_WNDPROC, LongInt(NewWndProc))); end else begin NewWndProc := nil; OldWndProc := nil; end; end;destructor TClipMon.Destroy; begin ChangeClipboardChain(FHandle, FNextViewerHandle); if Assigned(NewWndProc) then begin SetWindowLong(FHandle, GWL_WNDPROC, Longint(OldWndProc)); FreeObjectInstance(NewWndProc); end; inherited Destroy; end;{设置是否允许自动剪贴板监控} procedure TClipMon.SetActive(Value: Boolean); begin if FActive <> Value then FActive := Value; end;{取剪贴板格式} function TClipMon.GetFormat: TClipFormat; var I: Integer; begin Result := cfNone; if Clipboard.HasFormat(CF_TEXT) then Result := cfText else if Clipboard.HasFormat(CF_BITMAP) then Result := cfBitmap else if Clipboard.HasFormat(CF_METAFILEPICT) then Result := cfMetaFilePict else if Clipboard.HasFormat(CF_PICTURE) then Result := cfPicture else if Clipboard.HasFormat(CF_COMPONENT) then Result := cfComponent else for I := 0 to Clipboard.FormatCount - 1 do if Clipboard.HasFormat(Clipboard.Formats[I]) then begin Result := cfOther; Break; end; end;{伪过程,事实是剪贴板格式是只读的} procedure TClipMon.SetFormat(Value: TClipFormat); begin end;{处理来自剪贴板观察器链的消息} procedure TClipMon.NewWndMethod (var msg: TMessage); begin case msg.msg of WM_DRAWCLIPBOARD: begin Loaded; msg.Result := SendMessage(WM_DRAWCLIPBOARD, FNextViewerHandle, 0, 0); end; WM_CHANGECBCHAIN: if THandle(msg.wParam) = FNextViewerHandle then begin FNextViewerHandle := msg.lParam; msg.Result := 0; end else msg.Result := SendMessage(FNextViewerHandle, WM_CHANGECBCHAIN, msg.wParam, msg.lParam); else msg.result := CallWindowProc(OldWndProc, FHandle, msg.msg, msg.WParam, msg.LParam); end; end;{部件装载完毕} procedure TClipMon.Loaded; begin if FActive and Assigned(FOnChange) then FOnChange(Self); end;end.
To: bb_star_bb(爱编程的菜鸟) 好像不可以!我所需要的是针对所有按键!并不是针对本程序的! 我知道是用键盘钩子来实现但我不知道如何来实现! 谢谢! 只有我自己来顶了!
procedure TForm1.Button1Click(Sender: TObject);var CutLengthOfLine{ 被处理字符串的总长度 }, i, j: integer; sLine{ 被处理的源字符串 }: string; sCuted{ 按固定长度分割出来的部分字符串 }: string; iCutLength{ 按固定长度分割出来的部分字符串的长度 }: integer; bIsDBCS{ 是否是汉字的前半字节 }: boolean;beginif edit1.text='' then beginexit;end; CutLengthOfLine:=strtoint(edit1.text); if CutLengthOfLine < 2 then begin showmessage('CutLengthOfLine 必须大于等于 2 !'); Exit; end; Memo2.Lines.Clear; for i := 0 to Memo1.Lines.Count - 1 do begin sLine := Memo1.Lines[i]; if Length(sLine) = 0 then Memo2.Lines.Add(#13+#10) else repeat //开始处理字符串 iCutLength := CutLengthOfLine; sCuted := Copy(sLine, 1, iCutLength);//从头取出 iCutLength 长的字符串 bIsDBCS := False;//先假设没有半个字符串 for j := 1 to iCutLength do //从头到尾逐个检查,至于为什么?//原作者是这样解释的//1. 为什麽不直接抓最後一个字元判断? 因为中文字的 Trail-byte, 其内码也可能落在 Lead-byte// 的内码区间内.//2. 为什麽不直接抓最後两个字元来判断? 因为前一个字的 Trail-byte 加上後一个字的 Lead-byte,// 可能又是一个中文字. begin if bIsDBCS then //如果上一个字节是汉字的前半部分 bIsDBCS := False //则此时本字节是汉字的后半部分, //所以将是否前半个汉字检测标志设为假 else if Windows.IsDBCSLeadByte(byte(sCuted[j])) then bIsDBCS := True;//否则检查本字节,并根据结果设置标志 end; //end of for//如果最后一个字节的上一个字节是汉字的前半部分,则结束时//检测标志为假, if bIsDBCS then Dec(iCutLength);//如果最后一个字节是汉字的前半部分, 则少截取一个字符,避免乱码 Memo2.Lines.Add(Copy(sLine, 1, iCutLength)); sLine := Copy(sLine, iCutLength + 1, Length(sLine) - iCutLength);//拷贝出下一部分固定长度的字符串,循环处理 until Length(sLine) <= 0; end;memo2.setfocus;memo2.selstart:=0;memo2.SelLength:=0;end;
在Delphi中有一些全局对象,永远不要去构造它们的实例。其中有两个对象是以全局
变量的方式提供的,这两个变量一个是Application(TApplication类型,包含Forms单元即
可调用),另一个是Screen(TScreen类型,包含Forms单元即可调用)。而另外两个对象是以
函数方式提供的,这两个对象一个是Printer(TPrinter类型,包含Printers单元就可调),
另一个就是Clipboard(TClipboard类型,包含Clipbrd单元就可调用)。用函数而不是全局变
量会令实际的变量存贮在单元的实现部分而不是接口部分,这样就永远不能对它赋值。
现在介绍Clipboard的编程。
Clipboard是由系统自动实例化的一个对象,通过该对象可以操作剪贴板,可以存取和
清除剪贴板的内容。不过一般不显式地操作剪贴板,而是通过操作其它的控件或由系统自动
更新剪贴板内容。如基于TCustomEdit的控件(如TEdit, TMemo,TRichEdit等)就有直接操作
剪贴板的方法:CopyToClipboard,CutToClipboard和PasterFromClipboard。事实上在
TCustomEdit运行时,Ctrl+C, Ctrl+X, Ctrl+V自动定义成了操作剪贴板的热键,不用
编写任何代码。剪贴板的内容可以通过查询HasFormat获得其格式。Windows系统支持三
种基本格式:CF_TEXT, CF_BITMAP和CF_METAFILEPICT,分别表示文本、位图和元文件图
象,其它的格式难以预知,因为任何新的格式都需要向Windows注册新类型。Delphi就注
册了两种类型:CF_PICTURE(TPicture类型,包括TIcon, TBitmap和TMetafile)和
CF_COMPONENT(TComponent类型)。全部的格式可以通过Windows API的枚举函数
CountClipboardFormats和EnumClipboardFormats测知,甚至还可以用GetClipboardFormatName
查出每种格式的名称。
Clipboard的基类是TPersistent,说明Clipboard不能处理任何Windows消息。剪贴板
是由Windows运行中的所有任务共同操作的,当有任何一个任务修改剪贴板内容时,不能
自动通知需要监测剪贴板状态的窗口。如果工具栏中有一个粘贴的按钮,不能动态地修改
这个按钮的活动状态。有两种方法可以解决这个问题:一个是重载主窗体的Windows消息过
程,并在OnCreate和OnDestroy添加和注销剪贴板观察窗体链。另一个是设计一个剪贴板监
控器部件,需要时添加到主窗体中即可。显然第二种方法较好。unit ClipMonitor;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, clipbrd;type
TClipFormat = (cfNone, cfText, cfBitmap, cfMetaFilePict,
cfPicture, cfComponent, cfOther); TClipMonitor = class(TComponent)
private
FHandle, FNextViewerHandle: THandle;
FActive: Boolean;
FOnChange:TNotifyEvent;
OldWndProc, NewWndProc: Pointer;
procedure SetActive(Value: Boolean);
function GetFormat: TClipFormat;
procedure SetFormat(Value: TClipFormat);
protected
procedure NewWndMethod(var msg: TMessage);
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Active: Boolean read FActive write SetActive default False;
property Format: TClipFormat read GetFormat write SetFormat stored False;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
end;procedure Register;implementationprocedure Register;
begin
RegisterComponents('System', [TClipMon]);
end;constructor TClipMon.Create(AOwner: TComponent);
begin
if not (AOwner is TForm) then
raise Exception.CreateFmt('''%s'' is not a Form', [AOwner.Name])
else if AOwner = nil then
raise Exception.Create('No Windowized Owner');
inherited Create(AOwner);
FHandle := (Owner as TForm).Handle;
FNextViewerHandle := 0;
FActive := False;
FNextViewerHandle := SetClipboardViewer(FHandle);
if not (csDesigning in ComponentState) then begin
NewWndProc := MakeObjectInstance(NewWndMethod);
OldWndProc := Pointer(SetWindowLong(FHandle, GWL_WNDPROC,
LongInt(NewWndProc)));
end else begin
NewWndProc := nil;
OldWndProc := nil;
end;
end;destructor TClipMon.Destroy;
begin
ChangeClipboardChain(FHandle, FNextViewerHandle);
if Assigned(NewWndProc) then begin
SetWindowLong(FHandle, GWL_WNDPROC, Longint(OldWndProc));
FreeObjectInstance(NewWndProc);
end;
inherited Destroy;
end;{设置是否允许自动剪贴板监控}
procedure TClipMon.SetActive(Value: Boolean);
begin
if FActive <> Value then FActive := Value;
end;{取剪贴板格式}
function TClipMon.GetFormat: TClipFormat;
var
I: Integer;
begin
Result := cfNone;
if Clipboard.HasFormat(CF_TEXT) then Result := cfText
else if Clipboard.HasFormat(CF_BITMAP) then Result := cfBitmap
else if Clipboard.HasFormat(CF_METAFILEPICT) then Result := cfMetaFilePict
else if Clipboard.HasFormat(CF_PICTURE) then Result := cfPicture
else if Clipboard.HasFormat(CF_COMPONENT) then Result := cfComponent
else for I := 0 to Clipboard.FormatCount - 1 do
if Clipboard.HasFormat(Clipboard.Formats[I]) then begin
Result := cfOther;
Break;
end;
end;{伪过程,事实是剪贴板格式是只读的}
procedure TClipMon.SetFormat(Value: TClipFormat);
begin
end;{处理来自剪贴板观察器链的消息}
procedure TClipMon.NewWndMethod (var msg: TMessage);
begin
case msg.msg of
WM_DRAWCLIPBOARD:
begin
Loaded;
msg.Result := SendMessage(WM_DRAWCLIPBOARD,
FNextViewerHandle, 0, 0);
end;
WM_CHANGECBCHAIN:
if THandle(msg.wParam) = FNextViewerHandle then begin
FNextViewerHandle := msg.lParam;
msg.Result := 0;
end else
msg.Result := SendMessage(FNextViewerHandle, WM_CHANGECBCHAIN,
msg.wParam, msg.lParam);
else
msg.result := CallWindowProc(OldWndProc, FHandle, msg.msg,
msg.WParam, msg.LParam);
end;
end;{部件装载完毕}
procedure TClipMon.Loaded;
begin
if FActive and Assigned(FOnChange) then FOnChange(Self);
end;end.
好像不可以!我所需要的是针对所有按键!并不是针对本程序的!
我知道是用键盘钩子来实现但我不知道如何来实现!
谢谢!
只有我自己来顶了!