[C con Clase] HDN_BEGINTRACK ListView

Steven Davidson srd4121 en njit.edu
Mar Mayo 27 23:00:50 CEST 2008


Hola Fernando,

Fernando wrote:
> Hola Steven, parece q hay un error en esta página de lista, pues hay
> entrar a leer tus respuestas, más abajo alguién retroalimenta sobre
> otros temas, en fin algo sin trascendencia. Respecto a la ins. de
> datos, cree un proyecto nvo. c un sólo dlg, y ya inserta
> perfectamente, quizá estoy mezclando los HWND de mi Dlg y del
> ListView, de igual forma gracias, aunq el tema de no redimensionar
> las columnas c/ mouse, no c por donde empezarlo, pues el rubro de
> clases y subclases no lo he utilizado , así q no tengo idea por donde
> implementar el msj HDN_BEGINTRACK, espero puedas librarme algún
> código...
> 

Disculpa que haya tardado tanto en responderte, pero sinceramente la 
solución era algo más complicada de la que esperaba.

Veamos. De las tres opciones que te di, la mejor es la primera: realizar 
una subclase. No te preocupes, no es del todo difícil, ya que sólo vamos 
a cambiar dos mensajes; bueno tres.

Hacer una subclase de un control no es nada más que sustituir su 
procedimiento de ventana por nuestra versión. En nuestro (nuevo) 
procedimiento de ventana, procesamos los mensajes que nos interesan y 
los que no los pasamos al procedimiento original. Hacemos lo siguiente:

WNDPROC WndProcOriginal;  // variable global

LRESULT CALLBACK HeaderProc( HWND hwnd, UINT message, WPARAM wParam, 
LPARAM lParam );

LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM 
lParam )
{
   static HWND hLV;  // manipulador al control "list-view"
   static HWND hHeader;

   switch( message )
   {
     case WM_CREATE:
     {
       // Código que necesites
       // ...
       hHeader = ListView_GetHeader( hLV );

       // Sustituimos el procedimiento de 'hHeader' por el nuestro
       WndProcOriginal = (WNDPROC)SetWindowLongPtr( hHeader, 
GWLP_WNDPROC, (LONG_PTR)HeaderProc );
       // Más código por aquí
       // ...
     }
     return 0;

     case WM_DESTROY:
       // Sustituimos el procedimiento de 'hHeader' por el original
       SetWindowLongPtr( hHeader, GWLP_WNDPROC, (LONG_PTR)WndProcOriginal );
       PostQuitMessage(0);
     return 0;
   }
   // Más casos y código
   // ...
}

LRESULT CALLBACK HeaderProc( HWND hwnd, UINT message, WPARAM wParam, 
LPARAM lParam )
{
   switch( message )
   {
     case WM_LBUTTONDOWN:
     case WM_LBUTTONDBLCLK:
       HDHITTESTINFO hti;
       hti.pt.x = LOWORD(lParam);
       hti.pt.y = HIWORD(lParam);

       // Comprobar dónde está el ratón en el control "header"
       SendMessage( hwnd, HDM_HITTEST, 0, (LPARAM)(&hti) );
       if( hti.flags & (HHT_ONDIVIDER | HHT_ONDIVOPEN) )
         return 0;
     break;

     case WM_SETCURSOR:
     return TRUE;  // No cambiamos el cursor
   }

   // Llamamos al procedimiento original para procesar los demás mensajes
   return CallWindowProc( WndProcOriginal, hwnd, message, wParam, lParam );
}

También podríamos cubrir todas las posibilidades y procesar los mensajes 
de ratón con el botón derecho (WM_RBUTTONXXX) y con el botón central 
(WM_MBUTTONXXX). Sin embargo, como en estos momentos estos mensajes no 
tienen ninguna repercursión, no hace falta considerarlos.


Espero que todo esto te ayude.

Steven






Más información sobre la lista de distribución Cconclase