[C con Clase] Crear un Bitmap en tiempo de ejecucion y usarlo como fondo de un boton

Agustín Cota Reguero clom2002 en yahoo.es
Lun Mar 5 16:40:21 CET 2012


Hola, he seguido el ejemplo que me has puesto, que basicamente era lo que estaba haciendo yo, pero sigue sin hacer nada. Solo veo una diferencia y es que tu lo haces en la gestión del mensage WM_CREATE y yo lo hago en el WM_INITDIALOG ya que el boton está en en un dialogo que abro con CreateDialogParam en unas ocasiones y en otras con DialogBoxParam (aunque esta vez probe con uno abierto con la primera de las dos). Te voy a poner el codigo que he usado a ver si ves algo que se me escape.

#include "includes.h"

BOOL CALLBACK WProcPuntoProp(HWND hdwnd,UINT message, WPARAM wParam, LPARAM lParam)
{
    static HINSTANCE hInstance;
    HDC hDC;
    PAINTSTRUCT ps;
    RECT clien;
    HBRUSH hbrush;
    HPEN hpen;
    static HDC hDcmem;
    static PointProp* vistaprevia;
    static PointProp* Param;
    static PointProp Param_antiguo;
    static HBITMAP hBitmap;
    static HDC hCompatibleDC;
    RECT re = {0, 0, 63, 19};
    static HBITMAP hBitmap1;

    switch(message){

        case WM_INITDIALOG:
            hInstance = ((LPCREATESTRUCT)lParam)->hInstance;

            Param = (PointProp*)lParam;
            Param_antiguo = *Param;

            vistaprevia = new PointProp(31,Param->GetTipo(),Param->GetColor(), Param->GetRelleno());

            if(Param->GetRelleno() == true)
            {
                CheckDlgButton(hdwnd,IDC_CHECKBOX_RELLENO,BST_CHECKED);
            }

            GetClientRect(hdwnd,&clien);

            hDC = GetDC(hdwnd);
            hDcmem = CreateCompatibleDC(hDC);
            hBitmap = CreateCompatibleBitmap(hDC,clien.right,clien.bottom);
            hCompatibleDC = CreateCompatibleDC(hDC);
            hBitmap1 = CreateCompatibleBitmap(hDC, 64, 20);
            SelectObject(hCompatibleDC, hBitmap1);
            // Dibujar el botón:
            FillRect(hCompatibleDC, &re, (HBRUSH)GetStockObject(WHITE_BRUSH ));
            FrameRect(hCompatibleDC, &re, (HBRUSH)GetStockObject(GRAY_BRUSH ));
            Ellipse(hCompatibleDC, 20, 2, 44, 18);
            ReleaseDC(hdwnd,hDC);
            SelectObject(hDcmem,hBitmap);
            hpen = CreatePen(PS_SOLID,1,vistaprevia->GetColor());
            SelectObject(hDcmem,hpen);
            PatBlt(hDcmem,0,0,clien.right,clien.bottom,PATCOPY);
            SendDlgItemMessage(hdwnd,IDC_BUTTON1_RESPUNTOPROP, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBitmap);
            SendDlgItemMessage(hdwnd, IDC_COMBO_TAM,CB_ADDSTRING, 0, (LPARAM)"1");
            SendDlgItemMessage(hdwnd, IDC_COMBO_TAM,CB_ADDSTRING, 0, (LPARAM)"3");
            SendDlgItemMessage(hdwnd, IDC_COMBO_TAM,CB_ADDSTRING, 0, (LPARAM)"5");
            SendDlgItemMessage(hdwnd, IDC_COMBO_TAM,CB_ADDSTRING, 0, (LPARAM)"7");
            SendDlgItemMessage(hdwnd, IDC_COMBO_TAM,CB_ADDSTRING, 0, (LPARAM)"9");
            SendDlgItemMessage(hdwnd, IDC_COMBO_TAM,CB_ADDSTRING, 0, (LPARAM)"11");
            SendDlgItemMessage(hdwnd, IDC_COMBO_TAM,CB_ADDSTRING, 0, (LPARAM)"15");
            SendDlgItemMessage(hdwnd, IDC_COMBO_TAM,CB_ADDSTRING, 0, (LPARAM)"21");
            SendDlgItemMessage(hdwnd, IDC_COMBO_TAM, CB_SELECTSTRING,(WPARAM)-1, (LPARAM)"7");
            break;

        case WM_SYSCOMMAND:
            switch(wParam)
            {
                case SC_CLOSE:
                    *Param = Param_antiguo;
                    EndDialog(hdwnd,-1);
                    break;
            }
            break;
        case WM_COMMAND:
           switch(LOWORD(wParam)) {
              case IDCANCEL_RESPUNTOPROP:
                *Param = Param_antiguo;
                 EndDialog(hdwnd, FALSE);
                 break;

              case IDC_CHECKBOX_RELLENO:
                if(IsDlgButtonChecked(hdwnd,IDC_CHECKBOX_RELLENO)==BST_CHECKED)
                    {
                        vistaprevia->SetRelleno(true);
                    }else{
                        vistaprevia->SetRelleno(false);
                    }
                    InvalidateRect(hdwnd,NULL,TRUE);

              break;

              case IDOK_RESPUNTOPROP:
                 InvalidateRect(hdwnd,NULL,TRUE);
                 break;
           }
            break;

        case WM_PAINT:
            hDC = BeginPaint(hdwnd,&ps);
            GetClientRect(hdwnd,&clien);
            hbrush = CreateSolidBrush(RGB(240,240,240));
            SelectObject(hDcmem,hbrush);
            PatBlt(hDcmem,0,0,clien.right,clien.bottom,PATCOPY);
            vistaprevia->Figura(hDcmem,45,65);
            BitBlt(hDC,0,0,clien.right,clien.bottom,hDcmem,0,0,SRCCOPY);
            EndPaint(hdwnd,&ps);
            break;

            return TRUE;
    }
    return FALSE;
}


