7

是否有一种简单/聪明的方法可以将标准 Windows TEdit 菜单加载到这个 TRichEdit 中?

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

编辑:我找到了一个可能的线索(试图弄清楚,因为我不是 MFC 专家)......

4

1 回答 1

11

基于“可能的线索”和一点 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;

任何反馈都会很好:)

于 2012-04-19T10:53:02.003 回答