Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Creando un componente derivado de TListView

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Creando un componente derivado de TListView Responder citando

Hola compañeros:

Les escribo solicitando su apoyo para entender porque no funciona del todo este componente que estoy desarrollando.

Está derivado de un TListView, y le tengo colocado varias cosas que he estado encontrando en la red.

En resumen, el componente funciona, pero en tiempo de diseño si lo selecciono me aparece una ventana de error indicando que:
"Canoot focus a disabled or invisible window."
Entiendo que estuviera entregando el foco a una ventana inactiva, pero es el TListView que está recibiendo el foco, o hay algo que no estoy entendiendo del todo ???

Espero que me puedad ayudar.

Saludos !!!


Código del CPP
Código:


#include <vcl.h>

#pragma hdrstop

#include "FondoListView.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//

static inline void ValidCtrCheck(TFondoListView *)
{
        new TFondoListView(NULL);
}
//---------------------------------------------------------------------------
__fastcall TFondoListView::TFondoListView(TComponent* Owner)
        : TListView(Owner)
{

}
//---------------------------------------------------------------------------

AnsiString __fastcall TFondoListView::RutaDelArchivo(void)
{
 if ( Ruta.IsEmpty() )
 {
  char temp[MAX_PATH];

  memset(temp,'\0',sizeof(temp));
  GetTempPath(sizeof(temp),temp);
  Ruta = AnsiString().sprintf("%snoitems.bmp", IncludeTrailingBackslash(temp) );
 }

 return Ruta;
}

void __fastcall TFondoListView::ColocaMensajeDeVacio(void)
{
  Graphics::TBitmap *Bitmap = new Graphics::TBitmap();
  Bitmap->Width = 250;
  Bitmap->Height = 100;
  Bitmap->Canvas->Font->Name = "Tahoma";
  Bitmap->Canvas->Font->Style = TFontStyles() << fsItalic;
  Bitmap->Canvas->TextOut(2, 5, "    No hay elementos disponibles en esta vista.");
  Bitmap->SaveToFile( RutaDelArchivo() );
  delete Bitmap;

  SendMessage(Handle, WM_SETREDRAW, false, 0);
  ListView_SetTextBkColor(Handle, CLR_NONE);
  ListView_DeleteAllItems(Handle);

  LVBKIMAGE lvbki;
  ZeroMemory(&lvbki, sizeof(LVBKIMAGE));
  lvbki.ulFlags = LVBKIF_SOURCE_URL | LVBKIF_STYLE_NORMAL;
  lvbki.pszImage = RutaDelArchivo().c_str();
  lvbki.xOffsetPercent = 50;
  lvbki.yOffsetPercent = 0;

  ListView_SetBkImage(Handle, &lvbki);
  SendMessage(Handle, WM_SETREDRAW, true, 0);
  InvalidateRect(Handle, NULL, true);
}

void __fastcall TFondoListView::LimpiaMensajeDeVacio(void)
{
  LVBKIMAGE lvbki;
  ZeroMemory(&lvbki, sizeof(LVBKIMAGE));
  ListView_SetBkImage(Handle, &lvbki);
  SendMessage(Handle, WM_SETREDRAW, true, 0);
  InvalidateRect(Handle, NULL, true);
}

void __fastcall TFondoListView::WndProc(TMessage& Msg)
{
 NMHDR* nmh;

 if (ComponentState.Contains(csDesigning))
 {
  Dispatch(&Msg);
  return;
 }
 switch ( Msg.Msg )
 {
   case WM_ERASEBKGND:
        DefaultHandler(&Msg);
        break;

   case WM_SETCURSOR:

         /* Si se seleccionó que SI se pueda mover las columnas */
         if ( FColumnasMovibles )
          Dispatch(&Msg);
         else
          Msg.Result = 1;
         break;

   case WM_NOTIFY:
          nmh = (NMHDR*)Msg.LParam;
          if ( (
                (nmh->code == HDN_BEGINTRACKW) ||
                (nmh->code == HDN_BEGINTRACKA) ) &&
                !FColumnasMovibles
             )
            Msg.Result = 1;
          else
           Dispatch(&Msg);
        break;

   /*case WM_PAINT:

         // If the listview is empty...
         if (
             (ListView_GetItemCount(Handle) <= 0) && //No tengo elementos
             FMostrarLeyendaVacio &&                 //Debo mostrar la leyenda que indica que está vacia la lista
             !FCadenaDeVacio.IsEmpty() &&            //Tiene algo que mostrar la leyenda
             (ViewStyle == vsReport)                 //El estilo es vsReport
            )
         {
             PAINTSTRUCT ps;
             HDC hdc = BeginPaint(Handle, &ps);

             // Find the listview dimensions
             RECT rc;
             ::GetClientRect(Handle, &rc);

             // Find the height of the header of the listview
             RECT rcHeader;
             HWND hHeader = ListView_GetHeader(Handle);
             Header_GetItemRect(hHeader, 0, &rcHeader);
             rc.top += rcHeader.bottom;
             rc.top += 10;

             ::SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
             SetBkMode(hdc, TRANSPARENT);
             SelectObject(hdc, (HFONT)GetStockObject(ANSI_VAR_FONT));

             DrawText(hdc, FCadenaDeVacio.c_str(), -1, &rc,DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_NOCLIP);
             EndPaint(Handle, &ps);
          }

         break;*/

   default:
        Dispatch(&Msg);
        break;
 }
}

