(1706 palabras totales en este texto) (26573 Lecturas) 
Ejemplo de programación en Symbian con C++
Aquí os presento un documento de cómo hacer un ejemplo sencillo de una
aplicación Symbian OS para vuestro móvil. Para este ejemplo he usado el
SDK 1.0 Series 60,
y el compilador Visual C++ 6.0 de Microsoft. En el tutorial sólo voy a centrarme
en la programación en si, por tanto doy por hecho que tenéis el SDK bien
instalado, así como el wizard para VC++ que os viene en el propio SDK.
Vamos allá.
El primer paso es crear nuestro proyecto. Lanzamos el wizard de Series 60 que
tenemos para el VC++ y nos encontraremos con la siguiente ventana:

Aquí elegimos "EIKON Control", con lo que el wizard nos va a crear
un "control" por defecto donde se va a desarrollar nuestra aplicación.
El
Unicode UID no lo toquéis, es un número que se asigna de forma aleatoria
al programa,
ya que cada programa Symbian que sea crea lleva un identificador único.
Le damos a aceptar y en la siguiente ventana podemos ver las clases que el
wizard nos va a crear en nuestro proyecto. Le damos a finish y si todo ha ido
bien ya tenemos nuestro proyecto preparado y listo para ponernos manos a la
obra.
El control que nos ha creado el wizard es la clase CTutoContainer, nos la crea
con cierta "basura", ya que es para un ejemplo así que mejor
limpiarla
un poco. Podéis consultar el archivo CTutoContainer.h para ver como queda la
clase después de quitar métodos que no vamos a utilizar.
Nuestro ejemplo va a consistir en un objeto que moveremos por la pantalla del
móvil mediante el joystick o el pad. Para ello necesitamos que nuestro control
(CTutoContainer) sea capaz de responder a eventos de teclado. Esto se consigue
sobrecargando el siguiente método de la clase CCoeControl (esta es la clase
base de nuestro CTutoContainer) :
TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType);
Este método será llamado en nuestro control cada vez que se pulse
una tecla. El primer parámetro es un TKeyEvent, y nos da información
sobre la pulsación que ha provocado la llamada del método. El segundo parámetro
de tipo
TEventCode nos permite saber si el evento está asociado a la pulsación de una
tecla (EEventKeyDown) o que se ha soltado una tecla (EEventKeyUp).
Es decir
por cada pulsación de tecla, se reciben al menos dos llamadas a esta función, una para la
pulsación, y otra cuando se suelta. (También se suele producir
otra llamada intermedia, EEventKey, pero no nos interesa ahora mismo).
Lo único que vamos a hacer en el procesamiento de las teclas,
es modificar la posición del objeto que queremos pintar. Para llevar esta posición
vamos a añadir un TPoint a la clase CTutoContainer, que va a consistir
en las coordenadas x e y donde estamos pintando actualmente nuestro
objeto. A
esta variable, en adelante la llamaremos "pos". Volviendo al método
del teclado, lo que queremos es que se modifiquen estas coordenadas en función de la
pulsación. Lo haremos del siguiente modo:
TKeyResponse CTutoContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode
aType){
if(aType != EEventKeyDown)
return EKeyWasNotConsumed;
switch(aKeyEvent.iScanCode){
case EStdKeyUpArrow:
pos.iY--;
break;
case EStdKeyRightArrow:
pos.iX++;
break;
case EStdKeyDownArrow:
pos.iY++;
break;
case EStdKeyLeftArrow:
pos.iX--;
break;
default:
return EKeyWasNotConsumed;
}
DrawNow();
return EKeyWasConsumed;
}
Con el primer if lo que conseguimos es simplemente gestionar las
pulsaciones de tecla, no los demás eventos. Después obtenemos el código asociado
a la tecla pulsada con el miembro iScanCode de nuestro TKeyEvent.
En función de esa tecla movemos la posición de pintado. Hay que tener en cuenta, que este
método si procesa la tecla debe devolver EKeyWasConsumed para indicar al sistema
que ya ha procesado la tecla y que no tiene que pasarla a ningún control más
existente. En caso contrario, si no procesamos la tecla porque no nos interesa,
debemos devolver EKeyWasNotConsumed, para informar de la situación
opuesta. Pero aún nos queda algo por añadir, si hemos movido la posición
de nuestro
objeto, esto no va a ser reflejado en el display a no ser que forcemos al sistema
a redibujar nuestro control con el objeto en la nueva posición. Para esto debemos
añadir la llamada al método DrawNow() de CCoeControl justo
después de
procesar la tecla.
Lo siguiente que vamos a hacer es cargar la imagen con la que
queremos pintar el objeto. La clase que se utiliza en Symbian para la representación
de un "bitmap" es CFbsBitmap. Por eso, vamos a incluir otro miembro
dentro de nuestro control, una variable de la clase CFbsBitmap llamada
bitmap. Hacer
esto requiere una serie de cosas adicionales. Para empezar, en el fichero TutoContainer.cpp
debemos hacer el #include que es donde está la
declaración de
esta clase. Pero debido a que la implementación de esta clase está en una .dll
que no se enlaza por defecto con el wizard, debemos añadir esta .dll al
proyecto. Lo vamos a hacer del siguiente modo. Abrimos el fichero .mmp del
proyecto, y veréis que hay una serie de sentencias LIBRARY, aquí tenemos que añadir
lo siguiente:
LIBRARY fbscli.lib
Con esto conseguimos tener enlazada la clase que queríaamos y podemos
continuar. Lo siguiente que tenemos que hacer es añadir la imagen que
queremos visualizar en nuestro proyecto. Vamos a usar la imagen "bitmap.bmp"
que tenemos en el directorio data del proyecto. Para usar esta imagen en nuestro
proyecto tenemos que crear un fichero .mbm (Multi Bitmap file) que la contenga
y asociarlo al proyecto. Esto lo hacemos de nuevo desde el fichero .mmp.
Tenemos
que añadir lo siguiente:
START BITMAP tuto.mbm
TARGETPATH ........winscsystemapps uto
HEADER
SOURCEPATH ..data
SOURCE c12 bitmap.bmp
END
Vamos a explicarlo con más detalle:
- START BITMAP define cual va a ser el nombre del fichero .mbm que vamos a
crear, aquí he elegido tuto.mbm
- TARGETPATH nos dice dónde va a ser creado el fichero. Le hemos puesto la
ruta del directorio de la aplicación.
- HEADER indica que las cabeceras de los bitmaps se incluyen en el propio
bitmap
- SOURCEPATH es el directorio donde se buscaran las imágenes que formaran
el .mbm
- SOURCE Aquí decimos qué bitmaps se van a incluir dentro del .mbm.
c12 quiere
decir que la imagen se guardara en formato de 12 bits de color, y a
continuación
ponemos el nombre de nuestra imagen, bitmap.bmp
Ahora que tenemos la imagen creada dentro del proyecto, tenemos
que asociarlo a nuestra variable bitmap. Esto lo hacemos en la fase de construcción
de nuestro control, esto es, en el método ConstructL. Ponemos lo siguiente:
bitmap = CEikonEnv::Static()->CreateBitmapL(_L("c:systemapps uto uto.mbm"),0);
La explicación es la siguiente. El método estático CreateBitmapL toma como primer
parámetro la ruta del fichero .mbm del que queremos coger
la imagen, y el segundo parámetro es un índice dentro del fichero .mbm para
seleccionar la imagen que queremos cargar, en nuestro caso, como sólo hay una,
pues el índice es cero. El método nos retorna un puntero que asignamos a nuestra
variable bitmap. También hay que acordarse de hacer el correspondiente delete
del puntero en el destructor de CTutoContainer.
Pues bien, una vez cargada la imagen, y hecho el manejo de la posición de dibujo, lo
único que nos queda es pintar la imagen!! Las labores
de pintado de un control se llevan a cabo en el siguiente método de CCoeControl
que hemos de sobrecargar:
void Draw(const TRect& aRect) const;
Este método es llamado por el sistema cada vez que necesita pintar
nuestro control o parte de él, es decir, no suele ser llamado manualmente. En
este método hacemos lo siguiente:
void CTutoContainer::Draw(const TRect& aRect) const{
CWindowGc& gc = SystemGc();
gc.Clear();
gc.BitBlt(pos,bitmap);
}
Vamos a explicar lo que hacemos en este método. Con la llamada a SystemGc()
el contexto grafico que necesitamos para dibujar en pantalla. Lo siguiente que
hacemos es borrar todo lo que haya en pantalla, si no hiciéramos esto el objeto
iría "dejando estela" ya que no se borraría la pintada anterior. La
llamada a BitBlt es una abreviatura de "Bit Block Transfer" y como
su propio nombre indica, transfiere un bloque de bits (bitmap). Este bitmap
es lo que le pasamos como segundo parámetro, es decir nuestro CFbsBitmap que
habíamos creado antes. El primer parámetro es un TPoint, que indica las coordenadas
(x,y) donde se dibujará el bitmap, y aquí utilizamos nuestra variable pos que
es donde llevamos la posición de nuestro objeto.

Pues ya tenemos a nuestro dibujo moviéndose por la pantalla a las ordenes de
nuestro joystick!
Hay que resaltar de que esto no es un ejemplo de cómo se deben hacer del todo
bien las cosas, es un simple ejemplo didáctico. Con esto quiero decir por ejemplo,
que lo suyo seria tener una clase Sprite, con su imagen y posición y
demás aspectos.
Aquí podéis encontrar todos los ficheros que conforman
este ejemplo para que os sirvan de guía.
Espero que saquéis algo en claro de todo este texto. Dudas, opiniones, sugerencias,
y por supuesto criticas a gdesantos@bigfoot.com
También me podéis encontrar a mí y a otros desarrolladores de Symbian en el
canal #symbian de irc-hispano.
Autor:
Gustavo de Santos García
OverMind
Si has encontrado algo incorrecto o con lo que no estás de
acuerdo puedes ponerte en contacto con el autor o con Todo Symbian. Tu contribución será bienvenida.
Opina en el foro
sobre este reportaje.
¿Te
ha sido de utilidad? Vota por Todo Symbian en GSMspain TOPSites, tan sólo te
tomará un minuto. |