PDA

Ver la Versión Completa : Mostrar el Hint de la lista desplegable de un combobox


aguml
13-12-2017, 15:32:17
La idea es ir moviendo el raton por encima de la lista y como son textos mas grandes pues ir mostrando el Hint. Tengo esto a partir de una funcion que me pasasteis y intento modificarla:
void __fastcall TForm1::AppIdle(TObject *Sender, bool &done)
{
TPoint pt;
HWND HWL;

GetCursorPos( &pt );
HWL = WindowFromPoint( pt );

if ( HWL != 0 )
{
char buff[128];
GetClassName( HWL, buff, sizeof( buff ) );
if ( StrIComp( buff, "ComboLBox" ) == 0)
{
int inx;
if ( FInCBoxMaps)
{
::ScreenToClient( HWL, &pt );
inx = LOWORD( SendMessage( HWL, LB_ITEMFROMPOINT, 0,
(LPARAM)MAKELONG(pt.x, pt.y)));

if ( inx >= 0 ){
//Aqui muestro la imagen
MostrarImagenMapa(inx);
}
}
TComboBox *CB = static_cast<TComboBox*>(FindVCLWindow(Mouse->CursorPos));
if(CB)
CB->Hint= CB->Items[inx].Text;
}
}
}
El caso es que creo que lo que hago para mostrar el hint no es correcto porque compila pero me parece que CB nunca obtiene un puntero valido. ¿me podrian ayudar?

