Results 1 to 15 of 15

Thread: Window bitblt

  1. #1

    Thread Starter
    Addicted Member cheesebrother's Avatar
    Join Date
    Jul 2011
    Posts
    153

    Window bitblt

    I've got a cool idea for my game (not really unique, i don't know why i didn't think of it before). What it is is that when you press the "Menu" button on the form a menu appears. The thing which i'd like to do would be to have the whole window fade a bit and then the menu, on a picturebox, would appear with the faded window behind it (by this i mean the contents of the window, of course). So to do this i think that there are two basic steps, one is to somehow get the window into a picturebox which would appear over everything and then draw the faded effect on the picturebox. It's prettymuch like a bitblt from window.hdc to picture1.hdc. How would i make this image, getting all the controls, pictureboxes and their contents... Everything into a picturebox?
    Hooked for good.

  2. #2
    Addicted Member reacen's Avatar
    Join Date
    Jul 2009
    Location
    c:\windows\system32\gdi32.dll
    Posts
    243

    Re: Window bitblt

    I'm sure LaVolpe will be the one to resolve this (as always) just wait for him

    But meanwhile I have a piece of code that can help take screenshots of your window. (Tested on windows xp)

    Please use attached file for the example.
    Attached Files Attached Files
    DoEvents

  3. #3
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Window bitblt

    This is actually much simpler than taking screenshots. With Windows 2000 and above you can make your entire form semi-transparent.

    1. Create a menu in your form's menu editor (Ctrl+E), sample code calls it mnuButton
    :: Add the sub menu items to that menu. Make menu visible = false
    2. In your button's click event copy & pasted the following
    Code:
        Dim lStyle As Long
        ' set layered window attribute & fade window 50%
        lStyle = GetWindowLong(Me.hWnd, GWL_EXSTYLE)
        SetWindowLong Me.hWnd, GWL_EXSTYLE, lStyle Or WS_EX_LAYERED
        ' 128 below = 50%. Set value = (255 * (Percent/100))
        SetLayeredWindowAttributes Me.hWnd, 0&, 128, LWA_ALPHA
        ' show popup menu
        PopupMenu mnuButton
        ' remove layered attribute
        SetWindowLong Me.hWnd, GWL_EXSTYLE, lStyle
        ' tell window it needs to be repainted
        InvalidateRgn Me.hWnd, 0&, 1&
        ' call this to repaint, not Me.Refresh else menus that fade out will leave artifacts on form
        SetWindowPos Me.hWnd, 0&, 0&, 0&, 0&, 0&, SWP_FRAMECHANGED Or SWP_NOMOVE Or SWP_NOSIZE Or SWP_NOZORDER
    Here are the API declarations
    Code:
    Private Declare Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
    Private Declare Function SetLayeredWindowAttributes Lib "user32.dll" (ByVal hWnd As Long, ByVal crKey As Long, ByVal bAlpha As Byte, ByVal dwFlags As Long) As Long
    Private Declare Function SetWindowPos Lib "user32.dll" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
    Private Declare Function InvalidateRgn Lib "user32.dll" (ByVal hWnd As Long, ByVal hRgn As Long, ByVal bErase As Long) As Long
    Private Const SWP_NOMOVE As Long = &H2
    Private Const SWP_NOSIZE As Long = &H1
    Private Const SWP_FRAMECHANGED As Long = &H20
    Private Const SWP_NOZORDER As Long = &H4
    
    
    Private Const GWL_EXSTYLE As Long = -20&
    Private Const WS_EX_LAYERED As Long = &H80000
    Private Const LWA_ALPHA As Long = &H2&
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  4. #4

    Thread Starter
    Addicted Member cheesebrother's Avatar
    Join Date
    Jul 2011
    Posts
    153

    Re: Window bitblt

    Wow, that's really neat! I'd love to use it in some places but it isn't what i'm hoping to do here. Sorry for not being clear. When i said "fade" i meant that black gets mixed in with the window, not that it fades to semitransparent. You've probably seen it in some games where you hit esc and the menu appears. It doesn't cover the whole screen so what it doesn't cover just goes dark. Anothing misunderstanding was the meaning of "menu". by that i mean four or five buttons, new, open, save, exit... not a popupmenu. Anyway i'm glad you misunderstood me because i like the code a lot.

    reacen's getting at it with the screenshot thing. I guess the second question i've got is how to darken the picture after i've got in safe and sound in a picturebox.
    Last edited by cheesebrother; Dec 5th, 2011 at 10:48 AM.
    Hooked for good.

  5. #5
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Window bitblt

    So what exactly is suppose to "go dark"? The entire screen, including your app (except the picturebox to be displayed later)? Just your app? Is your app full screen? Maybe more details could be helpful
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  6. #6

    Thread Starter
    Addicted Member cheesebrother's Avatar
    Join Date
    Jul 2011
    Posts
    153

    Re: Window bitblt

    My app is a sizable form. It can be whatever size. What i want is the space inside the form to go dark. I'll make it crystal clear with an image i doctored up in photoshop. When the menu appears the space inside the form goes dark and the normal picturebox is in the middle with menu buttons on it.
    Attached Images Attached Images  
    Hooked for good.

  7. #7
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Window bitblt

    Ok, here's a really short example and has some logic issues you'll need to figure out.

    1. Include a picturebox (named picClientCapture below) which is hidden and exists on your form, not in some other container
    2. Include a picturebox to hold your "menu" (named picMenu below)
    3. Behind the button that is suppose to do this, add this code
    Code:
        Dim tmpPicColor As PictureBox
        Dim wDC As Long, Cx As Long, Cy As Long
        
        Set tmpPicColor = Me.Controls.Add("VB.Picturebox", "picClientColorXYZ")
        With picClientCapture
            .BorderStyle = 0
            .Appearance = 0
            .AutoRedraw = True
            .ZOrder vbBringToFront
            .Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
        End With
        With tmpPicColor
            .BorderStyle = 0
            .Appearance = 0
            .AutoRedraw = True
            .Move 0, 0, Me.ScaleWidth, Me.ScaleHeight
            .BackColor = vbBlack ' change to whatever 'blend' color you desire
        End With
        
        Cx = ScaleX(Me.ScaleWidth, Me.ScaleMode, vbPixels)
        Cy = ScaleY(Me.ScaleHeight, Me.ScaleMode, vbPixels)
        wDC = GetDC(Me.hWnd)
        BitBlt picClientCapture.hdc, 0, 0, Cx, Cy, wDC, 0, 0, vbSrcCopy
        ReleaseDC Me.hWnd, wDC
        
        ' below change 168 to higher value for more 'blend' color
        ' 168 = (66%/100)*255
        AlphaBlend picClientCapture.hdc, 0, 0, Cx, Cy, tmpPicColor.hdc, 0, 0, Cx, Cy, &H10000 * 168
        Me.Controls.Remove tmpPicColor
        Set tmpPicColor = Nothing
        
        picClientCapture.Visible = True
        picMenu.ZOrder vbBringToFront
        picMenu.Visible = True
    Here are the declarations
    Code:
    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 AlphaBlend Lib "msimg32.dll" (ByVal hdcDest As Long, ByVal xDest As Long, ByVal yDest As Long, ByVal WidthDest As Long, ByVal HeightDest As Long, ByVal hdcSrc As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal WidthSrc As Long, ByVal HeightSrc As Long, ByVal Blendfunc As Long) As Long
    Private Declare Function BitBlt Lib "gdi32.dll" (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
    Logic issues:
    1. If the form is resized, your effect is broken. You may want to set the backcolor of the form while the "menu" is displayed. If you do, set it at the end of the sample routine above. Don't forget to set the backcolor back to normal just before the 'menu' is removed. Here's a simple formula to figure out the right color
    Code:
    ' sample call to the following function looks like this:
        ' pass to the BackColorToBlendColor the same values you used for the blend color & percentage value
        Me.BackColor = BackColorToBlendColor(Me, vbBlack, 168)
    
    
    Private Function BackColorToBlendColor(formObject As Object, BlendColor As Long, Level As Long) As Long
        
        Dim lColor As Long
        Dim dstLevel As Long
        Dim R1 As Long, R2 As Long, G1 As Long, G2 As Long, B1 As Long, B2 As Long
        
        lColor = formObject.BackColor
        If lColor < 0& Then lColor = GetSysColor(lColor And &HFF&)
        dstLevel = 255 - Level
        
        R1 = BlendColor And &HFF
        G1 = (BlendColor And &HFF00&) \ &H100&
        B1 = (BlendColor And &HFF0000) \ &H10000
        
        R2 = lColor And &HFF
        G2 = (lColor And &HFF00&) \ &H100&
        B2 = (lColor And &HFF0000) \ &H10000
        
        R1 = ((R1 * Level) + (R2 * dstLevel)) \ 255
        G1 = ((G1 * Level) + (G2 * dstLevel)) \ 255
        B1 = ((B1 * Level) + (B2 * dstLevel)) \ 255
        
        BackColorToBlendColor = RGB(R1, G1, B1)
    
    End Function
    2. This is more difficult to fix and should be avoided. If your form is resizable and the form size is not large enough to show all of its controls when the code captures its appearance, then resizing the form will not show the now-unhidden-controls as 'blended'

    3. Any animation on your form will no longer be animating to the user; animation still occurring behind the capture picbox

    4. Not an issue, but for memory easing, after your 'menu' is removed, resize picClientCapture to 1x1 so it uses very little resources

    Oops, forgot to include this API if you will be using the BackColorToBlendColor function:
    Code:
    Private Declare Function GetSysColor Lib "user32.dll" (ByVal nIndex As Long) As Long
    Last edited by LaVolpe; Dec 5th, 2011 at 01:32 PM.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  8. #8
    PowerPoster jcis's Avatar
    Join Date
    Jan 2003
    Location
    Argentina
    Posts
    4,430

    Re: Window bitblt

    Windows does something similar in shut down screen when placing the mouse over the button, this fades to black and white, not exatly the same since you need to darken the Form.

    I think it could be easier to do if your screen behind (not your menu) is captured as picture and then using a PictureBox that would cover all your Form, then bliting the picture onto that, finally fading the picture in the Picbox and not the real controls, like a trick i mean, the user shouldn't see the difference. This Picbox should be made visible before your Menu opens and invisible when it closes.

    I say this because fading the real Form with its controls will be much harder, VB controls how thay are drawn and refreshed messing with that may requiere harder approaches like subclassing.

    How to exatly fade the Picture darker in progression i don't know but there are things to try, like alphablending with a dark pic, or using BitBlt with bSrcAnd (joins 2 pics together), making the dark pic a bit darker before each fade step.

    EDIT: didn't see last Lavolpe's post before posting
    Last edited by jcis; Dec 5th, 2011 at 02:10 PM.

  9. #9

    Thread Starter
    Addicted Member cheesebrother's Avatar
    Join Date
    Jul 2011
    Posts
    153

    Re: Window bitblt

    That's pretty good, thanks. I'm wondering if it wouldn't be possible to fire the blending sub when the form resizes. I tried doing that but it had and error "Me.Controls.Remove tmpPicColor". Is that why that won't work?
    Hooked for good.

  10. #10
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Window bitblt

    No. If you did, it would flicker like mad.

    Theoretically, when the "menu" is displayed your users shouldn't be able to resize the form anyway; should they? Not until a menuitem has been selected or menu canceled.

    So why the flicker? Because before a capture of the client area (your form), the previous capture, if any, would need to be removed; new capture done & displayed dark. This removal and replacement loop would cause a visible flicker. If the previous capture wasn't removed, the area of that capture would become progressively darker with each additional call the routine. Also your menu would now be captured. A possible work around would be to cache a capture (large enough for all controls), but that could require trying to capture controls that are not visible due to the form size. This is problematic in itself. Simply suggest preventing form resizing while your menu is displayed
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  11. #11

    Thread Starter
    Addicted Member cheesebrother's Avatar
    Join Date
    Jul 2011
    Posts
    153

    Re: Window bitblt

    Right. I guess the best way would to just fill in new areas with the same grey as the form's backcolor darkened. Thanks for the help lavolpe!
    Hooked for good.

  12. #12
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Window bitblt

    Quote Originally Posted by cheesebrother View Post
    Right. I guess the best way would to just fill in new areas with the same grey as the form's backcolor darkened. Thanks for the help lavolpe!
    That's what that BackColorToBlendColor function I gave you will do. See "Logic Issues #1 & #2" in post 7
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  13. #13
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,541

    Re: Window bitblt

    Here are a couple more things to think about.

    1. You could resize the picClientCapture to a screen size. If you do, set picClientCapture.BackColor to the return value of BackColorToBlendColor:
    picClientCapture .Move 0, 0, ScaleX(Screen.Width, vbTwips, Me.ScaleMode), ScaleY(Screen.Height, vbTwips, Me.ScaleMode)

    You may or may not like how this will affect partially visible controls at time of the capture

    2. While your picClientCapture & your menu are visible, users can still tab to your 'hidden' controls, the ones behind picClientCapture. This could be an issue you want to address
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  14. #14
    PowerPoster jcis's Avatar
    Join Date
    Jan 2003
    Location
    Argentina
    Posts
    4,430

    Re: Window bitblt

    Nice code Lavolpe. I'm trying to make it fade progressively, like windows shut down, this seems to do the trick, what do you think?

    By Replacing this..
    Code:
        ' below change 168 to higher value for more 'blend' color
        ' 168 = (66&#37;/100)*255
        AlphaBlend picClientCapture.hdc, 0, 0, Cx, Cy, tmpPicColor.hdc, 0, 0, Cx, Cy, &H10000 * 168
        Me.Controls.Remove tmpPicColor
        Set tmpPicColor = Nothing
        
        picClientCapture.Visible = True
        picMenu.ZOrder vbBringToFront
        picMenu.Visible = True
    with this..
    Code:
        Dim ColorVal As Long, i As Long ' (should be added where sub begins)
        
        For i = 1 To 20
            picClientCapture.Visible = False
            ColorVal = ColorVal + 1
            AlphaBlend picClientCapture.hdc, 0, 0, Cx, Cy, tmpPicColor.hdc, 0, 0, Cx, Cy, &H10000 * ColorVal
            picClientCapture.Visible = True
            DoEvents
            Sleep 30
        Next
        
        picMenu.ZOrder
        picMenu.Visible = True
        
        Me.Controls.Remove tmpPicColor
        Set tmpPicColor = Nothing
        
        Me.BackColor = vbButtonFace
    Sleep API declaration is required:
    Code:
    Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    Maybe it's not very "clean" using sleep but couldn't find another way to pause the thing to make it fade.
    Last edited by jcis; Dec 5th, 2011 at 02:09 PM.

  15. #15

    Thread Starter
    Addicted Member cheesebrother's Avatar
    Join Date
    Jul 2011
    Posts
    153

    Re: Window bitblt

    2. While your picClientCapture & your menu are visible, users can still tab to your 'hidden' controls, the ones behind picClientCapture. This could be an issue you want to address
    Yes, i anticipated that and disabled all the controls behind picClientCapture. Thanks again for the help. I should do good enough on my own from here.
    Hooked for good.

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