Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Win32 y mis amigos los botones con icono...

Iniciado por The_Dragon_Ladis, 10 de Septiembre de 2010, 02:27:21 AM

« anterior - próximo »

The_Dragon_Ladis

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:


Los tres cuadrados que se ven arriba deberían ser ser tres botones con forma de icono, que serían estos:


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 ^^

Juan Mellado

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 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

The_Dragon_Ladis

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 ^^






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.