• Viernes 8 de Noviembre de 2024, 08:26

Autor Tema:  Skin Que Muestre El Control Image Vb 6.0  (Leído 3976 veces)

ukyuky

  • Nuevo Miembro
  • *
  • Mensajes: 6
    • Ver Perfil
Skin Que Muestre El Control Image Vb 6.0
« en: Martes 27 de Mayo de 2008, 03:13 »
0
Hola a todos..
Nesecito saber si hay algun skin que me muestre el control image ya que no puedo modificar el sistema ya que cuenta con un mapa con muchas coordenadas
¿Alguien me puede ayudar?

Nebire

  • Miembro HIPER activo
  • ****
  • Mensajes: 670
    • Ver Perfil
Re: Skin Que Muestre El Control Image Vb 6.0
« Respuesta #1 en: Martes 27 de Mayo de 2008, 11:17 »
0
¿ Puedes explicarte mejor ???.

A qué llamas: 'saber si hay algún skin' ???
Que quieres decir con: 'que muestre un control image' ???
Qué quieres decir con: 'no puedo modificar el sistema' ???
....y que quieres decir con: 'cuenta con un mapa de muchas coordenadas' ???

La verdad, te leo y no de qué cojones estás hablando: de programación, de aplicaciones, de personalizar tu S.O. del robot de las estrellas .... , incluso me pareciera entender (de rebote) que quieres saber el nombre del OCX que maneja el control image... pero... con esas palabras no logro entender que quieres.

Explícate mejor, dedícale 5 minutos, no 20 sg. Unforo no es un teléfono celular, no te cuesta cada palabra que pones, no ahorres. aquí ahorrar palabras es ganarse que pasen de tu mensaje porque no se entiende qué quieres...
«Ma non troppo»
----> ModoVacaciones = False<----

ukyuky

  • Nuevo Miembro
  • *
  • Mensajes: 6
    • Ver Perfil
Re: Skin Que Muestre El Control Image Vb 6.0
« Respuesta #2 en: Martes 27 de Mayo de 2008, 14:02 »
0
Mis disculpas........
Parece que entendiste....
Quiero saber el nombre del OCX que maneja el control image... ya que tengo una imagen en un control image y no puedo ponerlo en un picture, ya que la imagen en el picture no se adapta a las dimenciones que deseo ya que la imagen es chica.
Espero que entiendas...
Gracias...

Nebire

  • Miembro HIPER activo
  • ****
  • Mensajes: 670
    • Ver Perfil
Re: Skin Que Muestre El Control Image Vb 6.0
« Respuesta #3 en: Miércoles 28 de Mayo de 2008, 13:01 »
0
Bien, te cuento...

De entrada saber el nombre del ocx no te soluciona tu problema, pero hay formas de solucionarlo, sigue leyendo y te explico 3 maneras de hacerlo... (2 muy parecidas entre sí).
 
El control Image tiene una propiedad llamada 'Strecht' si la pones a true, la imagen se ajusta al tamaño del control image... así modificas el tamaño del control, la imagen se adapta ditorsionándose si es preciso para rellenar el control image.

El control picturebox se comporta de forma muy distinta, el control picturebox, tiene una propiedad llamada 'autosize' si la activas lo que sucede es que en vez de la imagen ajustarse al control como sucedía con el control image, es el control el que se ajusta al tamaño de la imagen.

Yo sólo uso el control picturebox para mostrar imágenes cuando necesito usar ciertas funcionalidades como usar el método paintpicture o el savepicture, o cuando necesites incluir más controles para que actue como contenedor que es. Si no es así uso el 'image' usa menos recursos en memoria.

Entonces para resolver tu problema hay 3 formas la más sencilla de manejar es incluir dentro del control picturebox un control image, y cuando quieras redimensionar el picturebox, haces lo propio con el control image dentro de él. Para trabajar con la imagen dentro del picturebox te debes referir a ella con su porpiedad 'image' no 'picture' esto es asi: picturebox1.image  ...

