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 

Form con skin (piel/caratula)

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Tips & Tricks
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Form con skin (piel/caratula) Responder citando

Una sencilla función que permite darle a nuestro form una nueva apariencia usando un skin o piel:
Código:
/// Da al form la forma del bitmap dado, usando como color
//    transparente el de la esquina inferior izquierda
void __fastcall BitmapToRgn(TForm* form, TImage* img)
{
    form->BorderStyle = bsNone;
    Graphics::TBitmap *bmp =
        dynamic_cast< Graphics::TBitmap* >( img->Picture->Bitmap );
    bmp->HandleType = bmDIB;
    bmp->PixelFormat = pf32bit;
    form->SetBounds( form->Left, form->Top, bmp->Width, bmp->Height );
    img->SetBounds( 0, 0, bmp->Width, bmp->Height );
    form->Brush->Bitmap = bmp;

    DWORD colorTransparente =
        static_cast< DWORD* >( bmp->ScanLine[bmp->Height-1] )[0];
    HRGN rgn = CreateRectRgn( 0, 0, form->Width, form->Height );
    HRGN rgnTemp = CreateRectRgn( 0, 0, form->Width, form->Height );
    CombineRgn( rgn, rgn, rgnTemp, RGN_DIFF );
    DeleteObject( rgnTemp );
    for (int y=0; y < form->Height; ++y)
    {
        DWORD* pixel = static_cast< DWORD* >( bmp->ScanLine[y] );
        int ancho = 0;

        for (int x=0; x <= form->Width; ++x)
        {
            if ( x != form->Width && pixel[x] != colorTransparente )
                ancho++;
            else
                if ( ancho > 0 )
                {
                    rgnTemp = CreateRectRgn( x - ancho, y, x, y + 1 );
                    CombineRgn( rgn, rgn, rgnTemp, RGN_OR );
                    DeleteObject( rgnTemp );
                    ancho = 0;
                }
        }
    }
    SetWindowRgn( form->Handle, rgn, true );
    DeleteObject( rgn );
}


y la manera de usarla, basta simplemente con añadir un TImage (Image1) al form, cargar una imagen en el y poner la siguiente línea en el constructor del Form:
Código:
  BitmapToRgn(this, Image1);


---

Luego si queremos que se pueda arrastrar el Form de una manera mas comoda pinchando en cualquier parte del mismo podemos añadir el siguiente código en el evento OnMouseDown del TImage:
Código:
  if ( mbLeft == Button )
  {
      ReleaseCapture();
      Perform( WM_SYSCOMMAND, 0xF012, 0 );
  }



Aquí tenéis un ejemplo compilado si queréis probarlo y el código fuente del mismo para el BCB6.


PD: la función teóricamente debería funcionar en todas las versiones de C++Builder, excepto la versión 1.

[Editado para corregir el enlace]
Volver arriba
Mensaje    Asunto: Form con skin (piel/caratula) Responder citando

Y aquí una versión que funciona en todas las versiones, aunque esta hecha especialmente para BCB1:

- Añadimos: #include <memory>

Código:
void BitmapToRgn(TForm *form, TImage *img)
{
    form->BorderStyle = bsNone;
    Graphics::TBitmap *bmp =
        dynamic_cast< Graphics::TBitmap* >( img->Picture->Bitmap );

    form->SetBounds( form->Left, form->Top, bmp->Width, bmp->Height );
    img->SetBounds( 0, 0, bmp->Width, bmp->Height );
    form->Brush->Bitmap = bmp;

    int tamanyoImagen = bmp->Width * bmp->Height * 4;
    std::auto_ptr< BITMAPINFO > lpbmi( new BITMAPINFO );
    std::auto_ptr< BYTE > bits( new BYTE[tamanyoImagen] );

    ZeroMemory( lpbmi.get(), sizeof(BITMAPINFO) );
    lpbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    lpbmi->bmiHeader.biWidth = bmp->Width;
    lpbmi->bmiHeader.biHeight = bmp->Height;
    lpbmi->bmiHeader.biPlanes = 1;
    lpbmi->bmiHeader.biBitCount = 32;
    lpbmi->bmiHeader.biCompression = BI_RGB;
    lpbmi->bmiHeader.biSizeImage = tamanyoImagen;

    GetDIBits( bmp->Canvas->Handle, bmp->Handle, 0, bmp->Height,
        bits.get(), lpbmi.get(), DIB_RGB_COLORS );

    DWORD colorTransparente = reinterpret_cast<DWORD*>
        ( bits.get() )[ bmp->Width * (bmp->Height-1) ];

    HRGN rgn = CreateRectRgn( 0, 0, form->Width, form->Height );
    HRGN rgnTemp = CreateRectRgn( 0, 0, form->Width, form->Height );
    CombineRgn( rgn, rgn, rgnTemp, RGN_DIFF );
    DeleteObject( rgnTemp );
    for (int y=0; y < bmp->Height; ++y)
    {
        DWORD *pixel = &reinterpret_cast<DWORD*>
            ( bits.get() )[ bmp->Width * (bmp->Height - 1 - y) ];
        int ancho = 0;

        for (int x=0; x <= bmp->Width; ++x)
        {
            if ( x != bmp->Width && pixel[x] != colorTransparente )
                ancho++;
            else
                if ( ancho > 0 )
                {
                    rgnTemp = CreateRectRgn( x - ancho, y, x, y + 1 );
                    CombineRgn( rgn, rgn, rgnTemp, RGN_OR );
                    DeleteObject( rgnTemp );
                    ancho = 0;
                }
        }
    }
    SetWindowRgn( form->Handle, rgn, true );
    DeleteObject( rgn );
}


