Foros del Web » Programación para mayores de 30 ;) » Programación General » Visual Basic clásico »

Cabecera Listview

Estas en el tema de Cabecera Listview en el foro de Visual Basic clásico en Foros del Web. Que tal su ayuda por favor. Estoy tratando de hacer un menu contextual dando click con el boton derecho en la cabecera del control listview ...
  #1 (permalink)  
Antiguo 10/07/2008, 11:04
 
Fecha de Ingreso: julio-2008
Mensajes: 33
Antigüedad: 15 años, 9 meses
Puntos: 0
Cabecera Listview

Que tal su ayuda por favor. Estoy tratando de hacer un menu contextual dando click con el boton derecho en la cabecera del control listview pero no tengo este evento. Alguien sabe como???.
Gracias de antemano
  #2 (permalink)  
Antiguo 10/07/2008, 12:34
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
De acuerdo Respuesta: Cabecera Listview

Antes que nada. Bienvenido al foro, parboli.

Gracias a este código descubrí que podemos interceptar los mensajes del sistema enviados a una ventana: http://www.recursosvisualbasic.com.a...de-ventana.htm

Así que en este caso lo único que necesitamos es adaptarlo al encabezado del ListView para que recibamos el mensaje de click con el botón derecho.

Coloca este código en un módulo:
Código PHP:
Option Explicit
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As LongByVal hwnd As LongByVal msg As LongByVal wParam As LonglParam As Long) As Long
Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As LongByVal nIndex As LongByVal dwNewLong As Long) As Long
Private Declare Function SetTimer Lib "user32" (ByVal hwnd As LongByVal nIDEvent As LongByVal uElapse As LongByVal lpTimerFunc As Long) As Long
Private Declare Function KillTimer Lib "user32" (ByVal hwnd As LongByVal nIDEvent As Long) As Long
Private Const GWL_WNDPROC = (-4)
Private Const 
WM_RBUTTONDOWN = &H204
Private TrueWindowProc As Long
Private TimerEvent As Long
Public Function WindowProc(ByVal hwnd As LongByVal msg As LongByVal wParam As LonglParam As Long) As Long
If msg WM_RBUTTONDOWN Then
    TimerEvent 
SetTimer(000AddressOf RClickEvent)
End If
WindowProc CallWindowProc(TrueWindowProchwndmsgwParamlParam)
End Function
Public 
Sub ChangeWindowProc(ByVal hwnd As Long)
TrueWindowProc SetWindowLong(hwndGWL_WNDPROCAddressOf WindowProc)
End Sub
Public Sub RClickEvent()
KillTimer 0TimerEvent
'Aquí debes programar lo que quieres que se realice al hacer click con el botón derecho'
'Por ejemplo en este caso mostramos un menú contextual del Form1 con el nombre MainMenu'
Form1.PopupMenu Form1.MainMenu
End Sub 
En tu ventana coloca este código:
Código PHP:
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongByVal hWnd2 As LongByVal lpsz1 As StringByVal lpsz2 As String) As Long
Private Sub Form_Load()
Dim lhWnd As Long
'Obtenemos el hwnd del encabezado del ListView'
lhWnd FindWindowEx(ListView1.hwnd0"SysHeader32"vbNullString)
'Cambiamos el procedimiento para interceptar los mensajes'
ChangeWindowProc lhWnd
End Sub 
Espero que te sirva. Saludos
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #3 (permalink)  
Antiguo 10/07/2008, 13:06
 
Fecha de Ingreso: julio-2008
Mensajes: 33
Antigüedad: 15 años, 9 meses
Puntos: 0
De acuerdo Respuesta: Cabecera Listview

Muchas gracias David...lo probaré y lo comento.... Saludos
  #4 (permalink)  
Antiguo 10/07/2008, 14:30
 
Fecha de Ingreso: julio-2008
Mensajes: 33
Antigüedad: 15 años, 9 meses
Puntos: 0
Respuesta: Cabecera Listview

David probé el código tal como me indicaste,lo adapté a mi aplicación y no logré que apareciera el menú. Corre todo normal pero al hacer el click derecho en la cabecera del listview no produce nada, no aparece el menú.
Ayuda por favor
  #5 (permalink)  
Antiguo 10/07/2008, 14:43
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Exclamación Respuesta: Cabecera Listview

