FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour La rueda del rat贸n no funciona en DROPDOWNLIST
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
La rueda del rat贸n no funciona en DROPDOWNLIST
Posted: Fri Jul 19, 2024 07:56 PM

Foreros:

Resulta que la rueda del rat贸n (MouseWheel) no funciona en un ComboBox

con estilo DROPDOWNLIST, alguna idea?

Saludos

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: La rueda del rat贸n no funciona en DROPDOWNLIST
Posted: Mon Jul 22, 2024 06:18 AM
Estimado Armando,

La cuesti贸n que planteas aunque parece f谩cil es bastante complicada. Te explico el por qu茅:

1. Windows no proporciona un estilo de combobox que automaticamente procese el mensaje WM_MOUSEWHEEL en la lista desplegada del combobox.
2. Los mensajes WM_MOUSEWHEEL llegan a la lista desplegada y no al combobox por lo que no podemos usar oCombo:bMouseWheel
3. La 煤nica soluci贸n que parece posible es localizar el handle de ventana de la lista desplegable y "subclasear" su procedimiento para que procese WM_MOUSEWHEEL adecuadamente.

Para localizar el handle de la lista desplegada podemos hacer esto:
Code (fw): Select all Collapse
METHOD HandleEvent( nMsg, nWParam, nLParam ) CLASS TComboBox

聽 聽local hWndComboList

聽 聽if nMsg == FM_CLOSEUP
聽 聽 聽 return ::CloseUp()
聽 聽endif

聽 聽if nMsg == FM_DROPDOWN
聽 聽 聽 return ::DropDown()
聽 聽endif

聽 聽if ::hWndComboList == nil .and. IsWindow( hWndComboList := hWndComboList( ::hWnd ) )
聽 聽 聽 ::hWndComboList = hWndComboList 
聽 聽 聽 // SetWindowProc( hWndComboList, { || nil } ) 聽 // probando la nueva funci贸n SetWindowProc()
聽 聽endif 聽 

return ::Super:HandleEvent( nMsg, nWParam, nLParam )
Ahora en ::hWndComboList tenemos el handle de ventana de la lista desplegada y tenemos que implementar una nueva funci贸n SetWindowProc() para "subclasearla" y asi poder implementar el comportamiento para los mensajes WM_MOUSEWHEEL.

El c贸digo de la nueva funci贸n SetWindowProc() es un tanto complicado pero debera funcionar correctamente implementado asi:
Code (fw): Select all Collapse
#include <windows.h>
#include <hbapi.h>
#include <hbapiitm.h>
#include <hbvm.h>

#if ( defined( _MSC_VER ) 聽&& ( _MSC_VER < 1500 ) ) // VC98
聽 聽#define GWLP_USERDATA 聽 聽-21 
聽 聽#define GWLP_WNDPROC 聽 聽 聽-4
聽 聽LONG_PTR GetWindowLongPtr( HWND hWnd, int nIndex );
聽 聽LONG_PTR SetWindowLongPtr( HWND hWnd, int nIndex, LONG_PTR dwNewLong );
#endif

typedef struct
{
聽 聽PHB_ITEM pBlock;
聽 聽WNDPROC 聽pOldProc;
} HB_SUBCLASSED, * PHB_SUBCLASSED;

static LRESULT CALLBACK HB_SubclassedProc( HWND hWnd, UINT message,
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽WPARAM wParam, LPARAM lParam )
{
聽 聽PHB_SUBCLASSED pSubclassed = ( PHB_SUBCLASSED ) GetWindowLongPtr( hWnd, GWLP_USERDATA );

聽 聽if( pSubclassed && pSubclassed->pBlock )
聽 聽{
聽 聽 聽 PHB_ITEM pReturn;
聽 聽 聽 #ifndef _WIN64
聽 聽 聽 聽 聽PHB_ITEM phWnd = hb_itemPutNL( NULL, ( long ) hWnd );
聽 聽 聽 聽 聽PHB_ITEM pMessage = hb_itemPutNL( NULL, ( long ) message );
聽 聽 聽 聽 聽PHB_ITEM pwParam = hb_itemPutNL( NULL, ( long ) wParam );
聽 聽 聽 聽 聽PHB_ITEM plParam = hb_itemPutNL( NULL, ( long ) lParam ); 聽 聽 聽
聽 聽 聽 #else 聽 
聽 聽 聽 聽 聽PHB_ITEM phWnd = hb_itemPutNLL( NULL, ( HB_LONGLONG ) hWnd );
聽 聽 聽 聽 聽PHB_ITEM pMessage = hb_itemPutNLL( NULL, ( HB_LONGLONG ) message );
聽 聽 聽 聽 聽PHB_ITEM pwParam = hb_itemPutNLL( NULL, ( HB_LONGLONG ) wParam );
聽 聽 聽 聽 聽PHB_ITEM plParam = hb_itemPutNLL( NULL, ( HB_LONGLONG ) lParam ); 聽 聽 聽
聽 聽 聽 #endif 聽 
聽 聽 聽 hb_evalBlock( pSubclassed->pBlock, phWnd, pMessage, pwParam, plParam, NULL );
聽 聽 聽 hb_itemRelease( phWnd );
聽 聽 聽 hb_itemRelease( pMessage );
聽 聽 聽 hb_itemRelease( pwParam );
聽 聽 聽 hb_itemRelease( plParam );
聽 聽 聽 pReturn = hb_param( -1, HB_IT_ANY );
聽 聽 聽 if( HB_IS_NUMERIC( pReturn ) )
聽 聽 聽 聽 聽return hb_itemGetNL( pReturn );
聽 聽}

聽 聽return pSubclassed && pSubclassed->pOldProc ? 
聽 聽 聽 聽 聽 CallWindowProc( pSubclassed->pOldProc, hWnd, message, wParam, lParam ) :
聽 聽 聽 聽 聽 DefWindowProc( hWnd, message, wParam, lParam );
}

