elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP)
| | | |-+  Programación Visual Basic (Moderadores: LeandroA, seba123neo)
| | | | |-+  Como puedo semitransparentar un picturebox o parte de un form?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Como puedo semitransparentar un picturebox o parte de un form?  (Leído 5,899 veces)
okik


Desconectado Desconectado

Mensajes: 462


Ver Perfil
Como puedo semitransparentar un picturebox o parte de un form?
« en: 16 Marzo 2015, 19:40 pm »

Hola
Llevo tiempo intentando semitransparentar un picture o una sólo una parte de un formulario. A día de hoy no lo he conseguido. No me importa que sea con vb6 o vb.net


He hecho un poquito de trampa, para simular el efecto. Aquí dejo una muestra de lo que quiero. Pero repito, que sólo simula el efecto.

1 Formulario: Form1
1 Formulario: Form2 (establecer como BorderStyle=0)
1 PictureBox en Form1
1 PictureBox en Form2
1 Control Timer en el Form1: Timer1


En un MÓDULO:

Código
  1. Option Explicit
  2. Private Declare Function EnableWindow Lib "user32" (ByVal hwnd As Long, ByVal fEnable As Long) As Long
  3. 'Obtiene posición de una ventana u objeto
  4. Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hwnd As Long, lpRect As RECT) As Long
  5. Private Type RECT
  6.  Left As Long
  7.  Top As Long
  8.  Right As Long
  9.  Bottom As Long
  10. End Type
  11.  
  12. Private Declare Function SetLayeredWindowAttributes Lib "user32" (ByVal hwnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
  13. Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
  14. Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
  15. Private Const GWL_EXSTYLE = (-20)
  16. Private Const LWA_ALPHA = &H2
  17. Private Const WS_EX_LAYERED = &H80000
  18.  
  19.  
  20. Public Function CreateObjectTransparent(ByVal frmMain As Form, ByVal frmObj As Form, objPic As PictureBox, ByVal Alpha As Integer)
  21. Dim i
  22. frmObj.Show
  23. frmObj.ZOrder 1
  24. Transparencia frmObj.hwnd, Alpha
  25. objPic.BackColor = &HFF00FF
  26. AnularColor frmMain.hwnd, &HFF00FF
  27. EnableWindow frmObj.hwnd, 0
  28.  
  29. End Function
  30. 'Función que aplica la transparencia, se le pasa el hwnd del form y un valor de 0 a 100
  31. Public Function Transparencia(ByVal hwnd As Long, NivelTrans As Integer) As Long
  32. Dim X As Long
  33. On Error Resume Next
  34. NivelTrans = (NivelTrans * 255) / 100
  35.  
  36.   X = GetWindowLong(hwnd, GWL_EXSTYLE)
  37.   X = X Or WS_EX_LAYERED
  38.   SetWindowLong hwnd, GWL_EXSTYLE, X
  39.   'Establece la transparencia
  40.   SetLayeredWindowAttributes hwnd, 0, NivelTrans, LWA_ALPHA
  41.  
  42. If Err Then
  43.   Transparencia = 2
  44. End If
  45. End Function
  46. 'Función que aplica la transparencia, se le pasa el hwnd del form y un valor de 0 a 255
  47. Public Function AnularColor(ByVal hwnd As Long, Color As Long) As Long
  48. Dim X As Long
  49. On Error Resume Next
  50.       X = GetWindowLong(hwnd, GWL_EXSTYLE)
  51.       X = X Or WS_EX_LAYERED
  52.       SetWindowLong hwnd, GWL_EXSTYLE, X
  53.       'Establece la transparencia
  54.       SetLayeredWindowAttributes hwnd, Color, 0, &H1
  55.       AnularColor = 0
  56. If Err Then
  57. AnularColor = 2
  58. End If
  59. End Function
  60.  
  61.  
  62. Public Sub ResizeOjb(ByVal objPic As PictureBox, ByVal frmObj As Form)
  63. Dim r As RECT, s As RECT, N
  64. N = GetWindowRect(objPic.hwnd, r)
  65. frmObj.Move r.Left * 15 - 200, r.Top * 15 - 200, objPic.Width + 400, objPic.Height + 400
  66. End Sub
  67.  



En un FORMULARIO:

Código
  1. Private Sub Form_Load()
  2. Form2.Picture1.BackColor = vbBlack
  3. CreateObjectTransparent Form1, Form2, Picture1, 50
  4. End Sub
  5.  
  6. Private Sub Form_Unload(Cancel As Integer)
  7. Unload Form2
  8. End Sub
  9.  
  10. Private Sub Timer1_Timer()
  11. ResizeOjb Picture1, Form2
  12. End Sub
  13.  


Lo que hago es transparentar completamente el Picture1 del Form1 y luego semitransparentar el Form2 que contiene otro Picture. Obtengo la posición del Picture1 del Form1 y muevo y redimiensiono el Form2 al Picture1 del Form1. Coloco el Form2 debajo del Form1 y de esta manera creo el efecto de semitransperancia tan solo en un parte del Form1. Ademas he agrandado un poco el Form2 con respecto al Picture1 del Form1 para que al mover el formulario no se formen huecos ya que al mover muy rápido no le da tiempo a recolocar el Form2, lo bastante como para que se vean huecos si se mueve demasaido rápido

Este método que he utilizado NO me permite interactuar con el PictureBox semitransparente. Si que es posible quitando "EnableWindow frmObj.hwnd, 0" pero entonces al hacer clic en el Picture del Form2, éste se coloca delante del Form1. Ya he probado Zorder. No sirve queda un poco chapucero.

Esto  lo pongo como ejemplo pero no es lo que quiero. Lo ideal sería poder solo semitranspertentar una parte del Form o un Picture.



Saludos.


==============
Esto es una imagen que encontré googleando. Algo así me hiría de miedo. Como se ve en la imagen los controles no son transparentes pero el form sí.






« Última modificación: 17 Marzo 2015, 13:29 pm por okik » En línea

RIVASBROTHERS

Desconectado Desconectado

Mensajes: 1


Ver Perfil
Re: Como puedo semitransparentar un picturebox o parte de un form?
« Respuesta #1 en: 5 Mayo 2017, 21:50 pm »

Antes que todo disculparme por que la respuesta esta en C#, pero para lograr su objetivo puede hacer uso de la propiedad WS_EX_LAYERED, algo como esto:

Código
  1.  
  2. public const int WS_EX_LAYERED = 0x00080000;
  3.  
  4. protected override CreateParams CreateParams
  5. {
  6.    get
  7.    {
  8.        CreateParams createParams = base.CreateParams;
  9.  
  10.        if (DesignMode) return createParams;
  11.  
  12.        //Habilita el modo transparente del formulario
  13.        createParams.ExStyle |= WS_EX_LAYERED;
  14.        return createParams;
  15.    }
  16. }
  17.  
  18.  

Y luego dibujar los grafico sobre un bitmap y dibujar este bitmap sobre el formulario a través de un metodo de dibujo especial tal como se muestra en este articulo https://www.codeproject.com/Articles/1822/Per-Pixel-Alpha-Blend-in-C, puede hacerlo de esta manera:

Código
  1.  
  2. //Ejecuta el evento al cargar el formulario
  3. protected override void OnLoad(EventArgs e)
  4. {
  5.    base.OnLoad(e);
  6.    HandledPaintEvent();
  7. }
  8.  
  9. private void HandledPaintEvent()
  10. {
  11.    var rect = new Rectangle(Point.Empty, this.Size);
  12.    //Crea un objeto bitmap y obtiene los graficos
  13.    var bmp = new Bitmap(this.Width, this.Height, PixelFormat.Format32bppArgb);
  14.    using (Graphics g = Graphics.FromImage(bmp))
  15.    {
  16.        //Dibuja el fondo del form
  17.        using (LinearGradientBrush br = new LinearGradientBrush(ClientRectangle, Color.Red, Color.Transparent, LinearGradientMode.Vertical))
  18.        {
  19.            g.FillRectangle(br, rect);
  20.        }
  21.    }
  22.  
  23.    //Dibuja los controles sobre el bitmap
  24.    foreach (Control c in this.Controls)
  25.    {
  26.        if (c.Visible)
  27.        {
  28.            c.DrawToBitmap(bmp, c.Bounds);
  29.        }
  30.    }
  31.  
  32.    //Metodo para dibujar el bitmap sobre el form  (Mas Info: https://www.codeproject.com/Articles/1822/Per-Pixel-Alpha-Blend-in-C)
  33.    this.SetBitmap(bmp, 100);
  34. }
  35.  


De esta manera obtiene el mismo resultado de la imagen que encontro en google:



Los problemas que se presentan son los siguientes:

*Se debe redibujar el bitmap cada vez que el formulario cambia de tamaño o ejecute un evento importante que requiera redibujo.
*Los controles quedan estaticos a menos que actualice el bitmap cada vez que se ejecute un evento  mouseHover, mouseLeave o mouseDown sobre cada control.
*El metodo DrawToBitmap no soporta transparencia por ello aunque se asigna el fondo transparente a cada control siempre devuelve el fondo por defecto que tendria el formulario en el caso que no fuera WS_EX_LAYERED.

Saludos desde El Salvador.


« Última modificación: 5 Mayo 2017, 22:08 pm por RIVASBROTHERS » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.885



Ver Perfil
Re: Como puedo semitransparentar un picturebox o parte de un form?
« Respuesta #2 en: 6 Mayo 2017, 11:00 am »

Llevo tiempo intentando semitransparentar un picture o una sólo una parte de un formulario. A día de hoy no lo he conseguido. No me importa que sea con vb6 o vb.net

Vamos a ver. Empieza por intentar explicar con más detalle lo que que quieres hacer. Podrías mostrar una imagen para comprender mejor tus intenciones, puesto que "semi transparentar un picture" se puede interpretar de muchas maneras (y estoy hartísimo de repetir la falta de información al formular preguntas de programación), y no queda claro si al Form también quieres que se le aplique una transparencia o no.

En VB.NET puedes utilizar las propiedades Form.Opacity, Form.TransparencyKey y Form.Region/Control.Region para llevar a cabo funcionalidades de transparencia, todo ello sin necesidad de declarar cientos de p/invokes, aunque según para qué... si que podrías necesitar recurrir al uso de código no administrado, pero generálmente te debería sobrar haciendo uso de las propiedades mencionadas.

Si lo que quieres es volver semi transparente la imagen representada dentro de un PictureBox, pues sencillamente lo que debes hacer es eso, modificar la opacidad de los píxeles de la imagen (disminuir el valor del canal alpha del ARGB), y listo. Para ello puedes aplicarle una matríz de color (clase: ColorMatrix), o también puedes iterar los píxeles de la imagen mediante la metodología Bitmap.LockBits() o también mediante Bitmap.GetPixel().

Te muestro un ejemplo del resultado:



...Pero como ya he dicho al principio de este comentario, no sé si eso es realmente lo que querrás hacer, así que aquí finalizo mi respuesta a menos que se entregue información más elaborada por tu parte (una imagen vale más que mil palabras, como puedes ver).

¡Saludos!
« Última modificación: 6 Mayo 2017, 11:33 am por Eleкtro » En línea



Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.885



Ver Perfil
Re: Como puedo semitransparentar un picturebox o parte de un form?
« Respuesta #3 en: 6 Mayo 2017, 22:04 pm »

Pf... qué tonto de mi, acabo de darme cuenta que este post se publicó en el año 2015. Puesto que okik es un usuario activo, no me fijé en la fecha de publicación.

@RIVASBROTHERS por favor la próxima vez revisa la fecha del post antes de revivirlo. Como comprenderás no tiene mucho sentido invertir tiempo y esfuerzo en escribirle un código a alguien para responderle dos años despues a un tema que probablemente ya habrá solucionado o habrá dejado de interesarle. Además, revivir temas antiguos está prohibido por las reglas.

Cierro el tema.
« Última modificación: 6 Mayo 2017, 22:13 pm por Eleкtro » En línea



Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines