|
p> 在Delphi 3的时代,我们是没法让TMemo突破传统的64K界限的。现在可就轻松多了。出于方便、快捷和安全性的考虑(在文本模式下是不会有富裕(Rich)控制标识), TMemo制作的文本转换、文本阅读器是比较不错的好帮手,至少在编程上来得较为省时。唯一美中不足的是在这种状态下,难以确定行号和列号,而这些在阅读、打字时是比较常用的。 如果读者的编译器为10.0版以下,可以这样解决: 对TMemo的句柄发送EM_LINEFROMCHAR来获得当前字符的行数,进行一下Interger $#@60;-$#@62; String的变换就是行号了,而获得当前光标所在的列数就稍微复杂一点: 先对TMemo的句柄发送EM_GETSEL来获得当前光标对于所在字符的选择数(该返回值是一个DWORD,低位WORD为选择起始值,高位WORD为选择数),这个数包含了从TMemo文本缓冲开始以来的字符,因此,必须减去当前行以前的所有字符的另外一个数,这另外一个数可以对TMemo的句柄发送EM_LINEINDEX来获得。 也就是: 行数= SendMessage(Handle, EM_LINEFROMCHAR, -1, 0); 列数= LongRec(SendMessage(Handle, EM_GETSEL, 0, 0)).Hi - SendMessage(Handle, EM_LINEINDEX, -1, 0); 如果你正在使用Delphi 5,那么这一切都在TMemo.CaretPos的TPoint这个属性里,其X正是列值,而Y为行值。 为了正常显示行列号,建议读者使用消息来处理。这是为了正确处理用户在打字时按下诸如: Home、End之类的键。 一个范例: unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, StdCtrls; const WM_USERGETPOS = WM_USER + 100; //定义绘出行列号的消息 type TForm1 = class(TForm) Memo1: TMemo; StatusBar1: TStatusBar; procedure FormCreate(Sender: TObject); procedure Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure Memo1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); private { Private declarations } protected { protected declarati } procedure DrawMyPos(var Msg: TMessage);message WM_USERGETPOS; //消息事件 public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} procedure TForm1.DrawMyPos(var Msg: TMessage);var L1,L2: Integer;begin L1 := Memo1.CaretPos.y; L2 := Memo1.CaretPos.x; StatusBar1.SimpleText := IntToStr(L1)+:+IntToStr(L2); //格式为行:列显示end; procedure TForm1.FormCreate(Sender: TObject);begin Memo1.Clear; PostMessage(Handle,WM_USERGETPOS,0,0); //显示初始化end; procedure TForm1.Memo1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);begin PostMessage(Handle,WM_USERGETPOS,0,0); //响应用户的按键end; procedure TForm1.Memo1MouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);begin PostMessage(Handle,WM_USERGETPOS,0,0); //响应鼠标的定位end; end.
|