Ir al contenido



Foto

[MULTILENGUAJE] Como Copiar Campos de un TListView

TListView Copy

  • Por favor identifícate para responder
3 respuestas en este tema

#1 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.760 mensajes
  • LocationMadrid - España

Escrito 13 julio 2018 - 07:19

Se me ha presentado la necesidad de poder copiar campos (SubItems) de un TListView y dado que la aplicación tiene muchos controles de ese tipo, decidí hacer un sistema sencillo de adaptar a los formularios, que tengan el citado componente y que me ahorrase reescribir código. La solución que he implementado es una clase que realiza un subclassing del ListView y le introduce un PopupMenu con la opción "copy". Si ya existía un menú previo asignado al ListView puede utilizar éste. El código de la clase está escrito primeramente en C++ y con API, de esta forma se puede adaptar a aplicaciones No VCL. Pero no os preocupéis, he hecho una traducción a delphi.
 
Para dejar claro que se ha hecho la copia del campo seleccionado, aparece un marquito en su borde durante 300 ms.
Es necesario incluir un archivo de recursos estilo WinXP
 
0ad6b274ab935542d16a8bb0b60ba0d1o.gif
 
Vamos a exponer el código que está probado para delphi 6, 7 y Berlin.


delphi
  1. unit ListViewCopy;
  2.  
  3. //------------------------------------------------------------------------------
  4. // TLVCopy  V 2.0
  5. // escafandra 2018
  6. // Clase para permitir copiar al portapapeles un campo de texto de un ListView
  7. // tipo vsReport, visualiza el contorno del campo del Item copiado
  8. // Incluir recursos estilo WinXP
  9.      
  10.  
  11. interface
  12.  
  13. uses Windows, Messages, CommCtrl;
  14.  
  15. type
  16.  
  17. {$IfnDef TLVITEMINDEX}
  18. TLVITEMINDEX = record
  19.   iItem: integer;
  20.   iGroup: integer;
  21. end;
  22. PLVITEMINDEX = ^TLVITEMINDEX;
  23. {$EndIf}
  24.  
  25. TLVCopy = class
  26.   private
  27.     hListView: THANDLE;
  28.     Window: THANDLE;
  29.     OldListViewProc: Pointer;
  30.     Menu: HMENU ;
  31.     Point: TPOINT ;
  32.     ItemIndex: integer;
  33.     MenuIndex: integer;
  34.     DeleteMenu: boolean;
  35.  
  36.     function ListViewProc(Handle: HWND; Msg: DWORD; WParam: DWORD; LParam: DWORD): DWORD; stdcall;
  37.     function CopyText(Text: PAnsiChar): boolean;
  38.   public
  39.     destructor Destroy; override;
  40.     procedure  SetHandle(Handle: THANDLE; Text: PAnsiCHAR = nil; _menu: HMENU = 0; _menuIndex: integer = 0; Win: THANDLE = 0);
  41. end;
  42.  
  43. const
  44. LVM_GETITEMINDEXRECT = (LVM_FIRST + 209);
  45.  
  46. implementation
  47.  
  48. function ListView_GetColumnCount(hListView: THANDLE): integer;
  49. var
  50.   hHdr: HWND;
  51. begin
  52.   hHdr:= SendMessage(hListView, LVM_GETHEADER, 0, 0);
  53.   Result:= SendMessage(hHdr, HDM_GETITEMCOUNT, 0, 0);
  54. end;
  55.  
  56. function ListView_HitTest(hListView: THANDLE; var IInfo: TLVHITTESTINFO): integer;
  57. begin
  58.   Result:= SendMessage(hListView, LVM_HITTEST, 0, integer(@IInfo));
  59. end;
  60.  
  61. function ListView_GetItemIndexRect(hListView: THANDLE; var lvii: TLVITEMINDEX; SubItem, Code: cardinal; var Rect: TRect): integer;
  62. begin
  63.   Rect.Top:= SubItem;
  64.   Rect.Left:= Code;
  65.   Result:= SendMessage(hListView, LVM_GETITEMINDEXRECT, Cardinal(@lvii), cardinal(@Rect));
  66. end;
  67.  
  68. function GetItemAndSubItem(hListView: THANDLE; X, Y: integer; var SubItem: integer): integer;
  69. var
  70.   IInfo: TLVHITTESTINFO;
  71.   ItemIndex, Columns, ComentLeft: integer;
  72. begin
  73.   IInfo.pt.x:= 5;
  74.   IInfo.pt.y:= Y;
  75.   ItemIndex:= ListView_HitTest(hListView, IInfo);
  76.  
  77.   Columns:= ListView_GetColumnCount(hListView);
  78.   ComentLeft:= 0;
  79.   SubItem:= -1;
  80.   repeat
  81.     inc(SubItem);
  82.     ComentLeft:= ComentLeft + ListView_GetColumnWidth(hListView, SubItem);
  83.   until (X < ComentLeft) or (SubItem >= Columns - 1);
  84.  
  85.   if X > ComentLeft then SubItem:= -1;
  86.   Result:= ItemIndex;
  87. end;
  88.  
  89. // SubItem = 0 para Caption
  90. function GetRect(hListView: THANDLE; ItemIndex, SubItem: integer): TRect;
  91. var
  92.   lvii: TLVITEMINDEX;
  93. begin
  94.   lvii.iItem:= ItemIndex;
  95.   ListView_GetItemIndexRect(hListView, lvii, SubItem, LVIR_BOUNDS, Result);
  96.   if SubItem = 0 then
  97.     Result.right:= Result.left + ListView_GetColumnWidth(hListView, 0);
  98. end;
  99.  
  100. //---------------------------------------------------------------------------
  101. // SubItem = 0 para Caption
  102. procedure DrawFrameRect(hListView: THANDLE; ItemIndex, SubItem: integer; Color: TCOLORREF);
  103. var
  104.   R: TRect;
  105.   DC: HDC;
  106.   Pen: HPEN;
  107. begin
  108.   R:= GetRect(hListView, ItemIndex, SubItem);
  109.   DC:= GetDC(hListView);
  110.   Pen:= CreatePen(PS_SOLID, 3, Color);
  111.   SelectObject(DC, GetStockObject(NULL_BRUSH));
  112.   SelectObject(DC, Pen);
  113.   Rectangle(DC, R.left, R.top, R.right, R.bottom);
  114.   DeleteObject(Pen);
  115.   ReleaseDC(hListView, DC);
  116. end;
  117.  
  118.  
  119. function DefListViewProc(Handle: HWND; Msg: DWORD; WParam: DWORD; LParam: DWORD): DWORD; stdcall;
  120. var
  121.   pLVCopy: TLVCopy;
  122. begin
  123.   pLVCopy:= TLVCopy(GetWindowLong(Handle, GWL_USERDATA));
  124.   if pLVCopy <> nil then
  125.     Result:= pLVCopy.ListViewProc(Handle, Msg, WParam, LParam)
  126.   else
  127.     Result:= DefWindowProc(Handle, Msg, WParam, LParam);
  128. end;
  129.  
  130. function TLVCopy.ListViewProc(Handle: HWND; Msg: DWORD; WParam: DWORD; LParam: DWORD): DWORD; stdcall;
  131. var
  132.   Item: TLVITEMA;
  133.   P: TPoint;
  134.   Si, n: integer;
  135.   R: TRect;
  136.   Buffer: array [0..511] of AnsiCHAR;
  137. begin
  138.   if Msg = WM_RBUTTONDOWN then
  139.   begin
  140.     Point.x:= LParam and $FFFF;
  141.     Point.y:= LParam shr 16;
  142.     if (GetItemAndSubItem(hListView, Point.x, Point.y, Si) >= 0) and (Si>=0) then
  143.     begin
  144.       P:= Point;
  145.       ClientToScreen(Handle, P);
  146.       TrackPopupMenuEx(Menu, 0, P.x, P.y, hListView, nil);
  147.       Result:= DefWindowProc(Handle, Msg, WParam, LParam);
  148.       Exit;
  149.     end;
  150.   end
  151.   else if Msg = WM_COMMAND then
  152.   begin
  153.     if WParam = cardinal(MenuIndex) then
  154.     begin
  155.       // Obtengo ItemIndex y SubItem
  156.       ItemIndex:= GetItemAndSubItem(hListView, Point.x, Point.y, Si);
  157.  
  158.       // Leyendo el texto a copiar
  159.       Item.iItem:= ItemIndex;
  160.       Item.iSubItem:= Si;
  161.       Item.pszText:= Buffer;
  162.       Item.cchTextMax:= sizeof(Buffer);
  163.       n:= SendMessage(hListView, LVM_GETITEMTEXTA, ItemIndex, integer(@Item));
  164.  
  165.       // Copiando al ClipBoard y pintando el marco
  166.       if n>0 then
  167.       begin
  168.         // Copiando al ClipBoard
  169.         if CopyText(Buffer) then
  170.         begin
  171.           // Pintando el marco para confirmar
  172.           DrawFrameRect(hListView, ItemIndex, Si, $FFFF00);
  173.           Sleep(300);
  174.           R:= GetRect(hListView, ItemIndex, Si);
  175.           InflateRect(R, 1, 1);
  176.           InvalidateRect(hListView, @R, true);
  177.         end;
  178.       end;
  179.     end;
  180.     if (WParam and $0000FFFF) <> 0 then
  181.       // Se rebota el mensaje para que la ventana de tratamiento del menú ya existente
  182.       // pueda tratar el comando
  183.       PostMessage(Window, WM_COMMAND, WParam, 0);
  184.   end;
  185.   Result:= CallWindowProc(OldListViewProc, Handle, Msg, WParam, LParam);
  186. end;
  187.  
  188. // Cuando ya se dispone de un menú, se puede usar pasando su Handle, el Index para
  189. // activar el Copy y la ventana de tratamiento de mensajes del menú existenteprocedure TLVCopy.SetHandle(Handle: THANDLE; Text: PAnsiCHAR = nil; _menu: HMENU = 0; _menuIndex: integer = 0;  Win: THANDLE = 0);
  190. procedure TLVCopy.SetHandle(Handle: THANDLE; Text: PAnsiCHAR = nil; _menu: HMENU = 0; _menuIndex: integer = 0; Win: THANDLE = 0);
  191. begin
  192.   if (hListView <> 0) or (Handle = INVALID_HANDLE_VALUE) or (Handle = 0) then
  193.   if hListView <> 0 then
  194.   begin
  195.     SetWindowLong(hListView, GWL_USERDATA, 0);
  196.     SetWindowLong(hListView, GWL_WNDPROC, LongInt(OldListViewProc));
  197.     hListView:= 0;
  198.     if DeleteMenu then DestroyMenu(Menu);
  199.   end;
  200.  
  201.   if (Handle <> INVALID_HANDLE_VALUE) and (Handle <> 0) then
  202.   begin
  203.     hListView:= Handle;
  204.     SetWindowLong(hListView, GWL_USERDATA, LongInt(self));
  205.     OldListViewProc:= Pointer(SetWindowLong(hListView, GWL_WNDPROC, LongInt(@DefListViewProc)));
  206.     if _menu > 0 then
  207.     begin
  208.       Menu:= _menu;
  209.       Window:= Win;
  210.       MenuIndex:= _menuIndex;
  211.       DeleteMenu:= false;
  212.     end else
  213.     begin
  214.       Menu:= CreatePopupMenu();
  215.       MenuIndex:= 0;
  216.       if Text <> nil then
  217.         InsertMenuA(Menu, 0, MF_POPUP, MenuIndex, Text)
  218.       else
  219.         InsertMenuA(Menu, 0, MF_POPUP, MenuIndex, 'Copiar Campo');
  220.       DeleteMenu:= true;
  221.     end;
  222.   end;
  223. end;
  224.  
  225. function TLVCopy.CopyText(Text: PAnsiCHAR): boolean;
  226. var
  227.   clBuffer: HGLOBAL;
  228.   GBuffer: PAnsiCHAR;
  229. begin
  230.   Result:= OpenClipboard(hListView);
  231.   if Result then
  232.   begin
  233.     EmptyClipboard();
  234.     clBuffer:= GlobalAlloc(GMEM_DDESHARE, lstrlenA(Text)+1);
  235.     GBuffer:= GlobalLock(clBuffer);
  236.     lstrcpyA(GBuffer, Text);
  237.     GlobalUnlock(clBuffer);
  238.     SetClipboardData(CF_TEXT, clBuffer);
  239.     CloseClipboard();
  240.   end;
  241. end;
  242.  
  243. destructor TLVCopy.Destroy;
  244. begin
  245.   SetHandle(0);
  246. end;
  247.  
  248. end.

