Pues eso... tengo un problema para crear botones con iconos o bitmaps. He buscado en internet y cada uno lo hace de una manera distinta, pero el caso es que nunca consigo hacer que funcione.
Esta es la ventana de mi aplicación:
(http://i280.photobucket.com/albums/kk177/The_Dragon_Ladis/toolkyens.png)
Los tres cuadrados que se ven arriba deberían ser ser tres botones con forma de icono, que serían estos:
(http://i280.photobucket.com/albums/kk177/The_Dragon_Ladis/boton_soundgeons.png)(http://i280.photobucket.com/albums/kk177/The_Dragon_Ladis/boton_herocreator.png)(http://i280.photobucket.com/albums/kk177/The_Dragon_Ladis/boton_worldcraft.png)
El caso es que, como veis, no consigo hacer que se vean los iconos. He probador mil cosas distintas de mil webs, y ninguna termina de funcionar. He probado con archivos de recursos, cargando los iconos directamente con LoadIcon() y LoadImage(), e incluso definiendolos como una ventana más WS_CHILD y añadiendo el stilo BS_ICON, pero claro, según la documentación que hay en MSDN y he leído en Internet, después hay que hacer una llamada a SendMessage() con el tipo de mensaje BM_SETIMAGE, pero tampoco funciona. Llevo toda la noche dandole vueltas y no consigo hacer que funcione. No creo que sea tan difícil hacer un puñetero botón, así que debo estar comprendiendo mal algun concepto o equivocándome en alguna cosa tonta.
// Archivo de recursos
#include <Windows.h>
#include "ids.h"
IDI_TOOLKYENS ICON "images/icons/toolkyens.ico"
IDI_TOOLKYENS_SMALL ICON "images/icons/toolkyens_small.ico"
IDI_SOUNDGEONS ICON "images/icons/soundgeons.ico"
herocreator_ico ICON "images/icons/hero_creator.ico"
worldcraft_ico ICON "images/icons/worldcraft.ico"
IDB_BACKGROUND_INI BITMAP "images/backgrounds/ini.bmp"
//
// Aqui se definen los distintos identificadores
//
#define IDC_INIWND 100
//Iconos
#define IDI_TOOLKYENS 1001
#define IDI_TOOLKYENS_SMALL 1002
#define IDI_SOUNDGEONS 1003
//Fondos
#define IDB_BACKGROUND_INI 1100
//Botones
#define IDB_INIEXIT 1204
#define IDB_INISOUND 1205
#define IDB_INIHERO 1206
#define IDB_INIWORLD 1207
// Area de includes
#include "stdinc.h"
#include "iniWnd.h"
#define MAX_LOADSTRING 100
//Variables globales
HINSTANCE hInst;
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
HWND hIniWnd;
//Botones
HWND bExit;
HWND bSound;
HWND bHero;
HWND bWorld;
//Iconos
HICON iSound;
UINT horizontalSize;
UINT verticalSize;
//HDC
HDC hdc;
// Area de prototipos
LRESULT CALLBACK iniWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); //Procedimientos de la ventana de Inicio
// Main de la aplicacion
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR lpCmdLine, int nCmdShow)
{
//Variables
MSG msg;
WNDCLASSEX winClass;
LOGBRUSH background;
//Usamos hInstance como global
hInst = hInstance;
// Obtenemos los valores de la resolucion actual
hdc = GetDC(hIniWnd);
horizontalSize = GetDeviceCaps(hdc,HORZSIZE);
verticalSize = GetDeviceCaps(hdc,VERTSIZE);
//Cargamos la imagen de fondo
background.lbStyle = BS_PATTERN;
background.lbHatch = (long) LoadImage(hInstance,TEXT("images/backgrounds/ini.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
//Cargamos los iconos
iSound = (HICON)LoadIcon(hInst,MAKEINTRESOURCE(IDI_SOUNDGEONS));
//Definimos las propiedades de la ventana
winClass.hInstance = hInstance;
winClass.lpszClassName = "Inicio";
winClass.lpfnWndProc = iniWndProc;
winClass.style = CS_HREDRAW | CS_VREDRAW;
winClass.cbSize = sizeof(WNDCLASSEX);
winClass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TOOLKYENS));
winClass.hIconSm = LoadIcon(NULL, MAKEINTRESOURCE(IDI_TOOLKYENS_SMALL));
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
winClass.hbrBackground = CreateBrushIndirect(&background);
//Registramos la vetana
if(!RegisterClassEx(&winClass))
return 0;
//Creamos la Ventana
hIniWnd = IniWndCreate(hInstance,(UINT)horizontalSize/2,(UINT)verticalSize/2,900,400);
//Mostramos la ventana
ShowWindow(hIniWnd,SW_SHOWDEFAULT);
ShowWindow(bExit,SW_SHOWDEFAULT);
UpdateWindow(hIniWnd);
//Bucle de mensajes
while(GetMessage(&msg,NULL,0,0))
{
if(!IsDialogMessage(hIniWnd,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
//Declaraciones
LRESULT CALLBACK iniWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
//TODO: Codigo para los botones
bExit = CreateWindowEx(0,"BUTTON","Salir",
BS_DEFPUSHBUTTON |WS_CHILD | WS_VISIBLE | WS_TABSTOP,
830,370,
50,20,
hWnd,(HMENU)IDB_INIEXIT,hInst,NULL);
bSound = CreateWindowEx(0,"BUTTON","Soundgeon",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_ICON,
100,10,
100,100,
hWnd,(HMENU)IDB_INISOUND,hInst,NULL);
SendMessage(hIniWnd,BM_SETIMAGE,IMAGE_ICON,(LPARAM)iSound);
DrawIconEx(hdc,100,25,(HICON)iSound,100,100,0,NULL,DI_NORMAL);
bHero = CreateWindowEx(0,"BUTTON","Hero",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_ICON,
400,10,
100,100,
hWnd,(HMENU)IDB_INIHERO,hInst,NULL);
bWorld = CreateWindowEx(0,"BUTTON","Hero",
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_ICON,
700,10,
100,100,
hWnd,(HMENU)IDB_INIHERO,hInst,NULL);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
switch(wParam)
{
case IDB_INIEXIT:
PostQuitMessage(0);
break;
}
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return 0;
}
Si alguien puede hacerme un resumen o explicación rápida de como crear un botón de tipo icono de alguna de esas tres formas le estaria eternamente agradecido, porque ya estoy picado con el tema, y cuando empiezo a aprender algo puedo pasar horas y horas (mirad las horas que son y voy a acostarme porque tengo que estudiar, sino aquí podría quedarme hasta sacarlo...).
Un saludo amigos ^^
Un par de cosas:
1) El mensaje lo tienes que enviar al botón, no a la ventana principal
SendMessage(bSound,BM_SETIMAGE,IMAGE_ICON,(LPARAM)iSound);
2) La función LoadIcon (http://msdn.microsoft.com/en-us/library/ms648072%28VS.85%29.aspx) sólo carga iconos de tamaño y colores "estándares", si usas otros tienes que usar LoadImage:
iSound = (HICON)LoadImage(hInstance, TEXT("images/icons/soundgeons.ico"),IMAGE_ICON,0,0,LR_LOADFROMFILE);
Con esos dos cambios tu código funciona.
Saludos
Muchas gracias por las dos aclaraciones. Funciona como la seda. No encontraba ningún sitio donde lo explicara claramente, o quizás es que a esas horas yo no estaba muy lúcido para entenderlo... En cualquier caso muchas gracias ^^