AlphaBlend traer desde otra ventana

Leandro
04 de Junio del 2006
Hola tengo un problema y no le encuentro la vuelta estoy usando el api AlphaBlend (en esta pagina hay un ejemplo) bien a la hora de usarlo con dos pictures en el mismo form, funciona bien, pero yo intento traer el efecto de transparencia desde otro lugar por ejemplo form2.hdc y digamos que funciona pero el problema viene que esta ventana deve estar visible cosa que si lo hago con los dos pictures del mismo formulario no es nesesario, si pruevan el ejemplo que pongo a continuacion veran que si superpongo el form1 sobre el form2 este tomara el efecto de transparencia tomara parte del form1 o cualquier cosa que se sobreponga sobre el form2 entonces no encuentro la solucion para evitar esto, quizas y no soy muy entendido en el tema sea nesesario aplicar algun Byval pero estoy perdido

para provar agreguen tres picture , dos formularios y command1


Option Explicit


'Cada control debe tener una imagen, ambas deben ser distintas
Const AC_SRC_OVER = &H0
Private Type BLENDFUNCTION
BlendOp As Byte
BlendFlags As Byte
SourceConstantAlpha As Byte
AlphaFormat As Byte
End Type
Private Declare Function AlphaBlend Lib "msimg32.dll" (ByVal hdc As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal hdc As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal lInt As Long, ByVal BLENDFUNCT As Long) As Long
Private Declare Sub RtlMoveMemory Lib "kernel32.dll" (Destination As Any, Source As Any, ByVal Length As Long)

Private Sub Command1_Click()

Dim BF As BLENDFUNCTION, lBF As Long

'Cambiar el modo gráfico para que se mantenga la imagen
Picture1.AutoRedraw = True
Picture2.AutoRedraw = True
Picture3.AutoRedraw = True

Picture1.ScaleMode = vbPixels
Picture2.ScaleMode = vbPixels
Picture3.ScaleMode = vbPixels
Form2.ScaleMode = vbPixels
'asignar los parámetros
With BF
.BlendOp = AC_SRC_OVER
.BlendFlags = 0
.SourceConstantAlpha = 128
.AlphaFormat = 0
End With

'copia la función blend a una variable en memoria de tipo long
RtlMoveMemory lBF, BF, 4

'aplicar la Api desde la picture1 sobre la picture2
AlphaBlend Picture2.hdc, 50, 0, 100, 100, Picture1.hdc, 0, 0, Picture1.ScaleWidth, Picture1.ScaleHeight, lBF
Picture2.Refresh
'aplicar la Api desde la form2 sobre el picture3

'********** aca se me complica la cosa**************
AlphaBlend Picture3.hdc, 50, 0, 100, 100, Form2.hdc, 0, 0, Form2.ScaleWidth, Form2.ScaleHeight, lBF
Picture3.Refresh
End Sub

Private Sub Form_Load()
Form2.Show
Form2.BackColor = vbRed
End Sub

Covatex
04 de Junio del 2006
Deberias probar en lugar de usar pictureboxes, manejar los bitmaps en memoria con la api de windows. Lo que pasa es que VB maneja los hdc de sus controles... y cuando no esta visible un control, de alguna manera limpia el hdc. Incluso cuando haces un resize de un control, su hdc se modifica. Entonces al cargar un grafico mas grande que el control, este se corta.
Proba esto:
Public Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Public Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
Public Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long

Public Function LoadGraphicDC(sFileName As String) As Long
Dim LoadGraphicDCTEMP As Long
LoadGraphicDCTEMP = CreateCompatibleDC(GetDC(0))
SelectObject LoadGraphicDCTEMP, LoadPicture(sFileName)
LoadGraphicDC = LoadGraphicDCTEMP
End Function

Acordate despues de terminar de usar los bitmaps, llamar a la funcion DeleteDC() con el handler recien creado.
Espero que te sirva