Y aquí el ejemplo compilado con fuentes para BCB1.
(si pulsáis el botón derecho sobre el Form del ejemplo podéis cargar cualquier bitmap en tiempo de ejecución)

[Editado para corregir el enlace]
Volver arriba
Mensaje    Asunto: Form con skin (piel/caratula) Responder citando

hola, _Leo
he bajado el ejemplo para BCB 5, y el ejecutable funciona, pero al tratar de compilar el proyecto completo me sale este error "Unable to open file DBRTL.LIB", ¿que fichero trata de abrir?, ¿me puedes orientar? Gracias,
Volver arriba
Mensaje    Asunto: Form con skin (piel/caratula) Responder citando

El fichero de proyecto de arriba es para BCB6, así que directamente no vas a poder compilarlo en otra versión, y el de abajo es para BCB1.

Para otras versiones la cosa es muy fácil sin usar esos proyectos, solo tienes que seguir las instrucciones de arriba donde dice como usar la función.

Volver arriba
Mensaje    Asunto: Form con skin (piel/caratula) Responder citando

Hola.

He probado el código en una ventana nueva y sólo sale el botón en la barra de tareas. No sale la ventana ni nada de nada, ¿Qué estoy haciendo mal?

Gracias.

Volver arriba
Mensaje    Asunto: Form con skin (piel/caratula) Responder citando

Ceruléo,

Yo he probado este truco y funciona perfectamente.
Indicar que lo he probado en C++Builder 6 y WinXp; en lugar de teclear yo el código dejado por nuestro amigo _Leo, me he bajado el enlace al código proporcionado por este.

Saludos
_Willa

Volver arriba
Mensaje    Asunto: Otro tipo de skin más ambicioso Responder citando

Hola a todos. He probado el truco y está bastante bien. De todas formas, lo que yo quiero hacer es lo que hace el WinAmp. Quiero poder aplicar una piel a la ventana principal de la aplicación y que ésta tenga texturas (mármol, arena, arpillera, granito,...), así como los botones, de forma que sean temáticos (estándar de windows, familia Simpson, etc). ¿No sé si me estoy explicando? La idea es ofrecer una aspecto estándar por defecto y con el tiempo que bien el usuario o bien yo pueda personalizar el programa totalmente (fondo de ventana, colores, botones, etc, etc).
He estado buscando en internet y lo único que he conseguido es naufragar (no navegar, como habría sido deseable). Espero respuestas, pues es un asunto que me trae de cabeza hace largo tiempo.

Un saludo a todos y adelante.
"Si puede soñarse, puede hacerse"
Volver arriba
Mensaje    Asunto: Fallo de protección General Responder citando

He utilizado el código que muy amablemente nos ha proporcionado y es una maravilla, el problema es que estoy creando una aplicación en C++ builder 4 y con el código del skin para builder 1.0, este código lo pase a una unidad nueva, y en la forma principal incluyo la unidad y llamo la función desde el inicio de la forma; funciona pero luego de compliar o utilizar varias veces del programa aparece el siguiente mensaje de error:

PREDIN provocó un error de protección general
en el módulo DIBENG.DLL de 0003:00000fa9.
Registros:
EAX=000019d4 CS=03a7 EIP=00000fa9 EFLGS=00000202
EBX=000005b4 SS=2e07 ESP=00007790 EBP=000077ae
ECX=000002d8 DS=3366 ESI=000c46a0 FS=33cf
EDX=00000000 ES=20a7 EDI=003f6044 GS=209f
Bytes en CS:EIP:
,02x ,02x ,02x ,02x ,02x ,02x ,02x ,02x ,02x ,02x ,02x ,02x ,02x ,02x ,02x ,02x
Volcado de pila:
,08x ,08x ,08x ,08x ,08x ,08x ,08x ,08x ,08x ,08x ,08x ,08x ,08x ,08x ,08x ,08x

PREDIN es el nombre de la aplicación. Si no utilizo la función en el programa, este funciona correctamente, quiciera saber que es lo que sucede, y si _Leo, te queda un poco de tiempo dame una mano en este lio.
_________________
ssv
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Tengo un problema: Estoy usando un skin y quiero utilizar paneles para no tener que crear otras forms sino simplemente hacer visible o invisibles los paneles, pero no se como hacer los paneles transparentes o si no se puede, como hago para cambiarle el color del panel por uno que yo desee (diferente a los que las opciones me deja)?.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

no puedo bajar el ejemplo. alguien lo podria subir de nuevo por favor?

gracias
_________________
Jey U! I'm a Telecoman
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

SKIN.ZIP (211KB) [Para BCB6]
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: win98 24bits Responder citando

Hola:
El tema me parece interesante, he probado el primer codigo (de arriba) en BC6 y win98, trabaja bien cuando el bmp es de 8 bits de profundidad, pero cuando es de 24 aparece en la pantalla, el primer pixel de la imagen(que no deberia aparecer) y una especie de sombra, ambos del mismo color que el color transparente. En XP todo es correcto. Me gustaria que me ayuden. Gracias anticipadas.

Saludos
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola a todos,

Lo habéis probado con un botón? funcionaria?

Un abrazo.

Carlos
Volver arriba
Ver perfil de usuario Enviar mensaje privado Enviar email
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.