首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >TMemo中的Word块

TMemo中的Word块
EN

Stack Overflow用户
提问于 2012-03-08 23:10:55
回答 2查看 1.2K关注 0票数 4

我试图使一个基本的十六进制查看器的TMemo,我知道这可能不是理想的,但它将只有我个人使用它,所以这并不重要。

(1)

首先,假设备忘录中满是十六进制信息,如下所示:

如何计算所有显示的文本块,忽略空白?所以用这个图像,这个例子的结果是28。

这是我尝试过的,我知道这是完全错误的,因为我正在访问备忘线,但我不知道如何访问每个字符。

我似乎解决不了这个简单的问题

代码语言:javascript
运行
复制
function CountWordBlocks(Memo: TMemo): Integer;
var
  i: Integer;
  vCount: Integer;
begin
  for i := 0 to Memo.Lines.Count - 1 do
  begin
    if Length(Memo.Lines.Strings[i]) = 2 then
    begin
      Inc(vCount);
    end;
  end;

  Result := vCount;
end;

下面是我用来在备忘录中显示十六进制值的代码:

代码语言:javascript
运行
复制
procedure ReadFileAsHex(const AFileName: string; ADestination: TStrings);
var
  fs: TFileStream;
  buff: Byte;
  linecount: Byte;
  line: string;
begin
  linecount := 0;
  line := '';
  fs := TFileStream.Create(AFileName, fmOpenRead);

  try
    ADestination.BeginUpdate;
    try
      while fs.Position < fs.Size do
      begin
        fs.Read(buff, 1);
        line := line + IntToHex(buff, 2) + ' ';
        Inc(linecount);
        if linecount = 16 then
        begin
          ADestination.Add(line);
          line := '';
          linecount := 0;
        end;
      end;
      if Length(line) <> 0 then
        ADestination.Add(line);
    finally
      ADestination.EndUpdate;
    end;
  finally
    fs.Free;
  end;
end;

(2)

如果我点击备忘录,并且光标下有一个文本块,我怎么知道所选的块在所有其他块中是哪个数字?

因此,使用相同的第一个图像,插入符号位于68旁边的上线,因此结果将是3,因为它是28中的第三个文本块。

这应该是那么容易,但我不能清楚地想清楚,我还没有正确的编程思维,所以真正与基本逻辑和解决问题的斗争!

(3)

最后,我希望在运行时通过传递一个块号值来选择一个块。我尝试过,但没有成功:

代码语言:javascript
运行
复制
procedure FindBlock(Memo: TMemo; BlockNumber: Integer);
var
  i: Integer;
  txt: string;
  ThisWhite, PrevWhite: boolean;
  vRead: Integer;
begin
  txt := Memo.Text;
  vRead:= 0;
  PrevWhite := True;
  for i := 1 to Length(txt) do
  begin
    ThisWhite := Character.IsWhiteSpace(txt[i]);
    if PrevWhite and not ThisWhite then
    begin
      Inc(vRead);
      PrevWhite := False;
    end;
    PrevWhite := ThisWhite;

    if vRead = BlockNumber then
    begin
      Memo.SelStart := vRead;
      Memo.SetFocus;
      Exit;
    end;
  end;
end;
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-08 23:33:45

(1)

这样做是可行的:

代码语言:javascript
运行
复制
function TForm1.CountBlocks: integer;
var
  i: Integer;
  txt: string;
  ThisWhite, PrevWhite: boolean;
begin
  txt := Memo1.Text;
  result:= 0;
  PrevWhite := true;
  for i := 1 to Length(txt) do
  begin
    ThisWhite := Character.IsWhiteSpace(txt[i]);
    if PrevWhite and not ThisWhite then
    begin
      inc(result);
      PrevWhite := false;
    end;
    PrevWhite := ThisWhite;
  end;
end;

但是,如果可以获得有关备忘录内容的更详细信息,则可以对其进行优化。例如,如果您知道每一行由四个块组成,那么块的数量就是4*Memo1.Lines.Count。我上面的代码甚至会接受不同宽度的块。

(2)

简单地替换

代码语言:javascript
运行
复制
for i := 1 to Length(txt) do

通过

代码语言:javascript
运行
复制
for i := 1 to Memo1.SelStart + 1 do
票数 6
EN

Stack Overflow用户

发布于 2012-03-09 00:54:28

由于您控制着行的格式,而且行的格式是固定的,所以很容易计算所显示的字节数,而无需一次遍历单个行。每行每字节显示3个字符,最后一行以外的每一行显示16个字节,因此每一行完整的16字节行显示48个字符。利用这些事实,根据当前完整的16字节行数计算字节数,然后只从最后一行中添加剩余字节数:

代码语言:javascript
运行
复制
function CountWordBlocks(Memo: TMemo): Integer; 
var 
  Count: Integer; 
begin 
  Count := Memo.Lines.Count;
  if Count > 0 then
    Result := (16 * (Count-1)) + (Length(Memo.Lines[Count-1]) div 3);
  else
    Result := 0;
end;

您可以执行类似的操作,将备忘录中的字符偏移量转换为工作块号:

代码语言:javascript
运行
复制
function GetCurrentWordBlock(Memo: TMemo): Integer;
var
  SelStart, LineStart, LineNum: Integer
begin
  Result := 0;
  SelStart := Memo.SelStart;
  if SelStart < 0 then Exit;
  LineStart := Memo.Perform(EM_LINEINDEX, SelStart, 0);
  if LineStart < 0 then Exit;
  LineNum := Memo.Perform(EM_LINEFROMCHAR, LineStart, 0);
  Result := (16 * LineNum) + ((SelStart - LineStart) div 3) + 1;
end;

要选择给定的块号,可以这样做:

代码语言:javascript
运行
复制
procedure FindBlock(Memo: TMemo; BlockNumber: Integer); 
var
  LineNum, LineStart: Integer;
begin 
  if BlockNumber < 1 then Exit;
  LineNum = (BlockNumber - 1) div 16;
  LineStart = Memo.Perform(EM_LINEINDEX, LineNum, 0);
  if LineStart < 0 then Exit;
  Memo.SelStart = LineStart + (((BlockNumber - 1) - (16 * LineNum)) * 3);
  Memo.SelLength := 2;
  Memo.SetFocus; 
end; 
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9626517

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档