Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Alien-Z en 16 Septiembre 2011, 21:32 pm



Título: Iconos en botones (Win API)
Publicado por: Alien-Z en 16 Septiembre 2011, 21:32 pm
Buenas:

He llegado a un punto en el cual, para mejorar la interfaz de un programa, necesito ponerle iconos a los botones, fondos a los edit o static, etc. He encontrado por internet un par de cosas como la función CreateIcon (http://msdn.microsoft.com/en-us/library/ms648059%28v=vs.85%29.aspx) (que me ha dado 500 errores) y esta otra forma:

Código
  1. #include <windows.h>
  2.  
  3. enum {ID_BOTON1};
  4.  
  5. /*  Declare Windows procedure  */
  6. LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
  7.  
  8. /*  Make the class name into a global variable  */
  9. char szClassName[ ] = "CodeBlocksWindowsApp";
  10.  
  11. HINSTANCE estancia;
  12. HICON hIcon1;
  13. HWND boton1;
  14.  
  15. int WINAPI WinMain (HINSTANCE hThisInstance,
  16.                     HINSTANCE hPrevInstance,
  17.                     LPSTR lpszArgument,
  18.                     int nCmdShow)
  19. {
  20.    HWND hwnd;               /* This is the handle for our window */
  21.    MSG messages;            /* Here messages to the application are saved */
  22.    WNDCLASSEX wincl;        /* Data structure for the windowclass */
  23.  
  24.    estancia = hThisInstance;
  25.  
  26.    /* The Window structure */
  27.    wincl.hInstance = hThisInstance;
  28.    wincl.lpszClassName = szClassName;
  29.    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
  30.    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
  31.    wincl.cbSize = sizeof (WNDCLASSEX);
  32.  
  33.    /* Use default icon and mouse-pointer */
  34.    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  35.    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
  36.    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
  37.  
  38.  
  39.  
  40.    hIcon1 = LoadIcon (estancia, "RAIZ");
  41.  
  42.  
  43.  
  44.    wincl.lpszMenuName = NULL;                 /* No menu */
  45.    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
  46.    wincl.cbWndExtra = 0;                      /* structure or the window instance */
  47.    /* Use Windows's default colour as the background of the window */
  48.    wincl.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
  49.  
  50.    /* Register the window class, and if it fails quit the program */
  51.    if (!RegisterClassEx (&wincl))
  52.        return 0;
  53.  
  54.    /* The class is registered, let's create the program*/
  55.    hwnd = CreateWindowEx (
  56.           0,                   /* Extended possibilites for variation */
  57.           szClassName,         /* Classname */
  58.           "Code::Blocks Template Windows App",       /* Title Text */
  59.           WS_OVERLAPPEDWINDOW, /* default window */
  60.           CW_USEDEFAULT,       /* Windows decides the position */
  61.           CW_USEDEFAULT,       /* where the window ends up on the screen */
  62.           544,                 /* The programs width */
  63.           375,                 /* and height in pixels */
  64.           HWND_DESKTOP,        /* The window is a child-window to desktop */
  65.           NULL,                /* No menu */
  66.           hThisInstance,       /* Program Instance handler */
  67.           NULL                 /* No Window Creation data */
  68.           );
  69.  
  70.    /* Make the window visible on the screen */
  71.    ShowWindow (hwnd, nCmdShow);
  72.  
  73.    /* Run the message loop. It will run until GetMessage() returns 0 */
  74.    while (GetMessage (&messages, NULL, 0, 0))
  75.    {
  76.        /* Translate virtual-key messages into character messages */
  77.        TranslateMessage(&messages);
  78.        /* Send message to WindowProcedure */
  79.        DispatchMessage(&messages);
  80.    }
  81.  
  82.    /* The program return-value is 0 - The value that PostQuitMessage() gave */
  83.    return messages.wParam;
  84. }
  85.  
  86.  
  87. /*  This function is called by the Windows function DispatchMessage()  */
  88.  
  89. LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  90. {
  91.    switch (message)                  /* handle the messages */
  92.    {
  93.        case WM_CREATE:
  94.        {
  95.            boton1 = CreateWindow ("Button", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP, 20, 90, 40, 25, hwnd, (HMENU) ID_BOTON1, estancia, 0);
  96.            SendMessage(boton1, WM_SETICON, (WPARAM) hIcon1, true);
  97.            break;
  98.        }
  99.        case WM_DESTROY:
  100.            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
  101.            break;
  102.        default:                      /* for messages that we don't deal with */
  103.            return DefWindowProc (hwnd, message, wParam, lParam);
  104.    }
  105.  
  106.    return 0;
  107. }
  108.  

Archivo de recursos:

Código
  1. RAIZ ICON "raiz.ico"

No me da ningún error y el programa se compila y ejecuta correctamente pero no imprime el icono.


Título: Re: Iconos en botones (Win API)
Publicado por: Queta en 16 Septiembre 2011, 22:00 pm
http://www.codeproject.com/KB/buttons/nativewin32xpthemes.aspx (http://www.codeproject.com/KB/buttons/nativewin32xpthemes.aspx)


Título: Re: Iconos en botones (Win API)
Publicado por: Alien-Z en 16 Septiembre 2011, 22:44 pm
http://www.codeproject.com/KB/buttons/nativewin32xpthemes.aspx (http://www.codeproject.com/KB/buttons/nativewin32xpthemes.aspx)

Gracias pero no entiendo muy bien el code; no sé si es que usa una metodología de programación diferente o es que está programado teniendo presente formas de sintaxis más avanzadas, pero apenas comprendo el "main.cpp".

¿No hay ninguna manera menos compleja como la que he posteado?, ¿dónde podría estar el fallo en mi code?, reitero en que hace realtivamente poco que me puse a explorar la API de Windows y aunque sepa usar funciones muy diversas tampo soy un experto.

Saludos.


Título: Re: Iconos en botones (Win API)
Publicado por: Queta en 16 Septiembre 2011, 23:12 pm
¿No entiendes el main.cpp? Tu código me parece que es una plantilla, ¿lo entiendes?


Título: Re: Iconos en botones (Win API)
Publicado por: Alien-Z en 16 Septiembre 2011, 23:27 pm
¿No entiendes el main.cpp? Tu código me parece que es una plantilla, ¿lo entiendes?

Lo que está comentado en inglés es lo que da como plantilla Code::Blocks, lógicamente no voy a escribir lo básico para programar una ventana cada vez que cree un proyecto para probar funciones y hacer ensayos, en ese caso el código que da Code::Blocks al crear un nuevo proyecto viene a la perfección.

No, no entiendo el main.cpp que va con el source del ejemplo que me has pasado por la sencilla razón de que al ser principiante en Win API la única forma que he visto para crear ventanas es la que viene con Code::Blocks y en los ejemplos básicos de guías y foros; si empieza a crear 39898 archivos para hacer una simple ventana lo normal al ser un principiante, noob o como quieras llamarlo es que no me entere.

(http://img257.imageshack.us/img257/3461/dibujofcw.jpg)

¿Tantos archivos para añadirle un ICONO a un BOTÓN?.


Título: Re: Iconos en botones (Win API)
Publicado por: Queta en 16 Septiembre 2011, 23:34 pm
Pues antes de hacer botones con iconos deberías aprender cómo realmente funciona y se crea una ventana.

http://msdn.microsoft.com/en-us/library/bb384843.aspx (http://msdn.microsoft.com/en-us/library/bb384843.aspx)
http://winapi.conclase.net/ (http://winapi.conclase.net/)


Título: Re: Iconos en botones (Win API)
Publicado por: Alien-Z en 16 Septiembre 2011, 23:49 pm
Pues antes de hacer botones con iconos deberías aprender cómo realmente funciona y se crea una ventana.

http://msdn.microsoft.com/en-us/library/bb384843.aspx (http://msdn.microsoft.com/en-us/library/bb384843.aspx)
http://winapi.conclase.net/ (http://winapi.conclase.net/)

Gracias por tu tiempo, pero no estoy interesando en volver a dar lo que ya he visto, sé cómo crear una ventana; lo que no comprendo son las funciones que hay en el "main.cpp" de tu ejemplo que no tienen nada que ver con la ventana en si, sino que llaman a funciones de los otros 8 archivos dificultando su comprensión.

La idea es avanzar poco a poco no verme 15 funciones nuevas de golpe repartidas entre 8 archivos.

No te molestes, miraré por otro lado. Suerte.


Título: Re: Iconos en botones (Win API)
Publicado por: naderST en 17 Septiembre 2011, 05:32 am
TODO está en la MSDN pero te ayudo con lo siguiente para ponerle un icono a un botón tienes que usar el mensaje BM_SETIMAGE:

Código
  1. SendMessage(boton1, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM)hIcon1);
  2.  
  3.  

http://msdn.microsoft.com/en-us/library/bb761822(v=vs.85).aspx (http://msdn.microsoft.com/en-us/library/bb761822(v=vs.85).aspx)


Título: Re: Iconos en botones (Win API)
Publicado por: Alien-Z en 17 Septiembre 2011, 11:54 am
TODO está en la MSDN pero te ayudo con lo siguiente para ponerle un icono a un botón tienes que usar el mensaje BM_SETIMAGE:

Código
  1. SendMessage(boton1, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM)hIcon1);
  2.  
  3.  

