使用TRichEdit的TEdit上下文菜单

时间:2012-04-18 17:34:13

标签: delphi delphi-7

是否有一种简单/巧妙的方法可将标准Windows TEdit菜单加载到此TRichEdit中?

我知道我可以创建一个简单的菜单来模拟TEdit菜单,用于复制/粘贴等简单操作(Example),但我还想保留更高级的菜单选项,例如unicode选项,阅读顺序,以及使用相同的本地化字符串。

编辑:我找到了possible lead(因为我不是MFC专家,试图弄明白)...

1 个答案:

答案 0 :(得分:9)

基于“可能的领先”和一点MSDN,我提出了一个可能的解决方案。 我仍然无法解决阅读顺序问题(以及unicode选项)。似乎它对于RichEdit的工作方式与对Edit的工作方式不同,只是设置或获取WS_EX_RTLREADING标志不起作用。无论如何,这是代码:

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;

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

任何反馈都会很好:)