Results 1 to 6 of 6

Thread: [RESOLVED] UpdateLayeredWindow - help!

  1. #1

    Thread Starter
    Addicted Member Latin4567's Avatar
    Join Date
    Jan 2005
    Posts
    202

    Resolved [RESOLVED] UpdateLayeredWindow - help!

    I am trying to accomplish an effect similar to programs like Konfabulator and DesktopX which use the UpdateLayeredWindow API to achieve vista-like window layering. I need to create a translucent form with ranging alpha values based on a png image. So basically, I have want to be able to create custom forms which support alpha-blending directly to the desktop. (I am NOT trying to simply change the opacity of a form).

    MSDN Library briefly explains in the documentation for the UpdateLayeredWindow API how to do this but I cant get it to work, mostly because my lack of experience with api's. Perhaps someone can make sense of it: http://msdn.microsoft.com/library/de...eredwindow.asp

    So here's my question(s):

    How do you use pointers (IntPtr) to pass objects to an API

    How do you pass objects like the RECT structure to an API, because visual basic doesnt have a RECT structure... it has the rectangle type

    Here is my code... The api is encountering errors so it is returning false... Could someone please help me fix this/get it to work?

    VB Code:
    1. Public Class Form1
    2.     Private Structure BLENDFUNCTION
    3.         Public BlendOp As Byte
    4.         Public BlendFlags As Byte
    5.         Public SourceConstantAlpha As Byte
    6.         Public AlphaFormat As Byte
    7.     End Structure
    8.  
    9.     'AlphaFormat flags
    10.     Private Const AC_SRC_OVER As Long = &H0&
    11.     Private Const AC_SRC_ALPHA = &H1
    12.  
    13.     Private Declare Function UpdateLayeredWindow Lib "user32" Alias "UpdateLayeredWindow" (ByVal hwnd As Long, ByVal hdcDst As Long, ByVal pptDst As Object, ByVal psize As Object, ByVal hdcSrc As Long, ByVal pptSrc As Object, ByVal crKey As Long, ByVal pblend As BLENDFUNCTION, ByVal dwFlags As Long) As Long
    14.  
    15.     Private Const ULW_COLORKEY As Long = &H1&
    16.     Private Const ULW_ALPHA As Long = &H2&
    17.     Private Const ULW_OPAQUE As Long = &H4&
    18.  
    19.     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    20.         Me.Opacity = 0.9 'set the opacity to somthing to its a layered window...
    21.  
    22.  
    23.     End Sub
    24.     Dim Graphics As Graphics
    25.     Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
    26.         e.Graphics.Clear(Color.Transparent) 'I cant figure out how to create a graphics objet because they have no constructors so I am using the form's graphics object instead...
    27.         e.Graphics.DrawImage(My.Resources.alpha, New Point(0, 0)) 'the multi-alpha-channel png image that we want the form to look like
    28.  
    29.  
    30.         Dim blend As BLENDFUNCTION
    31.         blend.AlphaFormat = AC_SRC_OVER
    32.         blend.SourceConstantAlpha = 0
    33.         blend.BlendFlags = 0
    34.         blend.BlendOp = AC_SRC_OVER
    35.  
    36.  
    37.  
    38.         If UpdateLayeredWindow(Me.Handle, 0&, 0&, 0&, 0&, e.Graphics.GetHdc(), 0&, blend, ULW_ALPHA) = True Then
    39.             MsgBox("it worked")
    40.         Else
    41.             MsgBox("there was an error") 'it is throwing errors at this point... i havnt gotten it to work yet
    42.         End If
    43.  
    44.     End Sub
    45. End Class

  2. #2
    Frenzied Member dynamic_sysop's Avatar
    Join Date
    Jun 2003
    Location
    Ashby, Leicestershire.
    Posts
    1,142

    Re: UpdateLayeredWindow - help!

    here's a link to a C# example on the codeproject >> link <<
    it shouldn't be to hard to translate to vb.net
    ~
    if a post is resolved, please mark it as [Resolved]
    protected string get_Signature(){return Censored;}
    [vbcode][php] please use code tags when posting any code [/php][/vbcode]

  3. #3

    Thread Starter
    Addicted Member Latin4567's Avatar
    Join Date
    Jan 2005
    Posts
    202

    Re: UpdateLayeredWindow - help!

    Ive seen it... I guess I could try translating it...

  4. #4

    Thread Starter
    Addicted Member Latin4567's Avatar
    Join Date
    Jan 2005
    Posts
    202

    Question Re: UpdateLayeredWindow - help!

    Ok, I have completely converted the C# code to visual basic (im using the beta). I am getting some errors though.

    Here is the C# code I am trying to convert:
    VB Code:
    1. ;
    2. // class that exposes needed win32 gdi functions.
    3. class Win32
    4. {
    5.     public enum Bool
    6.     {
    7.         False= 0,
    8.         True
    9.     };
    10.  
    11.  
    12.     [StructLayout(LayoutKind.Sequential)]
    13.     public struct Point
    14.     {
    15.         public Int32 x;
    16.         public Int32 y;
    17.  
    18.         public Point(Int32 x, Int32 y) { this.x= x; this.y= y; }
    19.     }
    20.  
    21.  
    22.     [StructLayout(LayoutKind.Sequential)]
    23.     public struct Size {
    24.         public Int32 cx;
    25.         public Int32 cy;
    26.  
    27.         public Size(Int32 cx, Int32 cy) { this.cx= cx; this.cy= cy; }
    28.     }
    29.  
    30.  
    31.     [StructLayout(LayoutKind.Sequential, Pack=1)]
    32.     struct ARGB
    33.     {
    34.         public byte Blue;
    35.         public byte Green;
    36.         public byte Red;
    37.         public byte Alpha;
    38.     }
    39.  
    40.  
    41.     [StructLayout(LayoutKind.Sequential, Pack=1)]
    42.     public struct BLENDFUNCTION
    43.     {
    44.         public byte BlendOp;
    45.         public byte BlendFlags;
    46.         public byte SourceConstantAlpha;
    47.         public byte AlphaFormat;
    48.     }
    49.  
    50.  
    51.     public const Int32 ULW_COLORKEY = 0x00000001;
    52.     public const Int32 ULW_ALPHA    = 0x00000002;
    53.     public const Int32 ULW_OPAQUE   = 0x00000004;
    54.  
    55.     public const byte AC_SRC_OVER  = 0x00;
    56.     public const byte AC_SRC_ALPHA = 0x01;
    57.  
    58.  
    59.     [DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]
    60.     public static extern Bool UpdateLayeredWindow(IntPtr hwnd, IntPtr hdcDst, ref Point pptDst, ref Size psize, IntPtr hdcSrc, ref Point pprSrc, Int32 crKey, ref BLENDFUNCTION pblend, Int32 dwFlags);
    61.  
    62.     [DllImport("user32.dll", ExactSpelling=true, SetLastError=true)]
    63.     public static extern IntPtr GetDC(IntPtr hWnd);
    64.  
    65.     [DllImport("user32.dll", ExactSpelling=true)]
    66.     public static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC);
    67.  
    68.     [DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
    69.     public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
    70.  
    71.     [DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
    72.     public static extern Bool DeleteDC(IntPtr hdc);
    73.  
    74.     [DllImport("gdi32.dll", ExactSpelling=true)]
    75.     public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
    76.  
    77.     [DllImport("gdi32.dll", ExactSpelling=true, SetLastError=true)]
    78.     public static extern Bool DeleteObject(IntPtr hObject);
    79. }
    80.  
    81.  
    82.  
    83. /// <para>Your PerPixel form should inherit this class</para>
    84. /// <author><name>Rui Godinho Lopes</name><email>[email protected]</email></author>
    85. class PerPixelAlphaForm : Form
    86. {
    87.     public PerPixelAlphaForm()
    88.     {
    89.         // This form should not have a border or else Windows will clip it.
    90.         FormBorderStyle = FormBorderStyle.None;
    91.     }
    92.  
    93.  
    94.     /// <para>Changes the current bitmap.</para>
    95.     public void SetBitmap(Bitmap bitmap)
    96.     {
    97.         SetBitmap(bitmap, 255);
    98.     }
    99.  
    100.  
    101.     /// <para>Changes the current bitmap with a custom opacity level.  Here is where all happens!</para>
    102.     public void SetBitmap(Bitmap bitmap, byte opacity)
    103.     {
    104.         if (bitmap.PixelFormat != PixelFormat.Format32bppArgb)
    105.             throw new ApplicationException("The bitmap must be 32ppp with alpha-channel.");
    106.  
    107.         // The ideia of this is very simple,
    108.         // 1. Create a compatible DC with screen;
    109.         // 2. Select the bitmap with 32bpp with alpha-channel in the compatible DC;
    110.         // 3. Call the UpdateLayeredWindow.
    111.  
    112.         IntPtr screenDc = Win32.GetDC(IntPtr.Zero);
    113.         IntPtr memDc = Win32.CreateCompatibleDC(screenDc);
    114.         IntPtr hBitmap = IntPtr.Zero;
    115.         IntPtr oldBitmap = IntPtr.Zero;
    116.  
    117.         try {
    118.             hBitmap = bitmap.GetHbitmap(Color.FromArgb(0));  // grab a GDI handle from this GDI+ bitmap
    119.             oldBitmap = Win32.SelectObject(memDc, hBitmap);
    120.  
    121.             Win32.Size size = new Win32.Size(bitmap.Width, bitmap.Height);
    122.             Win32.Point pointSource = new Win32.Point(0, 0);
    123.             Win32.Point topPos = new Win32.Point(Left, Top);
    124.             Win32.BLENDFUNCTION blend = new Win32.BLENDFUNCTION();
    125.             blend.BlendOp             = Win32.AC_SRC_OVER;
    126.             blend.BlendFlags          = 0;
    127.             blend.SourceConstantAlpha = opacity;
    128.             blend.AlphaFormat         = Win32.AC_SRC_ALPHA;
    129.  
    130.             Win32.UpdateLayeredWindow(Handle, screenDc, ref topPos, ref size, memDc, ref pointSource, 0, ref blend, Win32.ULW_ALPHA);
    131.         }
    132.         finally {
    133.             Win32.ReleaseDC(IntPtr.Zero, screenDc);
    134.             if (hBitmap != IntPtr.Zero) {
    135.                 Win32.SelectObject(memDc, oldBitmap);
    136.                 //Windows.DeleteObject(hBitmap); // The documentation says that we have to use the Windows.DeleteObject... but since there is no such method I use the normal DeleteObject from Win32 GDI and it's working fine without any resource leak.
    137.                 Win32.DeleteObject(hBitmap);
    138.             }
    139.             Win32.DeleteDC(memDc);
    140.         }
    141.     }
    142.  
    143.  
    144.     protected override CreateParams CreateParams
    145.     {
    146.         get {
    147.             CreateParams cp = base.CreateParams;
    148.             cp.ExStyle |= 0x00080000; // This form has to have the WS_EX_LAYERED extended style
    149.             return cp;
    150.         }
    151.     }
    152. }

    Here is my visual basic version which has some errors:

    VB Code:
    1. Public Class Win32API
    2.     Public Enum Bool
    3.         iFalse = 0
    4.         iTrue = 1
    5.     End Enum
    6.  
    7.  
    8.  
    9.     <StructLayout(LayoutKind.Sequential)> _
    10.     Public Structure Point
    11.         Public x As Int32
    12.         Public y As Int32
    13.  
    14.         Public Sub New(ByVal cx As Int32, ByVal cy As Int32)
    15.             x = cx
    16.             y = cy
    17.         End Sub
    18.     End Structure
    19.  
    20.  
    21.     <StructLayout(LayoutKind.Sequential)> _
    22.     Public Structure Size
    23.         Public cx As Int32
    24.         Public cy As Int32
    25.  
    26.         Public Sub New(ByVal x As Int32, ByVal y As Int32)
    27.             cx = x
    28.             cy = y
    29.         End Sub
    30.     End Structure
    31.  
    32.  
    33.     Structure ARGB
    34.         Public Blue As Byte
    35.         Public Green As Byte
    36.         Public Red As Byte
    37.         Public Alpha As Byte
    38.     End Structure
    39.  
    40.  
    41.     Public Structure BLENDFUNCTION
    42.         Public BlendOp As Byte
    43.         Public BlendFlags As Byte
    44.         Public SourceConstantAlpha As Byte
    45.         Public AlphaFormat As Byte
    46.     End Structure
    47.  
    48.  
    49.  
    50.     Public Const ULW_COLORKEY As Byte = &H1
    51.  
    52.     Public Const ULW_ALPHA As Byte = &H2
    53.     Public Const ULW_OPAQUE As Byte = &H4
    54.  
    55.     Public Const AC_SRC_OVER As Byte = &H0&
    56.     Public Const AC_SRC_ALPHA As Byte = &H1
    57.  
    58.     Public Declare Function UpdateLayeredWindow Lib "user32" (ByVal hWnd As Long, ByVal hdcDst As IntPtr, ByVal pptDst As Point, ByVal psize As Size, ByVal hdcSrc As IntPtr, ByVal pptSrc As Point, ByVal crKey As IntPtr, ByVal pblend As BLENDFUNCTION, ByVal dwFlags As IntPtr) As Long
    59.     Public Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
    60.     Public Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hDC As Long) As Long
    61.     Public Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
    62.     Public Declare Function DeleteDC Lib "gdi32" (ByVal hDC As Long) As Long
    63.     Public Declare Function SelectObject Lib "gdi32" (ByVal hDC As Long, ByVal hObject As Long) As Long
    64.     Public Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
    65. End Class
    66.  
    67.  
    68.  
    69. Public Class AlphaForm
    70.     Inherits System.Windows.Forms.Form
    71.     Private alpha As Integer
    72.     Private back As Bitmap
    73.     Sub New(ByVal background As Bitmap, ByVal opacity As Double)
    74.         If background.PixelFormat = Imaging.PixelFormat.Format32bppArgb Then
    75.             back = background
    76.         Else
    77.             MsgBox("The image provided must be a valid 32bppARGB PNG", MsgBoxStyle.Critical, "DuroBlend - Fatal Error")
    78.             Me.Close()
    79.         End If
    80.         If opacity > 1 Then
    81.             opacity = 1
    82.         End If
    83.         If opacity < 0.01 Then
    84.             opacity = 0.01
    85.         End If
    86.         alpha = opacity * 255
    87.         Me.FormBorderStyle = Windows.Forms.FormBorderStyle.None
    88.     End Sub
    89.  
    90.  
    91.     Declare Function GetDesktopWindow Lib "user32" Alias "GetDesktopWindow" () As Integer
    92.     Declare Function GetWindowDC Lib "user32" Alias "GetWindowDC" (ByVal hwnd As Integer) As Integer
    93.     Private Sub AlphaForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    94.         ' I am using the msgboxes to figure out what line the error occures at when im debugging because you cant run control libraries so i am using it in a seperate project
    95.         MsgBox("line1")
    96.         Dim screenDc As IntPtr = GetWindowDC(GetDesktopWindow)
    97.         MsgBox("line2")
    98.         Dim memDc As IntPtr = Win32API.CreateCompatibleDC(screenDc)
    99.         MsgBox("line3")
    100.         Dim hBitmap As IntPtr = 0
    101.         MsgBox("line4")
    102.         Dim oldBitmap As IntPtr = 0
    103.         MsgBox("line5")
    104.         Try
    105.             MsgBox("line6")
    106.             hBitmap = back.GetHbitmap 'color.transparent
    107.             MsgBox("line7")
    108.             oldBitmap = Win32API.SelectObject(memDc, hBitmap)
    109.             MsgBox("line8")
    110.             Dim size As Win32API.Size
    111.             MsgBox("line9")
    112.             size.cx = back.Width
    113.             MsgBox("line10")
    114.             size.cy = back.Height
    115.             MsgBox("line11")
    116.             Dim pointsource As Win32API.Point
    117.             MsgBox("line12")
    118.             pointsource.x = 0
    119.             MsgBox("line13")
    120.             pointsource.y = 0
    121.             MsgBox("line14")
    122.             Dim topPos As Win32API.Point
    123.             MsgBox("line15")
    124.             topPos.x = Me.Left
    125.             MsgBox("line16")
    126.             topPos.y = Me.Top
    127.             MsgBox("line17")
    128.             Dim blend As Win32API.BLENDFUNCTION
    129.             MsgBox("line18")
    130.             blend.BlendOp = Win32API.AC_SRC_OVER
    131.             MsgBox("line19")
    132.             blend.BlendFlags = 0
    133.             MsgBox("line20")
    134.             blend.SourceConstantAlpha = alpha
    135.             MsgBox("line21")
    136.             blend.AlphaFormat = Win32API.AC_SRC_ALPHA
    137.             MsgBox("line22")
    138.  
    139.             Win32API.UpdateLayeredWindow(Me.Handle, screenDc, topPos, size, memDc, pointsource, 0, blend, Win32API.ULW_ALPHA)
    140.             MsgBox("line23")
    141.         Catch ex As Exception
    142.             MsgBox(ex.Message)
    143.         End Try
    144.  
    145.  
    146.  
    147.  
    148.  
    149.  
    150.     End Sub
    151. End Class

    Any help at all is highly appreciated

  5. #5
    I'm about to be a PowerPoster!
    Join Date
    Jan 2005
    Location
    Everywhere
    Posts
    13,647

    Re: UpdateLayeredWindow - help!

    If it is any help I have a nice example from PSC that shows how to do proper Alpha blending using a PNG image. It is in VB6 however but shouldn't be hard to convert. I can upload it later when I'm home.

  6. #6

    Thread Starter
    Addicted Member Latin4567's Avatar
    Join Date
    Jan 2005
    Posts
    202

    Resolved Re: UpdateLayeredWindow - help!

    ok, I sucessfully converted the code using the c# converter at developer fusion. If anyone wants it, pm me.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width