2012-04-18 10 views
5

¿Existe alguna manera simple/inteligente de cargar el menú estándar de Windows TEdit en este TRichEdit?Uso del menú contextual de TEdit para TRichEdit

Sé que podría crear un menú simple para simular el menú TEdit para las operaciones simples como copiar/pegar, etc. (Example), sin embargo, también me gustaría mantener las opciones de menú más avanzadas, como las opciones Unicode, orden de lectura, y para utilizar las mismas cadenas de localización.

Edición: He encontrado una possible lead (tratando de averiguarlo ya que no soy un experto MFC) ...

+0

sé que han hecho que la investigación sobre este antes, y yo creo que fue en relación con una pregunta SO. –

+0

@Andreas, y una conclusión: -? Supongo que esos menús provienen de clases base de Windows. – TLama

+0

TLama, sí, no creo que haya ninguna forma 'documentada' de hacerse con este menú. –

Respuesta

8

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 :)

Cuestiones relacionadas