namespace Fondolistview
{
        void __fastcall PACKAGE Register()
        {
                 TComponentClass classes[1] = {__classid(TFondoListView)};
                 RegisterComponents("General", classes, 0);
        }
}
//---------------------------------------------------------------------------


Código del H
Código:

//---------------------------------------------------------------------------

#ifndef FondoListViewH
#define FondoListViewH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Classes.hpp>
#include <ComCtrls.hpp>
#include <Controls.hpp>
//---------------------------------------------------------------------------
class PACKAGE TFondoListView : public TListView
{
private:
        AnsiString __fastcall RutaDelArchivo(void);
        bool       FColumnasMovibles;
        AnsiString Ruta;
        //bool       FMostrarLeyendaVacio;
        //AnsiString FCadenaDeVacio;
protected:
        virtual void __fastcall WndProc(TMessage& Msg);
public:
             __fastcall TFondoListView(TComponent* Owner);
        void __fastcall ColocaMensajeDeVacio(void);
        void __fastcall LimpiaMensajeDeVacio(void);
__published:
        __property bool       ColumnasMovibles    = {read=FColumnasMovibles   , write=FColumnasMovibles };
        //__property bool       MostrarLeyendaVacio = {read=FMostrarLeyendaVacio, write=FMostrarLeyendaVacio };
        //__property AnsiString       CadenaDeVacio = {read=FCadenaDeVacio      , write=FCadenaDeVacio };
};
//---------------------------------------------------------------------------
#endif
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Bien, pues he hecho un control pero deriva de TComboBox, y alli intercepto un mensaje en especifico pero lo hago con la macro BEGIN_MESSAGE_MAP. Puedes revisar en la ayuda toda la información respecto a esta macro.

He hecho las pruebas con lo que intentas hacer y funciona. Solo que cuando cambias de tamaño las columnas el mensaje de que "no hay datos" se distorciona. Será cuestion de seguir haciendo pruebas.

Te dejo el código para que lo pruebes y puedas terminar tu componente.

Cuerpo de la clase
Código:
class PACKAGE TFondoListView : public TListView
{
private:
        AnsiString __fastcall RutaDelArchivo(void);
        bool       FColumnasMovibles;
        AnsiString Ruta;
        bool       FMostrarLeyendaVacio;
        AnsiString FCadenaDeVacio;
        void __fastcall WMErase(TWMNoParams &Message);
        void __fastcall WMSetCursor(TWMNoParams &Message);
        void __fastcall WMPaint(TWMNoParams &Message);
        BEGIN_MESSAGE_MAP
            VCL_MESSAGE_HANDLER(WM_ERASEBKGND, TWMNoParams, WMErase);
            VCL_MESSAGE_HANDLER(WM_SETCURSOR, TWMNoParams, WMSetCursor);
            VCL_MESSAGE_HANDLER(WM_PAINT, TWMNoParams, WMPaint);
        END_MESSAGE_MAP(TListView)
protected:
//        virtual void __fastcall WndProc(TMessage &Msg);
public:
             __fastcall TFondoListView(TComponent* Owner);
        void __fastcall ColocaMensajeDeVacio(void);
        void __fastcall LimpiaMensajeDeVacio(void);
__published:
        __property bool       ColumnasMovibles    = {read=FColumnasMovibles   , write=FColumnasMovibles };
        __property bool       MostrarLeyendaVacio = {read=FMostrarLeyendaVacio, write=FMostrarLeyendaVacio };
        __property AnsiString       CadenaDeVacio = {read=FCadenaDeVacio      , write=FCadenaDeVacio };
};




