游民家园

leafyoung v.s. dotnet

导航

[TRichView] 自动插入上一段落前置空白字符

思路:在KeyPress时间中发现有回车(#13)按键,那么获取上一个段落的前置空白文本,插入到当前光标位置即可。

这里需要特别注意,在Delphi 2007中默认Unicode是False,对中文支持不好,开启Unicode之后才可以支持中文。

代码:

procedure TMainForm.rveMainKeyPress(Sender: TObject; var Key: Char);

  function GetPrevParaStartItemNoBeforeCaret(var VLastItemNo: Integer): Integer;
  var
    nStartItemNo, nStartItemOffs: Integer;
    nEndItemNo, nEndItemOffs: Integer;
  begin
    rveMain.GetSelectionBounds(nStartItemNo, nStartItemOffs, nEndItemNo, nEndItemOffs, True);

    VLastItemNo := nStartItemNo - 1;
    if VLastItemNo < 0 then VLastItemNo := 0;

    for Result := VLastItemNo downto 0 do
    begin
      if rveMain.IsParaStart(Result) then Break;
    end;
  end;

  // 返回值为true,说明整行文本都是空白字符构成,空白字符指空格或者Tab
  function AppendLeadingWhitespace(var sPadding: string; var AItem: TCustomRVItemInfo): Boolean;
  var
    I, nItemTextLen: Integer;
    oFontInfo: TFontInfo;
  begin
    if AItem is TRVTabItemInfo then // Tab键不是文本的一部分,这里特殊处理
    begin
      sPadding := sPadding + #9;
      Result := True;
      Exit;
    end
    else if AItem is TRVNonTextItemInfo then
    begin
      Result := False;
      Exit;
    end;

    // 文本Item(TRVTextItemInfo)
    Result := True;
    nItemTextLen := Length(AItem.ItemText);
    if nItemTextLen = 0 then Exit;

    oFontInfo := rveMain.Style.TextStyles[AItem.StyleNo];
    if oFontInfo.Unicode then
    begin
      I := 1;
      while (I + 1) <= nItemTextLen do
      begin
        if (AItem.ItemText[I] <> #32) { and (AItem.ItemText[I] <> #9) } then
        begin
          Result := False;
          Break;
        end;

        sPadding := sPadding + AItem.ItemText[I];
        I := I + 2;
      end
    end
    else begin
      for I := 1 to nItemTextLen do
      begin
        if (AItem.ItemText[I] <> #32) { and (AItem.ItemText[I] <> #9) } then
        begin
          Result := False;
          Break;
        end;

        sPadding := sPadding + AItem.ItemText[I];
      end;
    end;
  end;

var
  nItemNo, nParaStartItemNo, nLastItemNo: Integer;
  oItem: TCustomRVItemInfo;
  sPadding: string;
begin
  if Key = #13 then
  begin
    sPadding := '';

    nLastItemNo := 0;
    nParaStartItemNo := GetPrevParaStartItemNoBeforeCaret(nLastItemNo);
    for nItemNo := nParaStartItemNo to nLastItemNo do
    begin
      oItem := rveMain.GetItem(nItemNo);
      if not AppendLeadingWhitespace(sPadding, oItem) then Break;
    end;

    if Length(sPadding) > 0 then
      rveMain.InsertText(sPadding);
  end;
end;

 

posted on 2014-10-13 16:36  游民一族  阅读(359)  评论(0)    收藏  举报