Delphi, TMemo, TRichEdit 관련 팁

2021. 3. 17. 13:24카테고리 없음

[TMemo Component] 현재 라인번호 알아내기

메모에서 현재 Caret이 위치하고 있는 줄이 몇 번째 줄인지를 리턴한다.

Label1.Caption := IntToStr(GetCurrLine(Memo1));

function GetCurrLine(Memo : TMemo) : integer;
begin
  Result := Memo.Perform(EM_LINEFROMCHAR, Memo.SelStart, 0);
end;

 

[TMemo Component] 현재 컬럼번호 알아내기

메모에서 현재 Caret이 위치하고 있는 줄에서 몇 번째 컬럼인지를 리턴한다.

Label1.Caption := IntToStr(GetCurrCul(Memo1));

function GetCurrCul(Memo : TMemo)) : integer;
begin
  Result := Memo.SelStart - Memo.Perform(EM_LINEINDEX, GetCurrLine(Memo), 0);
end;

[TMemo Component] Caret를 원하는 라인으로 이동하기

Caret을 원하는 위치로 이동시키는데 이때 넘겨주는 값이 라인의 한계를 벗어나면 그 안 범위로 위치시킨다.

만약 라인의 맨끝으로 이동시키고 싶다면 아주 큰값을 주면된다.

SetCurrLine(Memo1. 10);

procedure SetCurrLine(Memo : TMemo; Value : integer);
begin
  if Value < 0 then Value := 0;
  if Value > Memo.Lines.Count then Value := Memo.Lines.Count;
  Memo.SelLength := 0;
  Memo.SelStart := Memo.Perform(EM_LINEINDEX, Value, 0);
end;

 

[TMemo Component] Caret을 원하는 컬럼으로 이동하기

SetCurrCul(Memo1. 10);

procedure SetCurrCul(Memo : TMemo; Value : integer);
var
  CurrLine : integer;
begin
  CurrLine := GetCurrLine(Memo);
  if Value < 0 then Value := 0;
  if (Value > Length(Memo.Lines[CurrLine])) then
  Value := Length(Memo.Lines[CurrLine]);
  Memo.SelLength := 0;
  Memo.SelStart := Memo.Perform(EM_LINEINDEX, CurrLine, 0) + Value;
end;

[TMemo Component] Text가 쓰여지는 영역 알아내기

현재 Text가 쓰여지는 영역을 TRect형으로 리턴한다.

즉 글자의 높이가 10이고 메모의 높이가 25라면 2라인만이 그려지게 된다.

따라서 글자가 그려지는 정확한 영역을 알아내기 위해서는 아래 함수를 사용한다.

Rect := GetTextRect(Memo1);

function GetTextRect(Memo : TMemo) : TRect;
var
  lParam : TRect;
begin
  Memo.Perform(EM_GETRECT, 0, Integer(@lParam));
  Result := lParam;
end;

[TMemo Component] 메모에서 현재 보이는 라인수 알아내기

Label1.Caption := IntToStr(GetVisibleLine(Memo1));

function GetVisibleLine(Memo : TMemo) : integer;
var
  Metric : TTextMetric;
  DC : hDC;
begin
  DC := GetWindowDC(Memo.Handle);
  GetTextMetrics(DC, Metric);
  Result := (GetTextRect(Memo).Bottom div Metric.tmHeight);
end;

[TMemo Component] 원하는 라인만큼 스크롤하기

현재상태에서 원하는 x, y만큼 스크롤한다.

DoScroll(Memo1, 10, 10);

procedure DoScroll(Memo : TMemo; x : integer; y : integer);
begin
  Memo.Perform(EM_LINESCROLL, x, y);
end;

[TRichEdit Component] 블록설정부분 폰트 변경하기

리치에디트컴포넌트는 메모컴포넌트와는 달리 설정부분만 폰트를 변경한다던가, 정렬상태를 바꾸는게 가능하다.