Implemnetacion de la clase
Código:
AnsiString __fastcall TFondoListView::RutaDelArchivo(void)
{
 if ( Ruta.IsEmpty() )
 {
  char temp[MAX_PATH];

  memset(temp,'\0',sizeof(temp));
  GetTempPath(sizeof(temp),temp);
  Ruta = AnsiString().sprintf("%snoitems.bmp", IncludeTrailingBackslash(temp) );
 }

 return Ruta;
}

void __fastcall TFondoListView::ColocaMensajeDeVacio(void)
{
  Graphics::TBitmap *Bitmap = new Graphics::TBitmap();
  Bitmap->Width = 250;
  Bitmap->Height = 100;
  Bitmap->Canvas->Font->Name = "Tahoma";
  Bitmap->Canvas->Font->Style = TFontStyles() << fsItalic;
  Bitmap->Canvas->TextOut(2, 5, "    No hay elementos disponibles en esta vista.");
  Bitmap->SaveToFile( RutaDelArchivo() );
  delete Bitmap;

  SendMessage(Handle, WM_SETREDRAW, false, 0);
  ListView_SetTextBkColor(Handle, CLR_NONE);
  ListView_DeleteAllItems(Handle);

  LVBKIMAGE lvbki;
  ZeroMemory(&lvbki, sizeof(LVBKIMAGE));
  lvbki.ulFlags = LVBKIF_SOURCE_URL | LVBKIF_STYLE_NORMAL;
  lvbki.pszImage = RutaDelArchivo().c_str();
  lvbki.xOffsetPercent = 50;
  lvbki.yOffsetPercent = 0;

  ListView_SetBkImage(Handle, &lvbki);
  SendMessage(Handle, WM_SETREDRAW, true, 0);
  InvalidateRect(Handle, NULL, true);
}

void __fastcall TFondoListView::LimpiaMensajeDeVacio(void)
{
  LVBKIMAGE lvbki;
  ZeroMemory(&lvbki, sizeof(LVBKIMAGE));
  ListView_SetBkImage(Handle, &lvbki);
  SendMessage(Handle, WM_SETREDRAW, true, 0);
  InvalidateRect(Handle, NULL, true);
}

void __fastcall TFondoListView::WMErase(TWMNoParams &Message)
{
    if ( ! ComponentState.Contains(csDesigning) )
        DefaultHandler(&Message);

    TListView::Dispatch(&Message);
}

void __fastcall TFondoListView::WMSetCursor(TWMNoParams &Message)
{
    if ( ! ComponentState.Contains(csDesigning) )
    {
        if ( FColumnasMovibles )
            TListView::Dispatch(&Message);
        else
          Message.Result = 1;
    }
}

void __fastcall TFondoListView::WMPaint(TWMNoParams &Message)
{
    if ( ! ComponentState.Contains(csDesigning) )
    {
        // If the listview is empty...
         if (
             (ListView_GetItemCount(Handle) <= 0) && //No tengo elementos
             FMostrarLeyendaVacio &&                 //Debo mostrar la leyenda que indica que está vacia la lista
             !FCadenaDeVacio.IsEmpty() &&            //Tiene algo que mostrar la leyenda
             (ViewStyle == vsReport)                 //El estilo es vsReport
            )
         {
             PAINTSTRUCT ps;
             HDC hdc = BeginPaint(Handle, &ps);

             // Find the listview dimensions
             RECT rc;
             ::GetClientRect(Handle, &rc);

             // Find the height of the header of the listview
             RECT rcHeader;
             HWND hHeader = ListView_GetHeader(Handle);
             Header_GetItemRect(hHeader, 0, &rcHeader);
             rc.top += rcHeader.bottom;
             rc.top += 10;

             ::SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
             SetBkMode(hdc, TRANSPARENT);
             SelectObject(hdc, (HFONT)GetStockObject(ANSI_VAR_FONT));

             DrawText(hdc, FCadenaDeVacio.c_str(), -1, &rc,DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_NOCLIP);
             EndPaint(Handle, &ps);
          }
    }

    TListView::Dispatch(&Message);
}




Saludos!
_________________
Quien hace una pregunta teme parecer un ignorante durante cinco minutos, quien no pregunta se mantiene ignorante toda la vida.
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email MSN Messenger
Mensaje    Asunto: Responder citando

Very Happy Gracias Buildero, seguiré con tu aportación.

Saludos !!!
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mostrar mensajes de anteriores:   
Cambiar a:  
No puedes publicar temas nuevos en este foro
No puedes responder a temas en este foro
No puedes editar tus mensajes en este foro
No puedes borrar tus mensajes en este foro
No puedes votar en las encuestas de este foro


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.