본문 바로가기

프로그래밍/Delphi

TRichEdit에서 기본 컨텍스트팝업메뉴(Context Popup Menu) 활성화 시키기

1. 개요

  TMemo 컴포넌트에서는 마우스 오른쪽 버튼 클릭시 기본  컨텍스트 팝업 메뉴(실행취소/복사/붙여넣기 등등)가 기본 활성화 되는데 TRichEdit에서는 어떤 이유에서인지 기본 활성화가 되어 있지 않다. 기본 컨텍스트 메뉴를 선택적으로 활성화 시키는 방법을 알아 보자.


2. TRichEdit에 Context Menu 활성화를 위한 세팅


procedure RichEditPopupMenu(re: TRichEdit);
const
  IDM_UNDO   = WM_UNDO;
  IDM_CUT    = WM_CUT;
  IDM_COPY   = WM_COPY;
  IDM_PASTE  = WM_PASTE;
  IDM_DELETE = WM_CLEAR;
  IDM_SELALL = EM_SETSEL;
  IDM_RTL    = $8000; // WM_APP ?

  Enables: array[Boolean] of DWORD = (MF_DISABLED or MF_GRAYED, MF_ENABLED);
  Checks: array[Boolean] of DWORD = (MF_UNCHECKED, MF_CHECKED);
var
  hUser32: HMODULE;
  hmnu, hmenuTrackPopup: HMENU;
  Cmd: DWORD;
  Flags: Cardinal;
  HasSelText: Boolean;
  FormHandle: HWND;
  // IsRTL: Boolean;
begin
  hUser32 := LoadLibraryEx(user32, 0, LOAD_LIBRARY_AS_DATAFILE);
  if (hUser32 <> 0) then
  try
    hmnu := LoadMenu(hUser32, MAKEINTRESOURCE(1));
    if (hmnu <> 0) then
    try
      hmenuTrackPopup := GetSubMenu(hmnu, 0);

      HasSelText := Length(re.SelText) <> 0;
      EnableMenuItem(hmnu, IDM_UNDO,   Enables[re.CanUndo]);
      EnableMenuItem(hmnu, IDM_CUT,    Enables[HasSelText]);
      EnableMenuItem(hmnu, IDM_COPY,   Enables[HasSelText]);
      EnableMenuItem(hmnu, IDM_PASTE,  Enables[Clipboard.HasFormat(CF_TEXT)]);
      EnableMenuItem(hmnu, IDM_DELETE, Enables[HasSelText]);
      EnableMenuItem(hmnu, IDM_SELALL, Enables[Length(re.Text) <> 0]);

      // IsRTL := GetWindowLong(re.Handle, GWL_EXSTYLE) and WS_EX_RTLREADING <> 0;
      // EnableMenuItem(hmnu, IDM_RTL, Enables[True]);
      // CheckMenuItem(hmnu, IDM_RTL, Checks[IsRTL]);

      FormHandle := GetParentForm(re).Handle;
      Flags := TPM_LEFTALIGN or TPM_RIGHTBUTTON or TPM_NONOTIFY or TPM_RETURNCMD;
      Cmd := DWORD(TrackPopupMenu(hmenuTrackPopup, Flags,
        Mouse.CursorPos.X, Mouse.CursorPos.Y, 0, FormHandle, nil));
      if Cmd <> 0 then
      begin
        case Cmd of
          IDM_UNDO:   re.Undo;
          IDM_CUT:    re.CutToClipboard;
          IDM_COPY:   re.CopyToClipboard;
          IDM_PASTE:  re.PasteFromClipboard;
          IDM_DELETE: re.ClearSelection;
          IDM_SELALL: re.SelectAll;
          IDM_RTL:; // ?
        end;
      end;
    finally
      DestroyMenu(hmnu);
    end;
  finally
    FreeLibrary(hUser32);
  end;
end;

3. TRichEdit의 OnContextPopup Event Handler 작성


procedure TForm1.RichEditEx1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
begin
  RichEditPopupMenu(TRichEdit(Sender));
  Handled := True;
end;

위와 같이 하면 TRichEdit에 기본 컨텍스트 팝업(Context Popup) 메뉴를 활성화 시킬 수 있다.