La forma de uso es bien sencilla, se precisa una instancia TLVCopy por cada TListView al que queramos dotar de la opción copy. A la instancia se le asigna el Handle del TListView y listo:


delphi
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7. Dialogs, ComCtrls, ListViewCopy;
  8.  
  9. type
  10. TForm1 = class(TForm)
  11. ListView: TListView;
  12. procedure FormCreate(Sender: TObject);
  13. private
  14. LVCopy: TLVCopy;
  15. public
  16. { Public declarations }
  17. end;
  18.  
  19. var
  20. Form1: TForm1;
  21.  
  22. implementation
  23.  
  24. {$R *.dfm}
  25.  
  26. procedure TForm1.FormCreate(Sender: TObject);
  27. begin
  28. LVCopy:= TLVCopy.Create;
  29. LVCopy.SetHandle(ListView.Handle);
  30. end;
  31.  
  32. procedure TForm1.FormDestroy(Sender: TObject);
  33. begin
  34.   LVCopy.Free;
  35. end;
  36.  
  37. end.

Para que el código sea compatible en versiones antiguas, he optado por descartar UNICODE aunque esto es transparente al uso de la clase, es importante decirlo por si alguno quiere meterle mano.
 
 
Características:
1. Usa la técnica del subclassing con API pura.
2. Cada Instancia controla un TListView.
3. Crea un PopupMenu con la opción de copiar.
4. Una vez copiado el texto, remarca el campo con un marquito durante 300 ms.
5. El Texto del Item del menú se puede personalizar.
6. Si ya existe un menú previo, se puede pasar como parámetro pero en este caso también hay que pasar el valor Item.Comand del MenuItem que se tenga previsto para la opción copiar.
7. Usa Texto no Unicode.
8. La versión delphi requiere destruir la instancia, no así la C++
 
 
Saludos.


  • 1