Cita:
Iniciado por parboli Ver Mensaje
David probé el código tal como me indicaste,lo adapté a mi aplicación y no logré que apareciera el menú. Corre todo normal pero al hacer el click derecho en la cabecera del listview no produce nada, no aparece el menú.
Ayuda por favor
Intenta colocar dentro del Sub RClickEvent() un MsgBox para ver si realmente se está ejecutando el código, o sea, si realmente está interceptando el click con el botón derecho del mouse...
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #6 (permalink)  
Antiguo 10/07/2008, 14:50
 
Fecha de Ingreso: julio-2008
Mensajes: 33
Antigüedad: 15 años, 9 meses
Puntos: 0
Respuesta: Cabecera Listview

Eso es lo que pasa, no intercepta el click...he estado depurando intrución por instrucción y cuando hago click con el botón derecho no produce nada, no se ejecuta ningún código
  #7 (permalink)  
Antiguo 10/07/2008, 14:57
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Pregunta Respuesta: Cabecera Listview

¿Estás colocando esto en el evento Load del Form?:
Código PHP:
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongByVal hWnd2 As LongByVal lpsz1 As StringByVal lpsz2 As String) As Long
Private Sub Form_Load()
Dim lhWnd As Long
'Obtenemos el hwnd del encabezado del ListView'
lhWnd FindWindowEx(ListView1.hwnd0"SysHeader32"vbNullString)
'Cambiamos el procedimiento para interceptar los mensajes'
ChangeWindowProc lhWnd
End Sub 
¿Cuando llamas a FindWindowEx te está devolviendo algún valor en lhWnd?
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #8 (permalink)  
Antiguo 10/07/2008, 15:09
 
Fecha de Ingreso: julio-2008
Mensajes: 33
Antigüedad: 15 años, 9 meses
Puntos: 0
Respuesta: Cabecera Listview

Si eso es lo que he hecho.
el valor que devuelve es: lhWnd= 0
  #9 (permalink)  
Antiguo 10/07/2008, 15:11
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Exclamación Respuesta: Cabecera Listview

Cita:
Iniciado por parboli Ver Mensaje
Si eso es lo que he hecho.
el valor que devuelve es: lhWnd= 0
Ahí está el problema, debería devolver el hWnd del encabezado del ListView, ¿cuál versión de Microsoft Windows Common Controls estás usando para insertar el ListView? Yo probé ese código usando la versión 5.0... no probé con la versión 6.0.
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #10 (permalink)  
Antiguo 10/07/2008, 15:33
 
Fecha de Ingreso: julio-2008
Mensajes: 33
Antigüedad: 15 años, 9 meses
Puntos: 0
Respuesta: Cabecera Listview

Ahí si corrió excelente ... pero al cambiar a la versión 5.0 no me corren mucho de las funciones que ya tenía programadas como por ejem al ordenar la lsita agregar iconos al emcabezado, no me aparecen las lineas de división, y varios procedimientos maá . Ay alguna forma de poder trabajar con la version 6.0 David el Grande ???
  #11 (permalink)  
Antiguo 10/07/2008, 15:50
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Exclamación Respuesta: Cabecera Listview

Sí, puedes trabajar con la versión 6.0. Solo debes cambiar donde dice SysHeader32 por msvb_lib_header.

Saludos
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #12 (permalink)  
Antiguo 10/07/2008, 17:15
 
Fecha de Ingreso: julio-2008
Mensajes: 33
Antigüedad: 15 años, 9 meses
Puntos: 0
De acuerdo Respuesta: Cabecera Listview

Muchas gracias David el grande, corre muy bien. Saludos
  #13 (permalink)  
Antiguo 10/07/2008, 21:50
 
Fecha de Ingreso: julio-2008
Mensajes: 33
Antigüedad: 15 años, 9 meses
Puntos: 0
Respuesta: Cabecera Listview

Otra consulta como puedo identificar a cual de las celdas o columnas de la cabecera del listview le he dado el clikck derecho. Gracias de antemano
  #14 (permalink)  
Antiguo 11/07/2008, 05:48
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Exclamación Respuesta: Cabecera Listview

Cita:
Iniciado por parboli Ver Mensaje
Otra consulta como puedo identificar a cual de las celdas o columnas de la cabecera del listview le he dado el clikck derecho. Gracias de antemano
No sé si eso sea posible, al menos yo no conozco ninguna forma de hacerlo. Pero trataré de investigar un poco más a ver qué sale, pero no te prometo que logre hacerlo...

Saludos
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #15 (permalink)  
Antiguo 11/07/2008, 12:42
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Exclamación Respuesta: Cabecera Listview