El otro método es usando el método paintpicture y requiere el uso de 2 controles picturebox, el primero contiene la imagen que deseas con la propiedad establecida a autosize=true, este picturebox está oculto 'invisible=true', ahora cuando queramos modificar el tamaño del picturebox que nos interesa modificamos su tamaño, y con el método paintpicture 'pegamos' la imagen del picturebox oculto en las coordenadas que nos interese del picturebox que nos interesa. Siempre que modifiquemos el picturebox destino, deberemos hacer un paintpicture desde el oculto hacia aquel, por tanto el oculto tiene la imagen tal como se ha recibido de donde sea que se tomare. Debes darte cuenta que este método pega una imagen no persistente, es decir si colocas una ventana encima verás que la imagen se 'pierde', para evitar que esto suceda lo que se debe hacer es activar la propiedad 'autoredraw=true' con ello lo que internamente hace es guardar una copia de la imagen contenida ' image' en memoria, de modo que cuando se exponga la superficie del picturebox, y sea invocado el repaint, redibuja el área expuesta con el contenido que tenía...  

El terce método es similar a este 2º pero no pegamos la imagen cada vez que cambiamos el pictureboxdestino, sino sólo lo pegamos 1 vez, luego nada más transferir el gráfico no persistente al picturebox hacer algo como: picturebox1.picture=picturebox1.image , con lo que consigues que ya tenga su propiedad picture dispuesta. Supongamos que ahora quiero modificar el tamaño, antes que nada regojo sus medidas actuales, luego modifico el tamaño del control y mediante paintpicture siendo el mismo el origen y el destino, y tomando como coordenadas de tamaño origen las que guardamos, pegamos la imagen al área del picturebox, nuevamente haremos un picturebox1.picture=picturebox1.image. Este método 3º sin embargo tiene bastantes inconvenientes por lo que sólo debería usarse cuando no quede otro remedio, por ejemplo si pegas la imagen sin rellenar todo el área nueva, la imagen se 'monta' encima de la existente, esto es útil en determinadas situaciones pero porbablemente en muchos casos no sea lo que se quiere hacer. Por tanto te recomiendo que uses el método 1 ó el 2. Este 3º método también se puede usar cuando no te interesa activar autoredraw por alguna razón (por ejemplo si dibujas encima de él), ya que si activas 'autoredraw' los gráficos no persistentes se fijan como gráfico, y por tanto si dibujaste un círculo encima de la imagen se mantiene y sólo puede ser borrado cuando la imagen es rescrita por otra. Un g´rafico no persistente puede borrarse siempre con 'picturebox1.cls'.

Estos 3 mecanismos bien usados son suficientes para controlar cualquier gráfico dentro de un picturebox. Una cosa más... si por ejemplo quieres modificar el tamaño del picturebox, de modo que la imagen se ajuste al picturebox pero manteniendo las proporciones originales, (no deformándose como nos sucedía en el control image), deberás guardar la proporción original de los píxeles (el alto con respecto al ancho), así cuando aumente el alto del picturebox, x pixeles, el ancho deberá aumentar 'x* proporción'

... te explico esto de la proporción. supongamos que nuestra imagen tiene 15x10 píxeles, entonces la proporción es ancho/alto= 15/10=1'5 entonces ahora cada vez que cambie el ancho por ejemplo 22 píxeles el alto deberé cambiarlo 22/1'5 o al revés si lo que quiero es modificar el alto en 47 pixeles el ancho deberé modificarlo así: 47* 1'5 naturalmente añadido al tamaño que ya tiene.... por tanto créate un variable picturebox1_Proporcion que debes actualizar cada vez que alojas una nueva imagen....
«Ma non troppo»
----> ModoVacaciones = False<----

ukyuky

  • Nuevo Miembro
  • *
  • Mensajes: 6
    • Ver Perfil
Re: Skin Que Muestre El Control Image Vb 6.0
« Respuesta #4 en: Miércoles 28 de Mayo de 2008, 14:44 »
0
Muchas Gracias...
Otra pregunta...
Puse el control image dentro del picturebox.. hasta ahi todo bien...
Tengo que graficar arriba de la imagen una linea , lo que me pasa es que  cuando tenia el control image me mostraba la linea, ahora que lo he puesto dentro del picturebox no me la muestra mas, ¿Como puedo solucionarlo?