#2 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.760 mensajes
  • LocationMadrid - España

Escrito 13 julio 2018 - 07:34

La versión C++ es la madre de la criatura y dado a que la clase no es un componente, la instancia creada no se trata como un puntero con lo que no se precisa destruirla. La funcionalidad es la misma que la versión delphi y también desecha UNICODE. Está probada en C++ Builder 5 y Berlin.


cpp
  1. //------------------------------------------------------------------------------
  2. // TLVCopy V 2.0
  3. // escafandra 2018
  4. // Clase para permitir copiar al portapapeles un campo de texto de un ListView
  5. // tipo vsReport, visualiza el contorno del campo del Item copiado
  6. // Incluir recursos estilo WinXP
  7.      
  8. #ifndef ListViewCopyH
  9. #define ListViewCopyH
  10.  
  11.  
  12. #include <Windows.h>
  13. #include <Windowsx.h>
  14. #include <commctrl.h>
  15.  
  16. #ifndef STRICT
  17.   typedef int  (__stdcall *PLRESULT)();
  18. #else
  19.   typedef WNDPROC PLRESULT;
  20. #endif
  21.  
  22.  
  23.  
  24. //typedef int (__stdcall *PLRESULT)();
  25.  
  26. //---------------------------------------------------------------------------
  27. #ifndef LVM_GETITEMINDEXRECT
  28. typedef struct tagLVITEMINDEX {
  29.   int iItem;
  30.   int iGroup;
  31. } LVITEMINDEX, *PLVITEMINDEX;
  32. #define LVM_GETITEMINDEXRECT    (LVM_FIRST + 209)
  33. #define ListView_GetItemIndexRect(hwnd, plvii, iSubItem, code, prc) \
  34.         (BOOL)SNDMSG((hwnd), LVM_GETITEMINDEXRECT, (WPARAM)(LVITEMINDEX*)(plvii), \
  35.                 ((prc) ? ((((LPRECT)(prc))->top = (iSubItem)), (((LPRECT)(prc))->left = (code)), (LPARAM)(prc)) : (LPARAM)(LPRECT)NULL))
  36. #endif
  37. /*
  38. int GetItemAndSubItem(HANDLE hListView, int X, int Y, int *SubItem);
  39. RECT GetRect(HANDLE hListView, int ItemIndex, int SubItem);
  40. void DrawFrameRect(HANDLE hListView, int ItemIndex, int SubItem,  COLORREF Color);
  41. */
  42. class TLVCopy
  43. {
  44.   private:
  45.   HWND  hListView;
  46.   HWND  Window;
  47.   HMENU hMenu;
  48.   PLRESULT OldListViewProc;
  49.   POINT Point;
  50.   int ItemIndex;
  51.   int MenuIndex;
  52.   BOOL DeleteMenu;
  53.  
  54.   BOOL CopyText(char* Text);
  55.   static LRESULT __stdcall DefListViewProc(HWND hWnd, UINT Msg, WPARAM WParam, LPARAM LParam);
  56.   LRESULT __stdcall ListViewProc(HWND hWnd, UINT Msg, WPARAM WParam, LPARAM LParam);
  57.  
  58.   public:
  59.   void SetHandle(HWND HListView, char *Text = 0, HMENU hmenu = 0, int menuIndex = 0, HWND hWnd = 0);
  60.   ~TLVCopy();
  61. };
  62.  
  63. #endif