procedure TForm1.FontBtnClick(Sender : TObject);
begin
  if RichEdit1.SelLength > 0 then
  begin
    FontDialog1.Font.Assign(RichEdit1.DefAttributes);
    if FontDialog1.Execute then
      RichEdit1.SelAttributes.Assign(FontDialog1.Font);
  end
  else
    ShowMessage('No Text Selected');
end;

[TRichEdit Component] 블록설정부분 속성 변경하기

아래의 소스는 굵게(Bold) 속성을 지정한다.

이탤릭(fsItalic), 밑줄(fsUnderLine) 등의 속성도 마찬가지로 바꿀 수 있다.

procedure TForm1.BoldBtn(Sender : TObject);
begin
  if BoldBtn.Down then
    RichEdit1.SelAttributes.Style := RichEdit1.SelAttributes.Style + [fsBold]
  else
    RichEdit1.SelAttributes.Style := RichEdit1.SelAttributes.Style - [fsBold];
end;

[TRichEdit Component] 블록설정부분 복사, 삭제, 잘라우기, 붙이기 설정방법

interface부의 uses절에 Clipbrd를 추가한다.

procedure TForm1.CopyBtnClick(Sender : TObject);
begin
  RichEdit1.CopyToClipboard; {복사}
  RichEdit1.CutToClipboard; {잘라두기}

  RichEdit1.ClearSelection; {지우기 - 클립보드에 저장되지 않는다}
  if Clipboard.HasFormat(CF_TEXT) then begin
    PasteBtn.Enabled := True; {복사가 되었으면 붙이기 버튼을 활성화}
  end;
end;

procedure TForm1.PasteBtnClick(Sender : TObject);
begin
  RichEdit1.PasteFromClipboard;
end;

[TRichEdit Component] Insert 키 상태 알아내기

이 소스는 RichEdit 컴포넌트에서만 사용할 수 있다.(메모컴포넌트는 삽입, 수정의 개념이 없음)

procedure TForm1.RichEdit1Key(Sender: TObject; var Key: Word; Shift: TShiftState);
var
  ret : integer;
begin
  ret := GetKeyState(45);
  if ret=1 then
    Label1.Caption := 'Overwrite'
  else
    Label1.Caption := 'Insert';
end;

 

[Find Dialog Component] 리치에디트에서 문자열찾기

먼저 폼에 Memo, FindDialog컴포넌트를 배치합니다. 델파이 도움말에서 참조했습니다.

procedure TForm1.FindBtnClick(Sender : TObject);
begin
  FindDialog1.Execute;
  { or ReplaceDialog1.Execute;}
end;

procedure TForm1.FindDialog1Find(Sender: TObject);
var
  SelPos: Integer;
begin
  with TFindDialog(Sender) do
  begin
    { Perform a global case-sensitive search for FindText in Memo1 }
    SelPos := Pos(FindText, Memo1.Lines.Text);
    if SelPos > 0 then
    begin
      Memo1.SelStart := SelPos - 1;
      Memo1.SelLength := Length(FindText);
    end
    else MessageDlg(Concat('Could not find "', FindText, '" in Memo1.'), mtError,[mbOk], 0);
  end;
end;

procedure TForm1.ReplaceDialog1Replace(Sender: TObject);
var
  SelPos: Integer;
begin
  with TReplaceDialog(Sender) do
  begin
    { Perform a global case-sensitive search for FindText in Memo1 }
    SelPos := Pos(FindText, Memo1.Lines.Text);
    if SelPos > 0 then
    begin
      Memo1.SelStart := SelPos - 1;
      Memo1.SelLength := Length(FindText);
      { Replace selected text with ReplaceText }
      Memo1.SelText := ReplaceText;
    end
    else MessageDlg(Concat('Could not find "', FindText, '" in Memo1.'), mtError,[mbOk], 0);
  end;
end;