Autor Tema: UserControl con Fondo Transparente, solo funciona la primera instancia  (Leído 53 veces)

0 Usuarios y 1 Visitante están viendo este tema.

TOLO68

  • Bytes
  • *
  • Mensajes: 36
  • Reputación: +2/-0
    • Ver Perfil
Hola a Todo el foro

Despues de varios meses de ausencia estoy por aqui otra vez
:)


Estoy intentando hacer un control con fondo transparente

las propiedades del usercontrol son:


   Autoredraw = True
   BackStyle = Opaque
   ControlContainer = True
   ClipControls = True



Nota: BackStyle = Transparent, no me sirve porque no puedo pintar en el en las zonas transparentes
y si le hago una mascara con maskpicture, no va bien para pintar con GDI+ para el antialias


el codigo del control es el siguiente:

-------------------------------------------------------------------

Private Declare Function BitBlt Lib "gdi32" _
   (ByVal hDestDC As Long, _
   ByVal x As Long, ByVal y As Long, _
   ByVal nWidth As Long, ByVal nHeight As Long, _
   ByVal hSrcDC As Long, _
   ByVal xSrc As Long, ByVal ySrc As Long, _
   ByVal dwRop As Long) As Long

Private Sub UserControl_Resize()
    MakeUCTransparent
    UserControl.Line (0, 0)-(100, 100), vbBlack
End Sub


Private Sub MakeUCTransparent()

   Dim ctl As Control
   Dim h1 As Long, h2 As Long
   
    h1 = UserControl.Extender.Container.hDC

    '  get offsets for BitBlt.
    Dim dL As Long: dL = UserControl.Extender.Left
    Dim dT As Long: dT = UserControl.Extender.Top
    Dim dW As Long: dW = UserControl.ScaleWidth
    Dim dH As Long: dH = UserControl.ScaleHeight
   
    '  Copy background to our usercontrol hDC.
    Call BitBlt(UserControl.hDC, 0, 0, dW, dH, h1, dL, dT, vbSrcCopy)
End Sub

-------------------------------------------------------------------

La cuestion es que cuando el primer UserControl en el Form va bien,
porque captura la imagen del Form y con BitBlt la dibuja en el control,...
pero cuando dentro el primer UserControl quiero meter otro UserControl (el mismo que el primero)
me da error 438 (El objeto no admite esta propiedad o método)


He leido en algunos ejemplos que se podria hacer con la API GetDC, GetWindowDC o algunas mas, pero no funcionan bien.

Seguro que algun genio de los que hay por el foro, seguramente lo podra solucionar

Saludos y gracias a todos








LeandroA

  • Administrador
  • Petabyte
  • *****
  • Mensajes: 1072
  • Reputación: +147/-8
    • Ver Perfil
Re:UserControl con Fondo Transparente, solo funciona la primera instancia
« Respuesta #1 en: Octubre 10, 2017, 06:51:19 am »
hola Tolo por lo visto tu error es hacer referencia al hdc del contenedor y no todos los controles tienen hdc tal como es el caso del Frame, una solución es con apis obtener el hwnd del parent (GetParent) del usercontrol y luego el hdc (GetDC) de este.

Código: [Seleccionar]
Private Declare Function BitBlt Lib "gdi32" _
   (ByVal hDestDC As Long, _
   ByVal x As Long, ByVal y As Long, _
   ByVal nWidth As Long, ByVal nHeight As Long, _
   ByVal hSrcDC As Long, _
   ByVal xSrc As Long, ByVal ySrc As Long, _
   ByVal dwRop As Long) As Long
Private Declare Function GetDC Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function ReleaseDC Lib "user32.dll" (ByVal hwnd As Long, ByVal hdc As Long) As Long
Private Declare Function GetParent Lib "user32.dll" (ByVal hwnd As Long) As Long


Private Sub UserControl_Resize()
    MakeUCTransparent
    UserControl.Line (0, 0)-(100, 100), vbBlack
End Sub


Private Sub MakeUCTransparent()

   Dim ctl As Control
   Dim h1 As Long, h2 As Long
   Dim ParentHwnd As Long

    ParentHwnd = GetParent(UserControl.hwnd)
    h1 = GetDC(ParentHwnd)

    '  get offsets for BitBlt.
    Dim dL As Long: dL = UserControl.Extender.Left
    Dim dT As Long: dT = UserControl.Extender.Top
    Dim dW As Long: dW = UserControl.ScaleWidth
    Dim dH As Long: dH = UserControl.ScaleHeight
   
    '  Copy background to our usercontrol hDC.
    Call BitBlt(UserControl.hdc, 0, 0, dW, dH, h1, dL, dT, vbSrcCopy)
   
    ReleaseDC ParentHwnd, h1
End Sub

De todas formas no encuentro sentido a esto, dudo que esto funcione como vos queres, creo que para lo que vos buscas lograr vas a tener que utilizar ventanas windowless (seria lo mismo que el control ucImage) pero no puede ser ControlContainer.



TOLO68

  • Bytes
  • *
  • Mensajes: 36
  • Reputación: +2/-0
    • Ver Perfil
Re:UserControl con Fondo Transparente, solo funciona la primera instancia
« Respuesta #2 en: Octubre 10, 2017, 09:20:33 am »
Hola de nuevo

Leandro el  codigo que me has enviado no me ha funcionado :(

Aveces me coge la imagen de lo que se ve en pantalla

Te explico lo que quiero hacer

Practicamente lo que quiero es hacer un control igual que el picturebox normal, pero que coja el fondo de su contenedor, que este si tiene hdc

no necesito frames, ni otros controles que no tengan hdc

imagina que tienes un Form con una imagen
en ese form colocas un picturebox1 y en vez de ser color gris, te pone el fondo de lo que hay justo debajo de ese picturebox, en ese caso el dibujo o imagen del Form

esto funciona con el ejemplo que te puse, ademas puedes dibujar en ese picturebox con lineas, pset, (incluso con gdiplus) para el antialias, no se si probaste el codigo que te envie

ahora imagina que dentro este primer picturebox1, le pongo otro picturebox2, y que en este picturebox2 de fondo me ponga lo que tiene pintado el picturebox1, que seria en ese caso el mismo dibujo que el form1

pero si en picture1 le pongo una imagen por ej de un auto, en el picturebox 2 tiene que salir la imagen del auto
porque el picturebox2 captura la imagen de su contenedor que en ese caso es picturebox1

no se si me explico

lo probe con

usercontrol.picture= UserControl.Extender.Container.image y
usercontrol.picture= UserControl.Extender.Container.picture

pero da un error que no me acuerdo cual es

bueno, yo seguire investigando a ver si puedo conseguirlo.

Gracias a todos de todas formas