cpp
  1. //------------------------------------------------------------------------------
  2. // TLVCopy  V 2.0
  3. // escafandra 2018
  4. // Clase para permitir copiar al portapapeles un campo de texto de un ListView
  5. // tipo vsReport, visualiza el contorno del campo del Item copiado
  6. // Incluir recursos estilo WinXP
  7.      
  8. #include "ListViewCopy.h"
  9.  
  10. int ListView_GetColumnCount(HWND hListView)
  11. {
  12.   HWND hHdr = (HWND)SendMessage(hListView, LVM_GETHEADER, 0, 0);
  13.   return SendMessage(hHdr, HDM_GETITEMCOUNT, 0, 0L);
  14. }
  15.  
  16. int GetItemAndSubItem(HWND hListView, int X, int Y, int *SubItem)
  17. {
  18.   LVHITTESTINFO IInfo;
  19.   IInfo.pt.x = 5;
  20.   IInfo.pt.y = Y;
  21.   int ItemIndex = ListView_HitTest(hListView, &IInfo);
  22.  
  23.   if(SubItem){
  24.     int Columns = ListView_GetColumnCount(hListView);
  25.     int ComentLeft = 0;
  26.     for(*SubItem = -1; *SubItem + 1 < Columns && X >= ComentLeft; ++*SubItem)
  27.       ComentLeft += ListView_GetColumnWidth(hListView, *SubItem + 1);
  28.     if(X > ComentLeft) *SubItem = -1;
  29.   }
  30.   return ItemIndex;
  31. }
  32.  
  33. // SubItem = 0 para Caption
  34. RECT GetRect(HWND hListView, int ItemIndex, int SubItem)
  35. {
  36.   RECT Result;
  37.   LVITEMINDEX lvii;
  38.   lvii.iItem = ItemIndex;
  39.   ListView_GetItemIndexRect(hListView, &lvii, SubItem, LVIR_BOUNDS, &Result);
  40.   if(SubItem == 0)
  41.     Result.right = Result.left + ListView_GetColumnWidth(hListView, 0);
  42.   return Result;
  43. }
  44.  
  45. //---------------------------------------------------------------------------
  46. // SubItem = 0 para Caption
  47. void DrawFrameRect(HWND hListView, int ItemIndex, int SubItem,  COLORREF Color)
  48. {
  49.   RECT R = GetRect(hListView, ItemIndex, SubItem);
  50.   HDC hDC = GetDC(hListView);
  51.   HPEN hPen = CreatePen(PS_SOLID, 3, Color);
  52.   SelectObject(hDC, GetStockObject(NULL_BRUSH));
  53.   SelectObject(hDC, hPen);
  54.   Rectangle(hDC, R.left, R.top, R.right, R.bottom);
  55.   DeleteObject(hPen);
  56.   ReleaseDC(hListView, hDC);
  57. }
  58.  
  59. //---------------------------------------------------------------------------
  60.  
  61.  
  62.  
  63. //---------------------------------------------------------------------------
  64. // Clase TLVCopy
  65. BOOL TLVCopy::CopyText(CHAR* Text)
  66. {
  67.   if(OpenClipboard(hListView)){
  68.     EmptyClipboard();
  69.     HGLOBAL clBuffer = GlobalAlloc(GMEM_DDESHARE, lstrlenA(Text)+1);
  70.     char* GBuffer = (char*)GlobalLock(clBuffer);
  71.     lstrcpyA(GBuffer, Text);
  72.     GlobalUnlock(clBuffer);
  73.     SetClipboardData(CF_TEXT, clBuffer);
  74.     CloseClipboard();
  75.     return true;
  76.   }
  77.   return false;
  78. }
  79.  
  80. //---------------------------------------------------------------------------
  81. // Tratamiento de Mensajes
  82. LRESULT __stdcall TLVCopy::DefListViewProc(HWND hWnd, UINT Msg, WPARAM WParam, LPARAM LParam)
  83. {
  84.   TLVCopy* pLVCopy = (TLVCopy*)GetWindowLongPtr(hWnd, GWL_USERDATA);
  85.   if(pLVCopy)
  86.     return pLVCopy->ListViewProc(hWnd, Msg, WParam, LParam);
  87.   else return DefWindowProc(hWnd, Msg, WParam, LParam);
  88. }
  89.  
  90. LRESULT __stdcall TLVCopy::ListViewProc(HWND hWnd, UINT Msg, WPARAM WParam, LPARAM LParam)
  91. {
  92.   if(Msg == WM_RBUTTONDOWN){
  93.     Point.x = GET_X_LPARAM(LParam);
  94.     Point.y = GET_Y_LPARAM(LParam);
  95.     int Si;
  96.     if(GetItemAndSubItem(hListView, Point.x, Point.y, &Si) >= 0 && Si >=0){
  97.       POINT P = Point;
  98.       ClientToScreen(hWnd, &P);
  99.       TrackPopupMenuEx(hMenu, 0, P.x, P.y, hListView, 0);
  100.       return DefWindowProc(hWnd, Msg, WParam, LParam);
  101.     }
  102.   }
  103.   else if(Msg == WM_COMMAND){
  104.     if(WParam == (UINT)MenuIndex){
  105.       // Obtengo ItemIndex y SubItem
  106.       int Si;
  107.         ItemIndex = GetItemAndSubItem(hListView, Point.x, Point.y, &Si);
  108.  
  109.       // Leyendo el texto a copiar
  110.       char Buffer[512];
  111.         LVITEMA Item;
  112.       Item.iItem = ItemIndex;
  113.       Item.iSubItem = Si;
  114.         Item.pszText = Buffer;
  115.       Item.cchTextMax = sizeof(Buffer);
  116.         int n = SendMessage(hListView, LVM_GETITEMTEXTA, ItemIndex, (LPARAM)&Item);
  117.  
  118.       // Copiando al ClipBoard y pintando el marco
  119.       if(n){
  120.         // Copiando al ClipBoard
  121.         if(CopyText(Buffer)){
  122.           // Pintando el marco para confirmar
  123.           DrawFrameRect(hListView, ItemIndex, Si, 0xFFFF00);
  124.           Sleep(300);
  125.           RECT R = GetRect(hListView, ItemIndex, Si);
  126.           InflateRect(&R, 1, 1);
  127.               InvalidateRect(hListView, &R, true);
  128.         }
  129.         }
  130.       }
  131.     else if(WParam & 0x0000FFFF){
  132.       // Se rebota el mensaje para que la ventana de tratamiento del menú ya existente
  133.       // pueda tratar el comando
  134.       PostMessage(Window, WM_COMMAND, WParam, 0);
  135.     }
  136.   }
  137.   return CallWindowProc(OldListViewProc, hWnd, Msg, WParam, LParam);
  138. }
  139.  
  140. // Cuando ya se dispone de un menú, se puede usar pasando su Handle, el Index para
  141. // activar el Copy y la ventana de tratamiento de mensajes del menú existente
  142. void TLVCopy::SetHandle(HWND HListView, char *Text, HMENU hmenu, int menuIndex, HWND hWnd)
  143. {
  144.   if(hListView || HListView == INVALID_HANDLE_VALUE || !HListView)
  145.   if(hListView){
  146.     SetWindowLong(hListView, GWL_USERDATA, 0);
  147.     SetWindowLong(hListView, GWL_WNDPROC, (LONG)OldListViewProc);
  148.     hListView = 0;
  149.     if(DeleteMenu) DestroyMenu(hMenu);
  150.   }
  151.   if(HListView != INVALID_HANDLE_VALUE && HListView){
  152.     hListView = HListView;
  153.     SetWindowLongPtr(hListView, GWL_USERDATA, (LONG)this);
  154.     OldListViewProc = (PLRESULT)SetWindowLongPtr(hListView, GWL_WNDPROC, (LONG)TLVCopy::DefListViewProc);
  155.     if(hmenu > 0){
  156.       hMenu = hmenu;
  157.       Window = hWnd;
  158.       MenuIndex = menuIndex;
  159.       DeleteMenu = false;
  160.     }
  161.     else{
  162.       hMenu = CreatePopupMenu();
  163.       MenuIndex = 0;
  164.       if(Text)
  165.         InsertMenuA(hMenu, 0, MF_POPUP, MenuIndex, Text);
  166.       else
  167.         InsertMenuA(hMenu, 0, MF_POPUP, MenuIndex, "Copiar Campo");
  168.       DeleteMenu = true;
  169.     }
  170.   }
  171. }
  172.  
  173. TLVCopy::~TLVCopy()
  174. {
  175.   SetHandle(0);
  176. }