HB_FUNC( SETWINDOWPROC )
{
聽 聽#ifndef _WIN64 
聽 聽 聽 HWND hWnd = ( HWND ) hb_parnl( 1 );
聽 聽#else 聽 
聽 聽 聽 HWND hWnd = ( HWND ) hb_parnll( 1 );
聽 聽#endif 聽 
聽 聽PHB_ITEM pBlock = hb_param( 2, HB_IT_BLOCK );

聽 聽if( hWnd && pBlock )
聽 聽{
聽 聽 聽 PHB_SUBCLASSED pSubclassed = ( PHB_SUBCLASSED ) GetWindowLongPtr( hWnd, GWLP_USERDATA );

聽 聽 聽 if( ! pSubclassed )
聽 聽 聽 {
聽 聽 聽 聽 聽pSubclassed = ( PHB_SUBCLASSED ) hb_xgrab( sizeof( HB_SUBCLASSED ) );
聽 聽 聽 聽 聽SetWindowLongPtr( hWnd, GWLP_USERDATA, ( LONG_PTR ) pSubclassed );
聽 聽 聽 }
聽 聽 聽 else
聽 聽 聽 聽 聽hb_itemRelease( pSubclassed->pBlock );

聽 聽 聽 pSubclassed->pBlock = hb_itemNew( pBlock );
聽 聽 聽 pSubclassed->pOldProc = ( WNDPROC ) SetWindowLongPtr( hWnd, GWLP_WNDPROC,
聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 聽 ( LONG_PTR ) HB_SubclassedProc );

聽 聽 聽 hb_retnl( ( LONG_PTR ) pSubclassed->pOldProc );
聽 聽}
聽 聽else
聽 聽 聽 hb_retnl( 0 );
}

HB_FUNC( REMOVEWINDOWPROC )
{
聽 聽#ifndef _WIN64 
聽 聽 聽 HWND hWnd = ( HWND ) hb_parnl( 1 );
聽 聽#else 聽 
聽 聽 聽 HWND hWnd = ( HWND ) hb_parnll( 1 );
聽 聽#endif 聽 

聽 聽if( hWnd )
聽 聽{
聽 聽 聽 PHB_SUBCLASSED pSubclassed = ( PHB_SUBCLASSED ) GetWindowLongPtr( hWnd, GWLP_USERDATA );

聽 聽 聽 if( pSubclassed )
聽 聽 聽 {
聽 聽 聽 聽 聽SetWindowLongPtr( hWnd, GWLP_WNDPROC, ( LONG_PTR ) pSubclassed->pOldProc );
聽 聽 聽 聽 聽hb_itemRelease( pSubclassed->pBlock );
聽 聽 聽 聽 聽SetWindowLongPtr( hWnd, GWLP_USERDATA, 0 );
聽 聽 聽 聽 聽hb_xfree( pSubclassed );
聽 聽 聽 }
聽 聽}
}
En principio todo parece estar bien y ya podriamos continuar implementando el soporte para WM_MOUSEWHEEL. El problema es que al intentar usar SetWindowProc() obtenemos un GPF que nos deja fuera de juego. Estamos buscando la raz贸n de ese GPF.
regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: La rueda del rat贸n no funciona en DROPDOWNLIST
Posted: Mon Jul 22, 2024 08:39 AM
Est谩bamos equivocados :-)

Sin ning煤n cambio en FWH, la rueda de mouse SI funciona con listas de combobox cuando la lista es m谩s grande que el 谩rea de la lista.

Cuando la lista es grande, vemos una barra de desplazamiento y luego tanto la barra de desplazamiento como la rueda de mouse funcionan.

Cuando la lista es peque帽a, no hay necesidad y ni siquiera tiene sentido que la rueda de mouse funcione.

Gracias a Rao por sabiamente observar esto!

regards, saludos

Antonio Linares
www.fivetechsoft.com
Posts: 3358
Joined: Fri Oct 07, 2005 08:20 PM
Re: La rueda del rat贸n no funciona en DROPDOWNLIST
Posted: Mon Jul 22, 2024 04:59 PM

Maestro Antonio y Mr. Rao:

Tienen la boca llena de raz贸n, tengo dos PRG que usan el control, ahora que lo mencionaste

compar茅 uno con otro y efectivamente, uno funciona y en el otro no.

Revis茅 el control y en el que no funcionaba tenia yo el WINDOWS-STYLE Vert Scrollbar a NO.

Me disculpo fue mi error.

Saludos

SOI, s.a. de c.v.
estbucarm@gmail.com
http://www.soisa.mex.tl/
http://sqlcmd.blogspot.com/
Tel. (722) 174 44 45
Carpe diem quam minimum credula postero

Continue the discussion