Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi TMemo中的字块_Delphi_Delphi Xe - Fatal编程技术网

Delphi TMemo中的字块

Delphi TMemo中的字块,delphi,delphi-xe,Delphi,Delphi Xe,我正在尝试用TMemo制作一个基本的十六进制查看器,我知道这可能并不理想,但只有我个人使用它,所以这并不重要 (1) 首先,假设备忘录中填充了十六进制信息,如下所示: 我怎样才能得到显示的所有文本块的计数,而忽略空白?因此,使用图像,在这种情况下,结果将是28 这是我尝试的,我知道这是完全错误的,因为我正在访问备忘录行,但我不知道如何访问每个字符 我似乎无法解决这个简单的问题:( 下面是我用来在备忘录中显示十六进制值的代码: procedure ReadFileAsHex(const AFil

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

(1)

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

我怎样才能得到显示的所有文本块的计数,而忽略空白?因此,使用图像,在这种情况下,结果将是28

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

我似乎无法解决这个简单的问题:(

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

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;
(1)

这项工作:

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)

简单地替换

for i := 1 to Length(txt) do


由于您可以控制行的格式,并且行具有固定的格式,因此计算显示的字节数非常容易,而无需每次循环一行。每行每字节显示3个字符,除最后一行外的每行显示16个字节,因此48个字符每个完整16字节行的字节数。利用这些事实,根据存在的完整16字节行数计算字节数,然后您可以添加最后一行的剩余字节数:

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;
您可以执行类似的操作,将备忘录中的字符偏移量转换为工作块编号:

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;
函数GetCurrentWordBlock(Memo:TMemo):整数; 变量 SelStart、LineStart、LineNum:整数 开始 结果:=0; SelStart:=Memo.SelStart; 如果SelStart<0,则退出; LineStart:=Memo.Perform(EM_LINEINDEX,SelStart,0); 如果LineStart<0,则退出; LineNum:=Memo.Perform(EM_LINEFROMCHAR,LineStart,0); 结果:=(16*LineNum)+((SelStart-LineStart)div 3)+1; 结束; 要选择给定的块编号,可以执行以下操作:

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; 
过程FindBlock(备注:TMemo;块号:整数);
变量
LineNum,LineStart:整数;
开始
如果BlockNumber<1,则退出;
LineNum=(BlockNumber-1)div 16;
LineStart=Memo.Perform(EM_LINEINDEX,LineNum,0);
如果LineStart<0,则退出;
Memo.SelStart=LineStart+((区块编号-1)-(16*LineNum))*3);
Memo.SelLength:=2;
Memo.SetFocus;
结束;

什么是Character.IsWhiteSpace?我得到了未声明的标识符错误。我不知道每行上的块数,它是通过TMemo的宽度。我将编辑问题以包括获取十六进制的代码。@Blobby:将
Character
添加到
uses
子句中。它们都非常有效。谢谢安德烈亚斯。如果我理解的话正确地说,你的代码实际上是在寻找空格以获得结果,而不是专注于实际的文本数据。是的,你几乎可以使用代码来计算小说中的字数。安德烈亚斯,我如何通过代码在备忘录中查找和选择块?我编辑了我的原始问题以显示我尝试了什么,但我似乎无法让它工作ng正确。谢谢你的输入,雷米。用你的答案计算积木似乎更容易。这两种方法都很好。我不明白。你的意思肯定是
4*(Count-1)
?无论如何,OP说(在对我答案的评论中)更新OK,我现在看到OP的Q已经更新了…Blobby的截图只显示了每行显示的
4
块,但是他的
ReadFileAsHex()中的代码
函数增加到每行
16
个块。我所有的代码片段都基于此。如果实际上,每行的块数基于
TMemo
宽度,那么只需将
16
替换为实际适合一行的块数,可以通过除以第一行是
3
。很抱歉没有解释得更清楚,截图只显示了4个块以使图像更小。雷米,你确定的是每行有16个块是正确的。我的备忘录宽度不大于这一点,所以我甚至没有注意到,单词包装的方式我假设每行没有预定义的块。比他对安德烈亚斯和雷米的道歉没有说得更清楚。
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;
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;
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;