http://msdn.microsoft.com/en-us/library/bb761822(v=vs.85).aspx (http://msdn.microsoft.com/en-us/library/bb761822(v=vs.85).aspx)

Muchas gracias, era exactamente lo que buscaba.

Aclaro un pequeño punto que no sale en la MSDN por si alguien ojea este tema: BM_SETIMAGE no funciona en Windows XP sino añades BS_ICON o BS_BITMAP al definir el botón/edit/static/etcétera. Un ejemplo:

Código
  1. case WM_CREATE:
  2. {
  3. //Esto funcionaría en W7 pero no en XP
  4. boton1 = CreateWindow ("Button", NULL, WS_CHILD | WS_VISIBLE | WS_TABSTOP, 20, 90, 40, 25, hwnd, (HMENU) ID_BOTON1, estancia, 0);
  5. SendMessage(boton1, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM)hIcon1);
  6. break;
  7. }

Código
  1. case WM_CREATE:
  2. {
  3. //Ahora lo reconoce el Windows XP
  4. boton1 = CreateWindow ("Button", NULL, BS_ICON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 20, 90, 40, 25, hwnd, (HMENU) ID_BOTON1, estancia, 0);
  5. SendMessage(boton1, BM_SETIMAGE, (WPARAM) IMAGE_ICON, (LPARAM)hIcon1);
  6. break;
  7. }

En caso de que sea una imagen en vez de BS_ICON hay que usar BS_BITMAP.

Saludos.