aguml
14-12-2017, 13:58:03
He estado liado con ello pero no doy con el modo y tengo muchas dudas que no se como solucionar.
Esto es lo que tengo para controlar el evento de desplazarse por la lista y mostrar los Hints:
//Funcion que controla el evento de desplazamiento del raton sobre los items del combobox de los mapas
void __fastcall TForm1::AppIdle(TObject *Sender, bool &done)
{
TPoint pt;
HWND HWL;

RECT rcItem,rcLista;

GetCursorPos( &pt );
HWL = WindowFromPoint( pt );

if ( HWL != 0 )
{
char buff[128];
GetClassName( HWL, buff, sizeof( buff ) );
if ( StrIComp( buff, "ComboLBox" ) == 0)
{
int inx;
if ( FInCBox)
{
::ScreenToClient( HWL, &pt );
inx = LOWORD( SendMessage( HWL, LB_ITEMFROMPOINT, 0,
(LPARAM)MAKELONG(pt.x, pt.y)));

if ( inx >= 0 ){
//Aqui muestro la imagen
if(FInCBoxMaps){
MostrarImagenMapa(inx);
}

memset(textoHint,'\0',sizeof(textoHint));

//Obtengo la cadena del item
SendMessage( HWL, LB_GETTEXT, inx, int(&textoHint));
//Obtengo su posicion en la lista
SendMessage( HWL, LB_GETITEMRECT, inx, (LPARAM)&rcItem);
int largo=SendMessage( HWL, LB_GETTEXTLEN,inx,0);
//Muestro el hint siempre y cuando sea diferente al que ya se esta mostrando
if(StrIComp( textoHint, hint->Caption.c_str()) != 0)
{
//Necesito saber cuando estoy dentro de la lista del combobox y cuando no para mostrar el hint o hacerlo desaparecer

//Necesito indicarle tanto la posicion donde mostrarse como el tamaño justo
rcLista.left=pt.x; //Necesito la posicion donde se debe mostrar el hint ya que esto me lo muestra arriba del todo de la pantalla
rcLista.top=pt.y; //Necesito la posicion donde se debe mostrar el hint ya que esto me lo muestra arriba del todo de la pantalla
rcLista.right=rcLista.left + (largo * 6); //Necesito el ancho justo de lo que ocupa el texto porque esto no funciona asi
rcLista.bottom=rcLista.top + (rcItem.bottom - rcItem.top); //Necesito el alto justo de lo que ocupa el texto
hint->Caption=textoHint;
hint->Color=clInfoBk;
hint->ActivateHint(rcLista,textoHint);
}
}
}
}
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBoxMapasDropDown(TObject *Sender)
{
hint= new THintWindow(ComboBoxMapas->Handle);
FInCBoxMaps = true;
FInCBox = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBoxMapasCloseUp(TObject *Sender)
{
delete hint;
ComboBoxMapas->Hint = ComboBoxMapas->Items->Strings[ComboBoxMapas->ItemIndex];
FInCBoxMaps = false;
FInCBox = false;
MostrarImagenMapa(ComboBoxMapas->ItemIndex);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBoxsDropDown(TObject *Sender)
{
hint= new THintWindow(ComboBoxMapas->Handle);
FInCBox = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBoxsCloseUp(TObject *Sender)
{
delete hint;
ComboBoxMapas->Hint = ComboBoxMapas->Items->Strings[ComboBoxMapas->ItemIndex];
FInCBox = false;
}
//---------------------------------------------------------------------------


Y en el .h:
class TForm1 : public TForm
{
__published: // IDE-managed Components
...
...
void __fastcall ComboBoxMapasCloseUp(TObject *Sender);
void __fastcall ComboBoxMapasDropDown(TObject *Sender);
void __fastcall ComboBoxsDropDown(TObject *Sender);
void __fastcall ComboBoxsCloseUp(TObject *Sender);
private: // User declarations
...
...
//Para mostrar imagenes cuando me mueva por el ComboBox de mapas
bool FInCBox, FInCBoxMaps;
THintWindow *hint;
char textoHint[200];

void __fastcall AppIdle(TObject *Sender, bool &done);
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Me muestra los Hints pero me los muestra arriba del todo de la pantalla en vez de debajo del item de la lista o encima o al lado como hace windows normalmente. Ademas no se como ponerle el ancho correcto para que coja todo el texto del Item. ¿Alguien que pueda ayudarme?
He visto un post donde Roman comenta sobre el tema y de ahi me he guiado un poco: https://www.clubdelphi.com/foros/showthread.php?p=523429#post523429
Tambien hablaba de que habia creado un componente que hacia esto pero al intentar descargarlo de los enlaces no puedo entrar en su pagina con lo que no puedo descargarlo y seria interesante tener un componente ya hecho que me hubiese ahorrado muchos dolores de cabeza :p

roman
14-12-2017, 15:47:00
He visto un post donde Roman comenta sobre el tema y de ahi me he guiado un poco: https://www.clubdelphi.com/foros/showthread.php?p=523429#post523429
Tambien hablaba de que habia creado un componente que hacia esto pero al intentar descargarlo de los enlaces no puedo entrar en su pagina con lo que no puedo descargarlo

Esa página ya no existe. En el otro hilo te he puesto el componente.

LineComment Saludos

aguml
14-12-2017, 16:26:05
He conseguido solucionarlo casi todo y ha quedado asi:
//Funcion que controla el evento de desplazamiento del raton sobre los items del combobox de los mapas
void __fastcall TForm1::AppIdle(TObject *Sender, bool &done)
{
TPoint pt;
HWND HWL;

RECT rcItem;

GetCursorPos( &pt );
HWL = WindowFromPoint( pt );

if ( HWL != 0 )
{
char buff[128];
GetClassName( HWL, buff, sizeof( buff ) );
if ( StrIComp( buff, "ComboLBox" ) == 0)
{
int inx;
if ( FInCBox)
{
::ScreenToClient( HWL, &pt );
inx = LOWORD( SendMessage( HWL, LB_ITEMFROMPOINT, 0,
(LPARAM)MAKELONG(pt.x, pt.y)));

if ( inx >= 0 ){
//Aqui muestro la imagen
if(FInCBoxMaps && lastIndex != inx){
MostrarImagenMapa(inx);
lastIndex=inx;
}

//memset(textoHint,'\0',sizeof(textoHint));

//Obtengo la cadena del item
SendMessage( HWL, LB_GETTEXT, inx, int(&textoHint));
//Obtengo su posicion en la lista
SendMessage( HWL, LB_GETITEMRECT, inx, (LPARAM)&rcItem);
}
}
//Muestro el hint siempre y cuando sea diferente al que ya se esta mostrando
if(pt.x >= rcItem.left && pt.x <= rcItem.right && pt.y >= rcItem.top && pt.y <= rcItem.bottom)
{
//Vuelvo a mostrarlo siempre que sea uno diferente al anterior
if(StrIComp( textoHint, hint->Caption.c_str()) != 0)
{
//Necesario para saber la posicion relativa para mostrar el hint
::ClientToScreen(HWL, &pt);
//int largo=SendMessage( HWL, LB_GETTEXTLEN,inx,0);

rcItem.left=pt.x;
rcItem.top=pt.y;
rcItem.right=pt.x + 300; //Necesito el ancho justo de lo que ocupa el texto porque esto no funciona asi
rcItem.bottom=pt.y + 15; //Necesito el alto justo de lo que ocupa el texto
hint->Caption=textoHint;
hint->Color=clInfoBk;
hint->ActivateHint(rcItem,textoHint);
}
}
}else{
if(hint != NULL){
hint->ReleaseHandle();
hint->Caption="";
}
}
}
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBoxMapasDropDown(TObject *Sender)
{
hint= new THintWindow(ComboBoxMapas->Handle);
FInCBoxMaps = true;
FInCBox = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBoxMapasCloseUp(TObject *Sender)
{
if(hint != NULL){
delete hint;
hint=NULL;
}
ComboBoxMapas->Hint = ComboBoxMapas->Items->Strings[ComboBoxMapas->ItemIndex];
FInCBoxMaps = false;
FInCBox = false;
MostrarImagenMapa(ComboBoxMapas->ItemIndex);
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBoxsDropDown(TObject *Sender)
{
hint= new THintWindow(ComboBoxMapas->Handle);
FInCBox = true;
}
//---------------------------------------------------------------------------

void __fastcall TForm1::ComboBoxsCloseUp(TObject *Sender)
{
TComboBox *CB = static_cast<TComboBox*>(Sender);
CB->Hint = CB->Items->Strings[CB->ItemIndex];
if(hint != NULL){
delete hint;
hint=NULL;
}
FInCBox = false;
}
//---------------------------------------------------------------------------

Lo que me falta es asignar el tamaño correcto al Hint para que se vea del largo del texto pero no se como hacerlo y ya llevo dos dias con esto.

aguml
14-12-2017, 18:18:29
Bueno, mirando el componente de Román he conseguido hacerlo. Gracias a todos.