Nebire

  • Miembro HIPER activo
  • ****
  • Mensajes: 670
    • Ver Perfil
Re: Skin Que Muestre El Control Image Vb 6.0
« Respuesta #5 en: Jueves 29 de Mayo de 2008, 13:55 »
0
No estoy muy seguro de a qué llamas 'graficar una línea'.... pero por suponer...

Hay otra cosa que debes saber, si te fijas el control image no tiene borde, entonces cuando metemos el control image en un control picturebox justo del mismo tamaño, en efecto puede verse que se tapan algunos pixeles por cada lado, esto es debido a que por defecto el picturebox si tiene borde.

Este marco puede quitarse si se desea estableciendo la propiedad borderstyle: picturebox1.borderstyle=0 ...esto quita el marco y en consecuencia deja ver esa línea de píxeles inferior superior y laterales que tapaba, que son 4 píxeles por cada lado lo que ocupa el 'marco'.

...pero si con graficar quieres decir que antes pintabas una línea en la parte superior del control image (lo que debía hacerse en realidad sobre su contenedor que era el formulario, ahora la situación no ha cambiado, ahora puedes dibujar esa línea sobre el control picturebox directamente. Al respecto hay que saber alguna cosa: Los controles se organizan por capas, que son niveles de profundidad, básicamente se consideran 3 capas (y cada capa puede tener tantos niveles como controles se ponga) . La métodos gráficos están en la capa media, por ejemplo si hacemos un Picture1.Line (0, 0)-(Picture1.Width, Picture1.Height), vbBlue  nos traza una línea azul en diagonal (si no llega de esquina a esquina es porque scalemode no está establecida a vbpixels, los métodos gráficos sólo trabajan con píxeles ellos no entienden los 'twips') si previamente hemos colocado por ejemplo un textbox dentro del picture que cruce la diagonal imaginaria, veríamos que se 'corta' donde se cruza con el textbox. Esto es porque el textbox tiene un nivel de profundidad inferior a los métodos gráficos. es decir está en primer plano. En cambio el control image está en la capa más baja, eso significa que la línea que hicimos atraviesa por encima de esa imagen.

Los controles comunes (aquellos que tienen una propiedad HDC o Handle) son de primer plano, los del fondo son los que no tienen esta propiedad, por ejemplo el control image, el control shape el control line o el control label. y los de la capa media son los métodos gráficos, esto es cuando manipulas píxeles directamente por ejemplo.
Código: Text
  1.  
  2. print (&#34;Hola&#34;)
  3.  
  4. print (&#34;Hola 2&#34;);
  5.  
  6. print (&#34;Hola 3&#34;) ,
  7.  
  8.  
  9. form1.line (0,0)-(20,40), vbred
  10.  
  11. ' coloca un button y mete este codígo dentro de su 'click'
  12. Private Sub Command1_Click()
  13.     Const colorMax = (2 ^ 24) - 1
  14.     Dim colo As Long
  15.     
  16.     Me.Cls
  17.           
  18.   For v = 500 To 2000 Step 20
  19.     For k = 1 To 10000 'HScrRayo.Value
  20.         colo = colorMax - ((((v * k) Mod colorMax) + k) Mod colorMax)
  21.         Form1.PSet (100 + ((v Mod k) * 30), 100 + ((k Mod 30) * (v Mod k))), colo ' vbRed
  22.     Next
  23.     DoEvents
  24.   Next
  25.    End Sub
  26.  
  27. ' tambi´´en puedes probar con 'circle'.
  28.  
  29.  

Entonces cuando quieres hacer algo encima de un control debes conocer previamente a qué capa pertenece....

No hay que confundir los métodos gráficos con los controles gráficos, el control line produce un resultado muy parecido al método line, pero el control line es un auténtico control, no se 'borra' al colocar algo encima aunque si se puede tapar, sin embargo existe en memoria, un método gráfico es situar píxeles y olvidarse de ellos, no se hace un 'memorizado' sobre ellos salvo que se establezca la propiedad autoredraw a true del contendor donde están... si se hace eso,  por ejemplo entonces  los controles gráficos se sobreponen sobre los métodos gráficos. es decir se redibujan los controles después del fondo.

Aparte puedes usar el control line y el más polifacético y práctico control shape....
Pero vamos por lo que entiendo que dices tu 'linea' ha sido tapada por el marco del picturebox que son 4 píxeles de perímetro sobre el control... y en cualquier caso cuando antes hacía form1.line ... para colocar una línea sobre el control  image ahora debes hacer picturebox1.line... pero en cualquier caso sigue siendo contendor.line siendo contendor el contendor donde está el objeto. Si en el control picturebox quieres colocar una línea encima del image necesariamente será en el píxel -1, los pixeles de coordenadas negativas no se ven, eso significa que si tu línea tiene pongamos 8 píxeles de grueso, deberás poner tu control image así: image1.top=8, y así desde el píxel 0 hasta el 7 puedes usarlo para poner esa línea. Naturalmente esos pixeles que has despalazado la imagen hacia abajo, debes tenerlas en cuenta para las modificaciones del picturebox (se supone que el picturebox lo ajusta al tamaño de la imagen).
«Ma non troppo»
----> ModoVacaciones = False<----

ukyuky

  • Nuevo Miembro
  • *
  • Mensajes: 6
    • Ver Perfil
Re: Skin Que Muestre El Control Image Vb 6.0
« Respuesta #6 en: Viernes 30 de Mayo de 2008, 02:34 »
0
Muchas Gracias por toda tu ayuda..
Te molesto en una cosa más..
Tengo que dibujar un circulo dentro de un picturebox. Lo hago con el comando picture1.circle(x,y),radio.
Despues tengo que borrar el circulo que realice y hacer otro en otro punto del picturebox.
Mi pregunta..
¿Como hago para borrar el circulo que hice?
¿Como hago para que el circulo este relleno?(Probe con picture1.fillcolor= vbblue . No me lo rellena)

Nebire

  • Miembro HIPER activo
  • ****
  • Mensajes: 670
    • Ver Perfil
Re: Skin Que Muestre El Control Image Vb 6.0
« Respuesta #7 en: Viernes 30 de Mayo de 2008, 12:19 »
0
Los métodos gráficos se borran con 'cls' así: picturebox1.cls , pero ojo se borra todo lo que tengas en el picturebox. Para borrar de modo selectivo, por ejemplo un cudrado creado antes, habría que repintar otro encima en el mismo sitio  es decir usando la misma sentencia empleada, pero con algunas características que paso a señalarte...

De entrada vamos a trabajar con un cuadrado relleno, así de paso ves que una línea también se puede convertir en un cuadrado y depaso ves como se rellena que es otra cosa que preguntas.
Código: Text
  1.  
  2. ' estructura de tipo punto, par de coordenadas
  3. public type Point
  4.      x as single
  5.      y as single
  6. end type
  7.  
  8. ' dibujamos un cuadrado dados dos pares de coordenadas
  9. Public sub DibujarCuadrado(origen as point, final as point)
  10.       Form1.Line (origen.x, origen.y)-(final.x, final.y), vbRed, BF
  11. end sub
  12.  
  13.  

Bien el código anterior podría ser llamado por ejemplo con la siguiente orden...
Código: Text
  1.  
  2.     ' según tu pantalla modifica estos valores
  3.     dim a as point :   a.x=3000 : a.y=6000
  4.     dim b as point :   b.x=6000 : b.y=3000
  5.     call Dibujarcuadrado(a,b)
  6.  
  7.  
Ahora examinamos el código y comentamos....
En dibujarCuadrado, vemos que empleamos el método line, sin embargo al ejecutarlo se genera un cudrado, porqué.... porque se ha añadido el parámetro 'B'  al final de la línea, ese parámetro le indica que con las coordenadas dibuje un cuadrado, si no estuviera b, dibujaría una línea en 'diagonal' (en diagonal si los pares de x o de y no fueran del mismo valor) desde el punto de la coordenada origen al punto de la coordenada destino. Fíjate que en realidad podemos señalar como origen cualquiera de las 4 esquinas y como final la opuesta, en este caso origen es la esquina izquierda baja, para probarlo comenta la línea de código form1.line justo después de 'vbred' y ejecútalo, ahora ves que la misma rutina puede servirte para dibujar cuadrados y líneas con colo modificarla un poco añadiendo un parámetro que indique eso mismo, lo vamos a hacer, porque el código fuente hace eso mismo así se entenderá mejor como actúa.

Código: Text
  1.  
  2. ' dibujamos un cuadrado dados dos pares de coordenadas
  3. Public sub DibujarCuadrado(origen as point, final as point, optional cuadro as boolean=false)
  4.       if cuadro=true then
  5.             Form1.Line (origen.x, origen.y)-(final.x, final.y), vbRed, BF
  6.       else
  7.            Form1.Line (origen.x, origen.y)-(final.x, final.y), vbRed
  8.       end if
  9. end sub
  10.  
  11. ' para llamarlo ahora para dibujar la línea... tomando los valores anteriores
  12.       call Dibujarcuadrado(a,b) ó también
  13.       call Dibujarcuadrado(a,b, false)
  14. ' para dibujar el cuadrado... se entiende que estas líneas van dentro del código de alguna rutina, por ejemplo de un botón.
  15.       call Dibujarcuadrado(a,b,true)
  16.  
  17.  
Seguimos... el cuadro podrá haberse rellenado o no. Bien tanto el relleno como el grosor de línea como el estilo de relleno como el color de relleno, se controlan a través del contenedor...

El contenedor además de usar el método gráfico contiene los 'fenes' de 'dispersión' de sus métodos gráficos... veamos cómo; ve a las propiedades del  picturebox donde dibujas cambia el valor de la propiedad drawwidth, por ejemplo a 5 así podrás apreciarlo bien, desde código también podrás cambiarlo por ejemplo: picture1.drawWidth=5 si ahora ejecutas verás que lo que cambia es el grosor de línea de borde del cuadrado o del círculo, es importante saber que cuando el grosor de línea es diferente de 1 algunas de las características que comentaremos a continuación se deshabilitan.

De igual modo modo usar 'fillColor' para elegir el color con que se rellena nuestro cuadro, pero ojo esto depende de otros factores, es decir queda alterado por otras propiedades.... por ejemplo 'FillStyle' . FillStyle por defecto es 'transparent' que es la razñon por la cual nuestro cuadro o círculo no se haya rellenado, si lo cambiamos a 'solid' ya se rellena 'de lo que sea, pero se rellena', pruébalo.

Bien si has probado a cambiar el color en fillcolor verás que 'no obedece', ello es porque nosotros hemos fijado VbRed que es una constante de color para definir el color rojo, cambia si quieres el VBREd del line por 'form1.FillColor', fillcolor es el color por defecto para los métodos gráficos cuando no se especifica color y el color no es obligatorio, si es obligatorio pero se ignora, entonces color es 0, es decir negro.

Más cosas... como borrar de modo selectivo... ya dijimos que si usas cls, se borran todos los métodos gráficos (en realidad redibuja todo el contenedor de nuevo, los píxeles que no constan memorizados por tanto se pierden que es lo que sucede con los métodos gráficos (salvo que tengamos autoredraw a true, que guarda copia del 'fondo' ), bien para borrar de modo selectivo hay que usar algún  método que consista en dejar algo como anteriormente estaba, te explicaré 3 métodos el primero es universal vale para todas las situaciones, es lo que hace el sistema pero nosotros a 'pequeña escala'

método 1: si vamos a cubrir una zona, antes de cubrirla hacemos copia de la sección a ocupar luego la cubrimos como queramos, cuando queramos restaurarla pegamos la copia que hicimos. Esto plantea 1 problema que pasa si hacemos sucesivos cambios en la misma zona... cada vez hacemos una copia de un trozo, eso significa que vamos guardando mucha información... este método si te fijas es lo que se hace para las opciones 'deshacer' de los programas gráficos, para nosotros puede ser un problema si no deseamos tener un control tan férreo , pués nos obligaría a tener un 'historial de copias' en una matriz, dicha matriz de imágenes la tendríamos que usar como cola tipo último en entrar primero en salir, para garantizar que se usa correctamente, sin embargo podríamos hacer trampa en esa cola y poder decidir que podemos usar directamente la del fondo eliminando eso sí el resto, es decir de un plumazo podríamos volver al primer cambio. Tu decides si implementas esto o no, seguramente como principiante no te atrevas, pero toma nota para el futuro. sin embargo si podrás tomar aunque sólo sea la 1ª vez no generar una amtriz, sino solo una.

método 2: El segundo método es más cómodo, se lo dejamos al sistema, pero no tendremos un control tan potente de decisión deberemos adaptarnos y conocer bien como funciona si no nos dará bastante trabajo, pero en principio es muy sencillo de usar. Establece la propiedad picture1.DrawMode=7 (Xor pen), por defecto es 13, CopyPen que es más o menos lo que se ve es lo que hay . Una operación Xor tiene una particularidad muy interesante al ejecutarlo hace algo al ejecutarlo nuevamente sobre el mismo valor anterior con el resultado anterior devuelve el estado anterior, con un ejemplo en palabras (no es exacto, vale, lo que pretendo es que lo entiendas sin perder tiempo en buscar una 'traducción exacta). imagina que tenemos 2 palabras: 'Barranco' y 'Ardgchfkl' , supongamos que al hacer un xor entre ambas palabras nos da este resultado: 'mgjrdisu' bien pués si ahora hacemos un xor entre este resultado y cualquiera de los 2 anteriores obtenemos justamente el otro que no hemos usado, es decir si hacemos xor con:
'mgjrdisu'  xor 'Barranco' = 'Ardgchfkl'  y si hacemos:
'mgjrdisu'  xor 'Ardgchfkl'  = 'Barranco'

Es decir después de un par de xor obtenemos nuevamente una copia exacta del original (ya te he dicho que el ejemplo es sólo para entender el concepto), pués eso es lo que haremos con nuestro DrawMode.. ahora ejecuta de nuevo dibujar el cuadro con fillStyle=0 (sólido), fillcolor y drawwidth como quieras, pero con DrawMode=7, cada 2 ejecuciones verás que se restaura, por tanto podrás mover tu círculo después de restaurado, por tanto es un 'cls' selectivo.

Esta técnica del xor se usa para casi todo, para los 'backBuffer' y en vídeo, donde sólo se redibujan los píxeles que cambian respecto de la imagen anterior, con lo que se redibuja una imagen más rápidamente. Este método conjunto con el anterior produce los mismos resulados que el anterior sólo pero ahorrando memoria empleada a base de un cálculo más complejo, en ocasiones es inevitable que algún píxel 'se pierda' lo cual habrás visto muchas veces en los programas en que algo gráfico cambia y parece que no se restablece... Para evitar estas situaciones el S.O. intenta que no se tenga acceso directo a los controladores de vídeo, y cuando esto deba suceder el S.O. entrega el 'poder' diciendo, eah, la pantalla es toda tuya, haz lo que necesitas... y así se entra en el modo 'pantalla completa' salvaguardando el resto de gráficos aparte, eso evita que éste corrompa a áquel si compartieran buffers en memoria.

método 3: Como todo esto no deja de tener cierta complejidad, es más cómodo usar un control que permite todo esto , un cuadro y un círculo a través de una propiedad, el control shape, el control shape es un control ligero como son los métodos gráficos, pero además posee toda esta funcionalidad de la que hemos estado hablando de forma independiente respecto del contenedor, es decir si antes decíamos picture1.drawWidth=5 porque queríamos que el grosor de un círculo fuera mayor veremos que también las nuevas líneas toman ese ancho, controlarlo implica establecer contínuamente de nuevo el valor, pués todas las acciones comparten el mismo valor, es lógico pues son propiedades y acciones del picturebox, sin embargo quita flexibilidad o mejor dicho añade complicación en un momento dado pudiéramos habernos perdido al no haber guardado el estado de algo en una variable específica. El control shape nos salva de esta complejidad pero con cierto límite... sin embargo todas estas propiedades que hemos descrito se usan por igual con el control shape, podría decirse que el control shape es un 'extracto' de los métodos gráficos, como ya te he explicado someramente sus propiedades solo me falta indicarte que definir un cuadro o un círculo se establece a través de su propiedad shape asi: shape1.shape=2 (óvalado). y finalmente ver que como todos los controles tiene medidas esto es top, left, width y height que son el par de coordenadas que usábamos para dibujar un picture1.line por ejemplo. Un control shape puede actuar como un control line si su porpiedad width  ó heigth (una sola a la vez tiene valor unitario), si nembargo para eso es mejor el conttrol line, el control line si se maneja con pares de coordenadas ya que 'carece' de alto y ancho, así se emplea x1,x2,y1,y2. Se entiende que traducir width y height a una coordenada final no tiene misterios, por eso lo he tratado tal como si fuera en si mismo una coordenada.... una licencia inocente...

Un punto importante cuando usar shape (ó line) y cuando usar métodos gráficos: aunque el control shape (y line) es mucho más cómodo de manejar que y controlar que los métodos gráficos tiene sus límites, por ejemplo si se ha de dibujar 400 cuadrados sin duda no interesa crear 400 controles shape. Imagina la siguiente situación:

coloca un timer en el formulario llámale TimCudros, establece interval a 200 y enabled a true, añade un botón  llamado 'Command1' pega el siguiente código en la ventana de código y ejecútalo....
Código: Text
  1.  
  2.  
  3. Private Sub Command1_Click()
  4.     TimCuadros.Enabled = Not TimCuadros.Enabled
  5. End Sub
  6.  
  7. Private Sub TimCuadros_Timer()
  8.     Dim coor(0 To 3) As Single ' esto es x1,x2,y1,y2 en ese orden
  9.     Dim veces As Integer, colorRnd As Long
  10.     Dim limite As Single   ' límite de ancho o de alto
  11.     Dim drawmodo As Byte   ' para cambiar el drawmode del contenedor
  12.     
  13.     ' el número 50 limita el máximo
  14.     veces = Int(((50 - 0 + 1) - (1)) * Rnd) ' este si debe estar fuera, signa el bucle
  15.     
  16.     ' estas 2 líneas si se meten dentro del bucle se cambia con cada cuadro dibujado
  17.     drawmodo = Int(((15 - 1 + 1) - (1 + 1)) * Rnd + 1)
  18.     Me.DrawMode = drawmodo
  19.     For v = 1 To veces
  20.         For k = 0 To 3   ' tomamos coordenadas aleatroiamente
  21.             If k Mod 2 = 0 Then
  22.                 limite = Me.Width  ' es decir x1 y x2
  23.             Else
  24.                 limite = Me.Height  ' es decir y1 e y2
  25.             End If
  26.             coor(k) = Int(((limite - 0 + 1) - (1)) * Rnd)
  27.         Next
  28.         colorRnd = Int((((2 ^ 24 - 1) - 0 + 1) - (1)) * Rnd)
  29.         
  30.     
  31.        Form1.Line (coor(0), coor(1))-(coor(2), coor(3)), colorRnd, BF
  32.     Next
  33. End Sub
  34.  
  35.  

Como puedes ver so ejecutaste el código, para cosas donde existe un número incierto de objetos o que es excesivamente grande es mala idea tener controles shape o line o circle, desde luego podríamos meterlos en una matriz para maenjarlo conjuntamente en vez de uno a uno por su nombre, pero que hacemos con ellos si de repente ya no los necesitamos...los podemos eliminar, pero si más tarde los volvemos a necesitar habráque volverlos crear.

Entonces de modo general si un gráfico no tiene un fin muy determinado y es finito en el tiempo es mejor usar métodos graficos, si por ejemplo creamos un contro, activex que tiene una forma rara y queremos darle un sombreado perimetral es mejor usar el método line para dibujarlo que el control line, las líneas no son persistentes, entonces todo lo que tendríamos que hacer es colocar el redibujado en el rutina 'paint' del control activex, cada vez que se redibuje se crearán las líneas, y se redibuja cada vez que se coloca en primer plano o se expone parte de él aemás de cuando lo llamamos explícitamente con control.refresh o desde el código interno al mçétodo 'paint'.

Para terminar... se puede crear una estructura que refleje el comportamiento similar al shape pero usado desde los contendores, esto es ya sabemos que propiedades utiliza el contendor para los métodos gráficos, a saber:
Código: Text
  1.  
  2. public type MiShape
  3.      ' Nombre as string  ' se podría usar para identificarlo por nombre en vez de por índice
  4.      DrawMode as DrawModeConstants  ' se pueden usar en la forma vbXorPen...
  5.      DrawStyle as DrawStyleConstants
  6.      DrawWidth as byte
  7.      FillColor as long
  8.      FillStyle as FillStyleConstants
  9.      X1 as single
  10.      X2 as single
  11.      Y1 as single
  12.      Y2 as single
  13.      Operacion as boolean  ' true=dibujar, false=borrar
  14.      HdcContenedor as long  '(el HDC del contendor) para saber a quien pertence.
  15. end type
  16. dim Shapes() as MiShape
  17. dim tmp as Mishape   ' para cambios temporales
  18.  
  19.  

Bien con esta estructura y parte de los métodos que ya describimos más arriba podríamos usarlo desde los contendores, para manejar cada línea cicculo ocuadro que manejemos, por ejemplo si queremos dibujar un círculo rellenamos los valores en un índice de la estructura, y llamamos a la rutnina dibujarCirculo (que sería similar a la que pusimos más arriba DibujarCuadro) pero con 1 parámetros más, el índice del control, entonces tendríamos otra rutina que sería dibujarlo en otro lado, esta rutina recibiría el parámetro 'x' que identifica el índice y las nuevas coordenadas y lo que haríamos dentro de esa rutina sería borrar shapes(x) de su ubicación actual  cambiar valores de posición según parámetros entrados y llamar a la rutina de dibujado....

Como ahora nuestro gráficos tiene valores asignados y por tanto hay 'memoria' de ellos podremos ahorrarnos el autoredraw, del contenedor y lo que haríamos sería colocar dentro del evento Paint del formulario un bucle que llamara a redibujar todos los 'objetos' que hay dentro de neustr matriz Shapes()
Código: Text
  1.  
  2. Private Sub Form_Paint()
  3.     Me.Line (3000, 6000)-(6000, 3000), Form2.FillColor, BF ' ejemplo a falta de otra cosa...
  4.    for k=0 to ubound(Shapes)
  5.        call Dibujar_MiGrafico(k)    ' esta funcion sería para redibujar cuanlquier gráfico en la matriz con sus valores actuales, por tanto le bastaría con usar un identificador, en este caso el índice...
  6.    next
  7. End Sub
  8.  
  9.  


Claro que todo esto último se haría mejor como una clase para controlar todos sus métodos y no confundirse y mezclarse con el código del formulario, o mejor aún en un control activex, con lo cual ya tendríamos una emulación del control shape pero con la particularidad de que podríamos condicionarlo a nuestras necesidades, por ejemplo para crear polígonos dado el nº de lados.

nota final: los métodos gráficos sólo se rellenan si están cerradas, si por ejemplo usas un arco no se cierra, a no ser que lo 'tapes' con una línea... line se rellena con el parámetro BF, la B indica que es un cuadro no una línea y la F que se rellena...
«Ma non troppo»
----> ModoVacaciones = False<----