PDA

Ver la Versión Completa : Arrastrar formulario de tamaño mayor al escritorio


Toni
09-09-2011, 19:54:42
Hola,

Necesito realizar un entorno para una nueva aplicación que ha de trabajar con formularios con estas caracteristicas:

-. Tamaño superior al escritorio.
-. Poderse arrastrar mediante el evento MouseDown solo verticalmente y no superando los limites del mismo.

He buscado por los foros y he encontrado una solucion que permite arrastrar el formulario implementando en el evento FormMouseDown:


void __fastcall TForm1::FormMouseDown(.....
{
ReleaseCapture();
Perfom(WM_SYSCOMMAND, 0xF012, 0);
}


El problema que me he encontrado con este metodo es que permite mover el formulario hacia cualquier dirección y no puedo controlar de una forma elegante que solo sea verticalmente y que no supere los limites del formulario, es decir el efecto que busco es parecido a la del navegador web pero sin la barra de desplazamiento.


void __fastcall TForm1::FormMouseDown(.....
{
ReleaseCapture();
Perfom(WM_SYSCOMMAND, 0xF012, 0);
Left=0;
}


Si añado un Left=0 funciona pero no de forma elegante como comentaba.

El otro problema que me encuentro es cuando arrastro el formulario de forma vertical hacia arriba y se sale del escritorio, en cuanto suelto el boton me lo posiciona automaticamente el formulario en la posición Top=0, como puedo hacer para desplazar fuera del margen del escritorio por la parte superior?

Y si alguien tiene idea como aplicar el efecto de arrastrar y velocidad que hace el iphone seria fantastico.

roman
09-09-2011, 21:10:54
Yo no entiendo a qué te refieres con "mover sólo verticalmente sin superar los límites del mismo" De hecho tampoco entiendo para qué podrías querer un formulario que ocupe más que el escritorio; quizá si nos explicas más acerca de lo que quieres hacer podríamos ayudarte mejor.

De todas maneras, creo que te puedo ayudar en la parte de mover el formulario sólo verticalmente:


TForm1 = class(TForm)
private
procedure WMMoving(var Message: TWMMoving); message WM_MOVING;
...
end;

...

procedure TForm1.procedure WMMoving(var Message: TWMMoving); message WM_MOVING;
begin
Message.DragRect.Left := Left;
Message.DragRect.Right := Message.DragRect.Left + Width;
end;


Con esto, el formulario se mantendrá siempre en la posición horizontal inicial.

// Saludos

_cero_
10-09-2011, 03:42:14
Qué te parece este ejemplo, es simple, y con un poquito de trabajo podría quedar algo similar a metro (ya que según veas lo puedes mover en x también, no solo en y).


Pd. Ce cierra con un doble click donde sea.
Pd2. Solo te lo pongo limitado a la parte de arriba, necesitarías echarle un poco de coco para la parte de abajo (solo pensar una condición adecuada).


ejem. http://www.megaupload.com/?d=SR4QQFHW

Toni
12-09-2011, 10:13:25
Hola,

Primero de todo daros las gracias por las respuestas.

Yo no entiendo a qué te refieres con "mover sólo verticalmente sin superar los límites del mismo" De hecho tampoco entiendo para qué podrías querer un formulario que ocupe más que el escritorio; quizá si nos explicas más acerca de lo que quieres hacer podríamos ayudarte mejor.

El motivo de todo esto es para realizar un interface de usuario en una nueva aplicación un poco diferente, la idea es hacer una aplicación con un aspecto 'similar' al interface de usuario del Ipod. Por eso comentaba que queria poder definir un formulario de mayor tamaño que el escritorio y por eso quiero poderlo desplazar de una forma facil arrastrando con el puntero del raton o con el dedo en una pantalla tactil.

Lo de no superar los limites, pues me refiero a que si tengo un formulario mayor que el escritorio, pues cuando lo muevo que solo me permita moverlo hasta el inicio o el fin del mismo no mas alla. Para que el efecto de mover el formulario sea como si fuese una pagina.

Con el codigo que me pones perfecto puedo mover el formulario verticalmente, pero me sucede el mismo problema que comentaba que cuando lo desplazo hacia arriba y supera el margen de la pantalla al soltar el boton del mouse me revota el formulario a la posicion Top=0. Como puedo evitar este revote?

Para que os hagais una idea lo que quiero hacer es una aplicación que se ejecutara en una PDA via terminal server y quiero que la aplicación se pueda manejar algo 'parecido' al Ipod, ya que la pantalla de estas pda's es bastante reducida y con esto me permitira darle un poco mas de juego a la hora de introducir datos en formulario mayores que la pantalla.

roman
12-09-2011, 15:34:08
Lo del Top=0 no le veo solución. Es decir, ni cuenta me había dado, pero parece ser el comportamiento normal; incluso si mueves una ventana cualquiera con el teclado (Alt+Space, Mover); aunque lo hace, apenas terminas el movimiento, regresa la ventana a Top=0.

Ahora, sigo sin entender del todo lo que quieres lograr, más que nada porque no conozco los iPods. Pero me da la impresión de que podrías lograrlo de otra forma. El formulario simplemente podría ocupar todo lo alto de la pantalla y lo que desplazas es el contenido. Es decir, un formulario puede tener más elementos de los que visualmente caben en la pantalla y al suceder esto aparecen barras de desplazamiento que puedes manipular.

// Saludos

Toni
12-09-2011, 17:23:32
Lo que intentaba explicar pues seria muy similar ha esto que tu comentas, de alguna forma realizar una aplicación que permitiese utilizar formualrio mayores que la pantalla, pero en lugar de utilizar barras de desplazamiento desplazarse por el formulario arrastrandolo con el mouse o dedo.

por ejemplo, como cualquier aplicación web que el formulario es mayor que la pantalla y lo vamos desplazando con la barra de desplazamiento o se va desplazando a medida que vamos introduciendo datos en los campos. Lo que queria realizar es esto, el porque no quiero utilizar las barras de desplazamiento, es porque lo estoy pensando para dispositivos tipo PDA y la pantalla ya es pequeña de por si y la barra te come un poco de pantalla.

Corrijo que mencione el Ipod y es Ipad:

http://www.youtube.com/watch?v=adnx6SjZpMw&feature=player_detailpage#t=74s

Realmente la unica pega que encontraba ahora es el reposicionamiento automatico en Top=0 que hace cuando desplazo la ventana hacia arriba.

El porque queria hacer de esta forma, con formularios es para aprovechar todo el IDE de Builder para crear los formularios en tiempo de diseño y no mediante código.

Espero haberme explicado un poco mejor.

Muchas gracias Roman.

_cero_
12-09-2011, 20:45:50
Y el ejemplo que te dejé, te sirvió? Lo ejecutaste?:confused: Hace exactamente lo que pides (claro de una forma básica), ya solo falta que tú le agregues las animaciones y el límite inferior, no se para las animaciones se me ocurre un timer que te regrese el formulario a 0 o al máximo de abajo.

Pd. Si, me imaginaba que lo que intentabas hacer era algo táctil, por eso mi mención de metro (en mi opinión un mejor concepto), que se puede mover en X y Y.

Pd2. Builder XE ya tiene forma de manejar interfaces táctiles, ahora mismo no te puedo decir como (ya que no lo he necesitado), pero por ahí debe de haber algo que te facilite la tarea.

Toni
12-09-2011, 23:16:27
Hola _cero_, muchas gracias por tu ejemplo tambien.

Si que lo mire pero esta hecho en una version superior a mi builder (BCB6.0) y al no poder abrir el proyecto no he podido ver que propiedades has modificado del TForm. He editado los archivos .cpp y .h para ver el codigo pero aqui no he visto que es lo que hace que se pueda desplazar hacia arribar el formulario fuera del margen.

La verdad que tambien me despisto porque has utilizado un TImage y pense que desplazabas el image y no el form.

Haber si me puedes decir que propiedades cambiastes en el form.

_cero_
13-09-2011, 01:07:00
Bueno, en el form solo cambie la propiedad “BorderStyle” a “bsNone”, y puse el tamaño a 2000 de ancho y 2000 de alto, y la magia de todo se hace en los eventos OnMouseDown, OnMouseMove, y OnMouseUp, estos eventos están en casi todos los componentes visuales, incluyendo el form, así que puedes moverlo desde el mismo form o desde un TImage como lo hago yo. Ahora explicare lo que hago:


//Primero declaramos dos variables globales.
bool dra = false; //Esta nos sirve para saber cuándo el usuario da click (o toca la pantalla), y cuando lo suelta.
TPoint poi; //Y esta nos sirve para saber en qué coordenadas lo hiso

//---------------------------------------------------------------------------
void __fastcall TForm1::ima2MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift,
int X, int Y)
{
/*En esta parte guardamos las coordenadas en las que el usuario hiso click*/
dra = true;
poi = Point( X, Y );
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ima2MouseMove(TObject *Sender, TShiftState Shift, int X, int Y)
{
/*Si dra == true o sea si el usuario hiso click y no lo ha soltado,
calculamos el punto Y (o Top), que el formulario tendrá*/
if ( dra == true ) {
// int xx = Form1->Left + X - poi.x;
int yy = Form1->Top + Y - poi.y;

if ( yy < 0 ) {
Form1->Top = yy;
}
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ima2MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift,
int X, int Y)
{
/*Aquí ponemos dra = false, porque el usuario levanto el click*/
dra=false;
}
//---------------------------------------------------------------------------
Pd. Para abrir el formulario que subí, solo tienes que crear un nuevo proyecto y agregar el cpp al proyecto que creaste, en teoría no debería haber mayor inconveniente, aunque no me acuerdo muy bien del builder 6.

Toni
13-09-2011, 17:35:59
Hola,

Por fin he tenido un poco de tiempo para probar el codigo que me enviaste. Funciona perfectamente, no tiene el problema del mencionado rebote que nos pasaba con las otras tecnicas.

La verdad que el codigo es muy similar ha como lo probe yo la primera vez y por eso me despisto cuando me lo enviaste, eso y el no poder abrir directamente el proyecto por no ser la misma version de builder.

Pero la verdad que asi funciona perfecto! Ahora tengo que hacerme una rutinas para que cuando cambie el foco de los objetos desplace tambien el formulario a la posicion correcta.

Por cierto, se os ocurre una vez hecho esto como se podria captar la velocidad del dedo al mover el formulario y para darle el efecto este como si lo lanzases.

Muchas gracias!

_cero_
13-09-2011, 19:35:47
mmm no tengo nada que te pueda ayudar a las animaciones, aunque creo que con un timer y algo de trabajo que daría algo de muy buen ver, pero como no tengo una pantalla táctil, y tampoco es algo en lo que este muy metido (me refiero en lo táctil), me temo que ahí quedare yo. De todos modos nos vemos, y te repito que desde la versión 2010 de builder, ya tienes los recursos para manejar mejor estas interfaces, así que si tienes la posibilidad de cambiar a esa versión, hazlo. Porque ahí ya está trabajadas las cosas como el efecto de lanzamiento y otras cuestiones. De todos modos nos vemos y te dejo un videin para que veas de qué hablo. http://www.youtube.com/watch?v=1a2dywOBKao#t=06m05s