C#: detectando cuando una ventana WPF es minimizada

Tanto si utilizamos un form como si utilizamos una ventana WPF la propiedad que tenemos que comprobar es WindowState. La diferencia viene en que un form el evento que se dispara al minimizar es _Resize y en una ventana WPF es _StateChanged.

En mi código quiero minimizar el form que contiene la barra de herramientas si minimizo la ventana principal, e igualmente quiero devolverla a su posición si maximizo o devuelvo a su posición a la principal.

Capture

Fuente: StackOverflow

C#: detectando cuando una ventana WPF es minimizada

Visual C#: obtener resolución del escritorio

La clase System.Windows.Forms.Screen nos ofrece la propiedad Screen.AllScreens que nos da acceso a una colección de todas las pantallas detectadas por el sistema. La propiedad Screen.PrimaryScreen nos da acceso a la pantalla principal.

La resolución la obtenemos de la propiedad Bounds del objeto:

Rectangle resolution = Screen.PrimaryScreen.Bounds;

La propiedad Screen.PrimaryScreen.WorkingArea nos ofrece el tamaño del área de trabajo.

Obtenido de stack overflow.

Visual C#: obtener resolución del escritorio

¿Cuándo usar el registro de Windows en vez de ficheros?

A la hora de crear una aplicación, a menudo nos vamos a encontrar que necesitamos reutilizar datos de una sesión anterior, una característica que dentro del mundo de la informática se conoce como persistencia. Lo más habitual es trabajar con ficheros, ya que al fin y al cabo el disco duro nos ofrece exactamente eso, la capacidad de almacenar datos que sobrevivan no sólo a la finalización de las aplicaciones sino al apagado del ordenador.

Debemos tener en cuenta, sin embargo, que Windows nos ofrece una base de datos integrada en el sistema que también nos permite almacenar información pero con algunas ventajas:

  • Cada usuario tiene su propio registro. Esto implica que si queremos almacenar datos por usuario, no tenemos que crear nosotros mismos un sistema de usuarios, de permisos ni de absolutamente nada.
  • Ofrece una interfaz de clave/registro que no necesita ser parseada. Podemos almacenar datos arbitrarios en el registro sin tener que andar insertando separadores.
  • El sistema operativo nos ofrece una interfaz gráfica de gestión. Utilizando regedit podemos crear claves, modificarlas y borrarlas.
  • El registro es gestionado por el kernel. Si tu aplicación se cuelga o tiene cualquier problema, los cambios que hayas hecho en el registro seguirán estando ahí. Si el sistema entero se cuelga, es responsabilidad de Windows asegurarse de que el registro es válido.
  • El registro es seguro para hilos. Varios hilos o procesos pueden estar accediendo a la misma clave y podremos asegurar que las modificaciones son atómicas.

Por supuesto, el registro presenta también desventajas:

  • No vale para una gran cantidad de datos. El registro no está diseñado para guardar ese nivel de dos gigas que has creado, sino para almacenar unos pocos parámetros de configuración.
  • Dificultad de manejo. Al ser un enorme bloque de bytes, es difícil de gestionar y de crear backups.
  • Escasa portabilidad. Si me quiero llevar mi aplicación a otro escritorio, no me queda otro remedio que andar exportando claves, frente a la opción de tener un fichero de configuración que pertenezca a los ficheros de la propia aplicación.

Si utilizamos C#, la clase Registry (que podemos encontrar en el namespace Microsoft.Win32) nos facilita operaciones para trabajar con él.

Sacado de éste enlace.

¿Cuándo usar el registro de Windows en vez de ficheros?

Configure NetBeans / SDL 2.0.3 / MinGW

I will reproduce here the steps to configure SDL2.0.3 library for Netbeans with MinGW in an intel i7 (x86_64 architecture) and Windows 7 64 bit SP1. I will assume you have downloaded already the neccesary packages (netbeans, mingw x86_64 and SDL 2.0.3) and know how to configure environment variables. If you don’t just google “windows 7 set environment variables” and follow instructions; it’s an easy and straightforward process.

  1. Install Netbeans (C/C++ version) from scratch. I installed stable version 7.4
  2. Install MinGW x86_64 version. The path where it was installed will be henceforth called %MINGWPATH%”
  3. Uncompress SDL tar file to %SDLPATH%
  4. Add “%MINGWPATH%/msys/1.0/bin” and “%MINGWPATH%/bin” to the PATH environment variable.
  5. Start netbeans; it should automatically detect your mingw tool collection. If it doesn’t, go to tools -> Options -> c/c++ -> build tools tab and click on add collection. Select the /bin folder of the %MINGWPATH% as the base directory, and %MINGWPATH%/msys/1.0/bin for the make.exe if it’s not automatically selected.
  6. Now create a new project and create a c++ application.
  7. In Project properties -> c++ compiler -> include directories and headers -> add folder %SDLPATH%/x86_64-w64-mingw32/bin
  8. Do not close the window; on the Linker section add %SDLPATH%/x86_64-w64-mingw32/lib to “additional library directories”.
  9. Finally, add these libraries in this order: mingw32.a, SDL2main.a, SDL2.a. The first file can be found on the %MINGWPATH%/x86_64-w64-mingw32/lib and the other two in the %SDLPATH%/x86_64-w64-mingw32/lib.