Un ejemplo de uso:


cpp
  1. //---------------------------------------------------------------------------
  2.  
  3. #include <vcl.h>
  4. #pragma hdrstop
  5.  
  6. #include "Unit1.h"
  7.  
  8.  
  9. //---------------------------------------------------------------------------
  10. #pragma package(smart_init)
  11. #pragma resource "*.dfm"
  12. TForm1 *Form1;
  13.  
  14.  
  15. //---------------------------------------------------------------------------
  16. __fastcall TForm1::TForm1(TComponent* Owner)
  17. : TForm(Owner)
  18. {
  19. LVCopy.SetHandle(ListView->Handle, "Copia esto");
  20. }
  21. //---------------------------------------------------------------------------

Como podéis ver, en este caso, asignamos un texto a nuestro menú.

 

 

Saludos.


  • 1

#3 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 13.804 mensajes
  • LocationMéxico

Escrito 13 julio 2018 - 11:32

Buenísimo, gracias amigo (y)

 

Saludos


  • 0

#4 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.760 mensajes
  • LocationMadrid - España

Escrito 16 agosto 2018 - 01:49

He actualizado el código para mejorar el comportamiento cuando se usa un menú ya existente.

 

 

Saludos.


  • 1





Etiquetado también con una o más de estas palabras: TListView, Copy