2012-04-18 4 views
5

Esiste un modo semplice/intelligente per caricare il menu di Windows TEdit standard in questo TRichEdit?Utilizzo del menu di scelta rapida TEdit per TRichEdit

So che potrei creare un semplice menu per simulare il menu TEdit per le semplici operazioni come copia/incolla ecc. (Example), tuttavia vorrei anche mantenere le opzioni di menu più avanzate come le opzioni Unicode, leggere l'ordine e utilizzare le stesse stringhe di localizzazione.

Edit: ho trovato un possible lead (cercando di capire come io non sono un esperto MFC) ...

+0

So di aver fatto della ricerca su questo prima, e penso che era in collegamento con una domanda SO. –

+0

@Andreas, e una conclusione: -? La mia ipotesi è che quei menu provengano da classi base di Windows. – TLama

+0

TLama, sì, non penso che ci sia un modo "documentato" per accedere a questo menu. –

risposta

8

Sulla base del "possibile piombo" e un po 'di MSDN, mi si avvicinò con una possibile soluzione. Non riesco ancora a risolvere il problema relativo all'ordine di lettura (e le opzioni Unicode). Sembra che funzioni diversamente per RichEdit che per Modifica, e semplicemente impostando o ottenendo il flag WS_EX_RTLREADING non funziona come previsto. In ogni modo, ecco il codice:

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; 

Qualsiasi commento sarebbe bello :)