Una forma no tan elegante que se me ocurrió es que al recibir el mensaje WM_RBUTTONDOWN enviemos el mensaje WM_CLICK, entonces lo que sucede es que se producirá el evento ColumnClick del ListView, con lo cual podremos saber en qué columna se produjo el evento.
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #16 (permalink)  
Antiguo 11/07/2008, 15:09
 
Fecha de Ingreso: julio-2008
Mensajes: 33
Antigüedad: 15 años, 9 meses
Puntos: 0
De acuerdo Respuesta: Cabecera Listview

Cita:
Iniciado por David el Grande Ver Mensaje
Una forma no tan elegante que se me ocurrió es que al recibir el mensaje WM_RBUTTONDOWN enviemos el mensaje WM_CLICK, entonces lo que sucede es que se producirá el evento ColumnClick del ListView, con lo cual podremos saber en qué columna se produjo el evento.
David el Grande creo que estaría bien, yo a través de una variable podría identificar cuando es de uno uno o del otro y operaria en distinta forma cuando se produsca el evento ColumnClick. Pero por favor indicane donde es que debería modificar, donde pongo para enviar el mensaje WM_CLICK,no soy bueno en eso. Gracias
  #17 (permalink)  
Antiguo 11/07/2008, 15:11
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Exclamación Respuesta: Cabecera Listview

Lo siento, pero ahora mismo no podré ponerte el código. Y es que estoy sin Visual Basic, pero investiga sobre la API (SendMessage) y la constante WM_CLICK, seguro que encuentras algo.

Saludos
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #18 (permalink)  
Antiguo 13/07/2008, 11:36
 
Fecha de Ingreso: abril-2005
Mensajes: 351
Antigüedad: 19 años
Puntos: 3
Respuesta: Cabecera Listview

hola fijate de este modo

Código:
Option Explicit


Public Type POINTAPI
  x As Long
  y As Long
End Type

Private Type HD_HITTESTINFO
  pt    As POINTAPI
  flags As Long
  iItem As Long
End Type


Private Type TLoHiLong
   Lo As Integer
   Hi As Integer
End Type

Private Type TAllLong
   All As Long
End Type

Private Const HDM_HITTEST As Long = &H1206
Private Const LVM_FIRST = &H1000
Private Const LVM_GETHEADER  As Long = (LVM_FIRST + 31)
Private Const WM_LBUTTONUP As Long = &H202
Private Const WM_RBUTTONUP As Long = &H205
Private Const GWL_WNDPROC = (-4)

Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long

Dim PrevProc As Long


Public Sub HookListView(hwnd As Long)
    Dim HandleHEADER As Long
    HandleHEADER = SendMessage(hwnd, LVM_GETHEADER, 0, 0)
    PrevProc = SetWindowLong(HandleHEADER, GWL_WNDPROC, AddressOf WindowProc)
End Sub

Public Sub UnHookListView(hwnd As Long)
    Dim HandleHEADER As Long
    HandleHEADER = SendMessage(hwnd, LVM_GETHEADER, 0, 0)
    SetWindowLong HandleHEADER, GWL_WNDPROC, PrevProc
End Sub


Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    WindowProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)

    Dim hti As HD_HITTESTINFO
    Dim mLH As TLoHiLong, mAL As TAllLong
    
    
     If uMsg = WM_LBUTTONUP Or uMsg = WM_RBUTTONUP Then
    

        mAL.All = lParam
        LSet mLH = mAL
        hti.pt.x = mLH.Lo
        hti.pt.y = mLH.Hi
        
        SendMessage hwnd, HDM_HITTEST, 0&, hti
        
        If hti.iItem > -1 Then
            Select Case uMsg
                Case WM_LBUTTONUP: EnventLeftButtonUp hti.iItem + 1
                Case WM_RBUTTONUP: EnventRightButtonUp hti.iItem + 1
            End Select
        End If
        
    End If
    
End Function


'aca lo que queres
Private Sub EnventLeftButtonUp(ByVal Columna As Long)
Debug.Print Columna
'Form1.PopupMenu Form1.archivo
End Sub

'aca lo que queres
Private Sub EnventRightButtonUp(ByVal Columna As Long)
Debug.Print Columna

End Sub
Saludos
  #19 (permalink)  
Antiguo 14/07/2008, 06:48
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Exclamación Respuesta: Cabecera Listview

Excelente solución LeandroA.

P.S.: Para hacer como te comenté, tenemos dos opciones, enviar no WM_CLICK sino WM_LBUTTONDOWN y WM_LBUTTONDOWN con lo que decimos a la ventana que se ha pulsado y soltado el botón izquierdo del mouse. O también podemos simular un click usando mouse_event...
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 23:00.