/////////////////////////////////
El fichero de recursos es 

/////////////////////////////////

LANGUAGE 0, SUBLANG_NEUTRAL
IDD_RESPUNTOPROP DIALOG 0, 0, 221, 121
STYLE DS_3DLOOK | DS_ABSALIGN | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_MINIMIZEBOX
CAPTION "Detalles de Puntos"
FONT 8, "Ms Shell Dlg"
{
    DEFPUSHBUTTON   "Ok", IDOK_RESPUNTOPROP, 8, 99, 50, 14
    PUSHBUTTON      "Cancelar", IDCANCEL_RESPUNTOPROP, 71, 99, 50, 14
    LTEXT           "Vista Previa", IDC_STATIC_RESPUNTOPROP, 12, 16, 38, 8, SS_LEFT
    AUTOCHECKBOX    "Relleno", IDC_CHECKBOX_RELLENO, 12, 65, 50, 10
    LTEXT           "Tamaño", IDC_STATIC_RESPUNTOPROP, 103, 29, 27, 8, SS_LEFT
    LTEXT           "Símbolo", IDC_STATIC_RESPUNTOPROP, 104, 46, 26, 8, SS_LEFT
    COMBOBOX        IDC_COMBO_TAM, 135, 25, 39, 130, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_TABSTOP
    COMBOBOX        IDC_COMBO2_RESPUNTOPROP, 135, 45, 41, 12, CBS_DROPDOWN | CBS_HASSTRINGS
    LTEXT           "Color", IDC_STATIC_RESPUNTOPROP, 104, 68, 17, 8, SS_LEFT
    PUSHBUTTON      "Negro", IDC_BUTTON1_RESPUNTOPROP, 125, 65, 85, 15, BS_BITMAP | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP
}




________________________________
 De: Salvador Pozo <salvador en conclase.net>
Para: cconclase en listas.conclase.net 
Enviado: Domingo 4 de marzo de 2012 14:53
Asunto: Re: [C con Clase] Crear un Bitmap en tiempo de ejecucion y usarlo como fondo de un boton
 
El pasado 2012-03-03 13:54:01, clom escribió:

c> ...
c> Alguien tiene idea de como puedo hacer lo que quiero o por que no funciona lo que estoy intnetando? 

Hola:

Sólo se me ocurre que estés haciendo algo mal, porque yo lo he intentado y si me funciona (aunque reconozco que me ha costado un poco :))

Sigue un pequeño ejemplo:

----8<------
    HWND hctrl;
    // Declaraciones necesarias:
    static HDC hCompatibleDC;
    RECT re = {0, 0, 63, 19};
    HDC hDC;

    switch (msg)                  /* manipulador del mensaje */
    {
        case WM_CREATE:
           hInstance = ((LPCREATESTRUCT)lParam)->hInstance;
           /* Insertar controles */
           hctrl = CreateWindowEx(
              0,
              "BUTTON",        /* Nombre de la clase */
              "Bitmap",        /* Texto del título */
              BS_BITMAP | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 
              160, 69,         /* Posición */
              95, 24,          /* Tamaño */
              hwnd,            /* Ventana padre */
              (HMENU)ID_BOTON5,/* Identificador del control */
              hInstance,       /* Instancia */
              NULL);           /* Sin datos de creación de ventana */

           // Parte del código para crear un bitmap
           hDC=GetDC(hwnd);
           hCompatibleDC = CreateCompatibleDC(hDC);
           hBitmap = CreateCompatibleBitmap(hDC, 64, 20);
           SelectObject(hCompatibleDC, hBitmap);
           // Dibujar el botón:
           FillRect(hCompatibleDC, &re, (HBRUSH)GetStockObject(WHITE_BRUSH ));
           FrameRect(hCompatibleDC, &re, (HBRUSH)GetStockObject(GRAY_BRUSH ));
           Ellipse(hCompatibleDC, 20, 2, 44, 18);
           // Liberar los DCs
           ReleaseDC(0, hDC);
           DeleteDC(hCompatibleDC);

           SendMessage(hctrl, BM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)hBitmap);
           return 0;
...
        case WM_DESTROY:
           // Al destruir el diálogo destruir el bitmap:
           DeleteObject(hBitmap);
...
----8<------

Para modificar el bitmap deberás volver a crear un DC compatible, seleccionar el bitmap en él, volver a dibujarlo y liberar el DC.

Supongo que habrá algunas diferencias entre este ejemplo y tu código.

Suerte, hasta pronto.

-- 
Salvador Pozo (Administrador)
mailto:salvador en conclase.net
_______________________________________________
Lista de correo Cconclase Cconclase en listas.conclase.net
http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20120305/b39234ea/attachment.html>


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