Sobre la base de la "posible pista" y un poco de MSDN, se me ocurrió una posible solución. Todavía no puedo resolver el problema de orden de lectura (y las opciones de Unicode). Parece que funciona de forma diferente para RichEdit que para Edit, y simplemente establecer u obtener el indicador WS_EX_RTLREADING no funciona como se esperaba. De todas formas, aquí está el código:
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;
Cualquier comentario sería bueno :)
sé que han hecho que la investigación sobre este antes, y yo creo que fue en relación con una pregunta SO. –
@Andreas, y una conclusión: -? Supongo que esos menús provienen de clases base de Windows. – TLama
TLama, sí, no creo que haya ninguna forma 'documentada' de hacerse con este menú. –