Now you should be able to succesfully compile an application that can make use of the SDL API. To create SDL applications, google a bit more. 🙂
Configure NetBeans / SDL 2.0.3 / MinGW

Aprender C: desarrollando un juego de ajedrez (II)

En el anterior post comenté que el tablero es un array de punteros a una variable de tipo pieza. En un principio pensé en crear una variable para cada pieza del juego, pero enseguida deseché la idea. ¿Qué valor me aporta una pieza por sí sola, sin estar situada en una casilla de un tablero? Un array de punteros me facilita la vida; si el puntero apunta a NULL entonces puedo considerar que la casilla está vacía. De lo contrario, si apunta a una variable de tipo pieza, sé que una pieza de ese tipo ocupa esa casilla, que es al final de cuentas lo que a mí me interesa. Además, de esta forma sólo necesito crear una variable por cada tipo de pieza y color; un único peón blanco, un único peón negro, un caballo blanco, etc. La declaración de variables e inicialización es como sigue:

tPiece  pb, pn, tb, tn, cb, cn, ab, an, rb, rn, reyb, reyn;

void initPieces() {
    
    pb.color = tb.color = cb.color= ab.color= rb.color= reyb.color=WHITE;
    pn.color= tn.color = cn.color= an.color= rn.color= reyn.color=BLACK;
    pb.rol= pn.rol=PAWN;
    tb.rol= tn.rol = ROOK;
    cb.rol= cn.rol=KNIGHT;
    ab.rol= an.rol=BISHOP;
    rb.rol= rn.rol=QUEEN;
    reyn.rol= reyb.rol= KING;
    
}

Estas variables y procedimiento yo los he incluído en ficheros aparte llamado pieces.h y pieces.c.

Las piezas están declaradas como variables globales; esto no es especialmente elegante, pero sí efectivo.

El tablero también debe ser iniciado al principio de la ejecución del programa, puesto que un puntero declarado pero no inicializado apunta a direcciones aleatorias de memoria – y aunque probablemente el sistema operativo no nos permitiría andar modificando contenido aleatorio de nuestra memoria, es una buena práctica inicializar los punteros.

void initBoard(tPiece* t[][8], int alto, int ancho) {

    int i,j;
    for( i = 0; i < ancho; i++ ) {
        for( j = 0; j < alto; j++ ) {
            t[i][j] = NULL;
        }
    }
    
}

Bien, pues con esto ya tenemos nuestro tablero y piezas listos para ser usados.

Aprender C: desarrollando un juego de ajedrez (II)

Aprendiendo C: desarrollando un juego de ajedrez

Como he decidido finalmente orientar mi carrera profesional a la industria del entretenimiento digital, y salí de la universidad con conocimientos de C muy bajos, he tomado la determinación de programar un juego de ajedrez en C para aprender (parte de) ese lenguaje.

Sin más dilación, hoy explicaré los tipos y estructuras de datos usadas.

Una pieza de ajedrez es un elemento del que (por el momento) nos interesa abstraer dos características: color y papel que juega. Mi declaración es la siguiente:

typedef struct {
   tColor color;
   tRol rol;
 } tPiece;

Tanto tColor como tRol son enumeraciones. En C una enumeración es un conjunto de elementos nombrados por el programador a los que el compilador asigna un valor en función de su orden. De esta manera,

typedef enum {WHITE, BLACK} tColor;
typedef enum {PAWN,ROOK, KNIGHT, BISHOP, QUEEN, KING} tRol;

A la hora de compilar, WHITE será sustituido por el valor 0, BLACK por 1. De igual modo, PAWN 0, ROOK 1, KNIGHT 2, etc.

Finalmente, el tablero es un array de 8×8. Ojo, es un array DE PUNTEROS a una variable de tipo tPiece:

tPiece* t[8][8];

Al por qué considero que debe ser un array de punteros, daré explicación en el siguiente post.

Aprendiendo C: desarrollando un juego de ajedrez

Drupal: redireccionar usuarios a una página

Existe un módulo específicamente diseñado para redireccionar a un usuario a una determinada página llamado Login Destination (http://drupal.org/project/login_destination).

Otro módulo es LoginToBoggan.

Otra forma (y esto solo funciona desde /user) es agregar la siguiente cadena al link de iniciar sesión:

http://example.com/user?destination=/ 

Eso hace que cuando el usuario inicie sesión desde la página user, sea redireccionado a la página inicial. Lo malo es que esto no funciona para bloques.

Drupal: redireccionar usuarios a una página