Author |
Message |
Jimmy #1 / 16
|
 Fading a PictureBox?
I Googled this like crazy and can't find much. There is a lot of code claiming they do it, but they are using a new form and using it like a PictureBox. I could do it this way if I had to, but I'd prefer using just PictureBoxes. But maybe it's not possible? I basically just want to take a PictureBox, change the background color to red, then make it 50% transparent so that anything in back of it on the form (and the form itself) shows through behind the PictureBox. I have simple code that uses SetLayeredWindowAttributes() to let me fade an entire form using its hwnd, but when trying to point it to a PictureBox, it does nothing and doesn't throw any error. Thanks in advance.
|
Thu, 30 Sep 2010 05:55:22 GMT |
|
 |
duke #2 / 16
|
 Fading a PictureBox?
Quote: > I Googled this like crazy and can't find much. There is a lot of code > claiming they do it, but they are using a new form and using it like a > PictureBox. I could do it this way if I had to, but I'd prefer using just > PictureBoxes. But maybe it's not possible? I basically just want to take a > PictureBox, change the background color to red, then make it 50% transparent > so that anything in back of it on the form (and the form itself) shows > through behind the PictureBox. > I have simple code that uses SetLayeredWindowAttributes() to let me fade an > entire form using its hwnd, but when trying to point it to a PictureBox, it > does nothing and doesn't throw any error. > Thanks in advance.
Here is an excellent sample of fading a picturebox: http://vbaccelerator.com/home/VB/Code/vbMedia/DIB_Sections/Alpha_DIBS...
|
Thu, 30 Sep 2010 12:51:25 GMT |
|
 |
Jimmy #3 / 16
|
 Fading a PictureBox?
Thanks. I did see that, but I don't think that's what I'm looking for. That's way more complicated and seems to copy other PictureBoxes and fade them in different areas. Plus when I try to put a control in the background, like a ListBox, that ListBox just says on top all the time no matter if I "Send To Back" or what. I'm wanting to directly fade a picture box around 50% on a form (solid color, no alpha channel even) and have it show through whatever controls are under it, be it a ListBox, TestBox, StatusBar, etc. The reason I want to do this is so I can highlight a certain area with red, for example, but not have it be a red box. It doesn't sound like it's possible?
|
Fri, 01 Oct 2010 04:29:26 GMT |
|
 |
Larry Serflate #4 / 16
|
 Fading a PictureBox?
Quote: > I'm wanting to directly fade a picture box around 50% on a form (solid > color, no alpha channel even) and have it show through whatever controls are > under it, be it a ListBox, TestBox, StatusBar, etc. The reason I want to do > this is so I can highlight a certain area with red, for example, but not > have it be a red box. > It doesn't sound like it's possible?
I dunno... Have you visited MSDN and got prompted to install Silverlight? The whole page fades except for the Siverlight dialog. What do you think about moving your form to a webbrowser control? LFS
|
Fri, 01 Oct 2010 10:39:25 GMT |
|
 |
Mike William #5 / 16
|
 Fading a PictureBox?
Quote: > . . . plus when I try to put a control in the background, > like a ListBox, that ListBox just says on top all the time > no matter if I "Send To Back" or what.
That's because the code is drawing the background, which is of course always behind any Controls in that area. It is possible to draw stuff over the top of Controls if you set the Form's ClipControl property to False, but you to achieve translucency you would need to grab the "image" of the Form under the area of interest (a copy of the Form and the Controls in that area) and then Alphablend that with your desired background colour or image and then draw the result to that area of the Form, with ClipControls at False. The problem with that of course is as soon as you clicked one of the Controls then that control (or at least part of it, depending on the Control) would redraw itself, completely spoiling the effect. To get around this you would need to subclass the control and get it to draw the desired blended background instead of its normal back color, which is only really possible for things such as the client area of TextBoxes and ListBoxes and which in any case requires a lot of work. Overall I think it very unlikely that you will be able to get your desired effect in that way, or at least you will be able to do it only for certain controls and with a massive amount of effort. Regarding your original requirement for a translucent window (such that the operating system sees the window as being translucent and draws the entire window translucently) I think you can only get that for top level windows, such as Forms, and not for things like Picture Boxes. Also, I assume you realise that an "OS translucent window" is actually seen as "solid" by the operating system, so although you can see the various things behind it translucently you cannot actually click them. So even if you could get an "OS translucent" PictureBox, or even if you placed an "OS transparent Form" over the top of the controls, you would not be able to click and interact with them. I assume that you want to be able to click and interact those things, so you'll need to look at it in a slightly different way. For example, have you considered a slightly different option where you draw just a "solid colour rectangle" (or perhaps a solid normally drawn picture or something) onto your main Form in the desired area and then place an "OS translucent" borderless Form over the top of it, with the OS translucent Form actually containing the Controls, and then subclassing the main Form's WM_MOVE message so that the overlying borderless Form always moves exactly with the main Form. I think that would produce exactly the visual effect you desire, with the small Form and all its contained controls automatically being translucent with the background colour or picture and all being fully accessible to the user. The only "fly in the ointment" with this is that when the user clicks a Control the main Form will show its Caption bar in its "unselected" state, but that might not be a problem to you and in any case it might be possible to deal with that problem in some way or other, perhaps drawing your own caption details. Anyway, that's the area I would be looking into if I were you. Post again if you decide to go that way and if you need some code to start you off. Mike
|
Fri, 01 Oct 2010 18:53:15 GMT |
|
 |
Jimmy #6 / 16
|
 Fading a PictureBox?
Ok, wow, thank you for the thoughtful post. My computer has been down for a while, but it's finally back up. I'm going to try and use a separate form (borderless) and fade that out. I'm guess that will work and it sounds much easier than all the subclassing stuff. I was just hoping because PictureBox had a hwnd that it could be faded out just like I do when I fade on my splash screen using SetLayeredWindowAttributes() there are no problems. What do you think about that?
|
Thu, 07 Oct 2010 03:52:08 GMT |
|
 |
Mike William #7 / 16
|
 Fading a PictureBox?
Quote: > Ok, wow, thank you for the thoughtful post.
You're welcome. Quote: > My computer has been down for a while, but it's finally > back up. I'm going to try and use a separate form > (borderless) and fade that out. I'm guess that will work > and it sounds much easier than all the subclassing stuff. > I was just hoping because PictureBox had a hwnd that > it could be faded out just like I do when I fade on my > splash screen using SetLayeredWindowAttributes() > there are no problems. > What do you think about that?
Unfortunately SetLayeredWindowAttributes cannot be applied to VB Picture Boxes, only top level windows. The separate Form should work okay though. But you need to realise that these translucent windows really drive the OS into the ground on slow to medium speed machines when you move them around, driving the processor way up to the 100 percent mark, especially in Vista where the video card's 2D hardware acceleration has been knobbled by Vista, so they are unlikely to follow the main Form in synch if you move it about rapidly. It should work okay though on most machines. Here's a very quick modification of some code I normally use for something quite different, so it is just a "rough and ready knockup", but it should get you started. You need a new VB project (everything with its default names). You need to place a PictureBox on the main Form and you need to create a small second Form and set it to Borderless and place some controls on it. You also need a standard code module. Here are the two code blocks: Mike ' *** START OF MODULE CODE *** Option Explicit Private Declare Function ClientToScreen _ Lib "user32" (ByVal hwnd As Long, _ lpPoint As POINTAPI) As Long Private Type POINTAPI x As Long y As Long End Type Public lOldWndProc As Long Public lOldWndProc2 As Long Private Const WM_MOVE = &H3 Private Const WM_SIZE = &H5 Public Const GWL_WNDPROC = (-4) Public Declare Function SetWindowLongA _ Lib "user32.dll" (ByVal hwnd As Long, _ ByVal nIndex As Long, _ ByVal dwNewLong As Long) As Long Private Declare Function CallWindowProcA _ Lib "user32.dll" _ (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, _ ByVal Msg As Long, ByVal wParam As Long, _ ByVal lParam As Long) As Long Public Const LWA_COLORKEY = &H1 Public Const LWA_ALPHA = &H2 Public Const GWL_EXSTYLE = (-20) Public Const WS_EX_LAYERED = &H80000 Public Declare Function GetWindowLong Lib "user32" _ Alias "GetWindowLongA" (ByVal hwnd As Long, _ ByVal nIndex As Long) As Long Public Declare Function SetWindowLong Lib "user32" _ Alias "SetWindowLongA" (ByVal hwnd As Long, _ ByVal nIndex As Long, ByVal dwNewLong As Long) _ As Long Public Declare Function SetLayeredWindowAttributes _ Lib "user32" (ByVal hwnd As Long, ByVal _ crKey As Long, ByVal bAlpha As Byte, _ ByVal dwFlags As Long) As Long Public Function WndProc(ByVal hwnd As Long, _ ByVal Msg As Long, ByVal wParam As Long, _ ByVal lParam As Long) As Long Dim p1 As POINTAPI If Msg = WM_MOVE Then ClientToScreen Form1.hwnd, p1 Form2.Move (p1.x + 50) * Screen.TwipsPerPixelX, _ (p1.y + 50) * Screen.TwipsPerPixelY End If WndProc = CallWindowProcA(lOldWndProc, hwnd, Msg, _ wParam, lParam) End Function ' *** END OF MODULE CODE *** ' ' *** START OF FORM1 CODE *** Option Explicit Private Sub Form_Load() Dim ret As Long Me.ScaleMode = vbPixels Picture1.BorderStyle = vbBSNone Picture1.BackColor = vbRed Picture1.Move 50, 50, 200, 300 Form2.BackColor = vbWhite Form2.Width = ScaleX(200, vbPixels, vbTwips) Form2.Height = ScaleY(300, vbPixels, vbTwips) Form2.Show , Me ret = GetWindowLong(Form2.hwnd, GWL_EXSTYLE) ret = ret Or WS_EX_LAYERED SetWindowLong Form2.hwnd, GWL_EXSTYLE, ret SetLayeredWindowAttributes Form2.hwnd, 0, 128, _ LWA_ALPHA lOldWndProc = SetWindowLongA(Me.hwnd, GWL_WNDPROC, _ AddressOf WndProc) End Sub Private Sub Form_QueryUnload(Cancel As Integer, _ UnloadMode As Integer) SetWindowLongA hwnd, GWL_WNDPROC, lOldWndProc End Sub Private Sub Form_Unload(Cancel As Integer) Unload Form2 End Sub ' *** END OF FORM1 CODE ***
|
Thu, 07 Oct 2010 04:59:58 GMT |
|
 |
Jimmy #8 / 16
|
 Fading a PictureBox?
Quote: > Unfortunately SetLayeredWindowAttributes cannot be applied to VB Picture > Boxes, only top level windows. The separate Form should work okay though. > But you need to realise that these translucent windows really drive the OS > into the ground on slow to medium speed machines when you move them > around, > driving the processor way up to the 100 percent mark, especially in Vista > where the video card's 2D hardware acceleration has been knobbled by > Vista, > so they are unlikely to follow the main Form in synch if you move it about > rapidly. It should work okay though on most machines.
Yeah, that's ok about it not working on a PictureBox. One could hope though. It would have been easier to deal with. I just applied what I was doing to a new form yeah, it works like a charm for the most part. I haven't done any resize code on it yet, but it looks perfect. It's a small strip in the status bar and only shows up every once in a while, so it's not there all the time. Hopefully it shouldn't tax the system all that much. Thanks for the sample code. That's very similar to what I'm using, but I don't think I need to use a PictureBox on the main form anymore though, right? The only reason I wanted to use one before is so I wouldn't need to use another form. The fewer controls/simpler, the better. Thanks tons for your help!!!
|
Fri, 08 Oct 2010 02:23:03 GMT |
|
 |
Jimmy #9 / 16
|
 Fading a PictureBox?
I was just trying to do resize code on that faded form, but of course when I move the main form, the faded form doesn't move with it. Argh. Is there a way I can parent the form some how so it moves with the main form? Another good reason to use a PictureBox if that had been possible. :(
|
Fri, 08 Oct 2010 02:47:52 GMT |
|
 |
Jimmy #10 / 16
|
 Fading a PictureBox?
I was just trying to do resize code on that faded form, but of course when I move the main form, the faded form doesn't move with it. Argh. Is there a way I can parent the form some how so it moves with the main form? Another good reason to use a PictureBox if that had been possible. :(
|
Fri, 08 Oct 2010 02:47:52 GMT |
|
 |
Mike William #11 / 16
|
 Fading a PictureBox?
Quote: > I was just trying to do resize code on that faded form, > but of course when I move the main form, the faded > form doesn't move with it. Argh. Is there a way I can > parent the form some how so it moves with the main form?
I'm not sure what you mean about the faded Form not moving with the main Form? Are you using the example code I posted? If so then if the main Form is a standard resizable Form smaller than the display which can be moved about by the user then the faded Form will move with it. That's what the code in the .bas module does. In fact I've just created a new VB project and followed the instructions that I post and it dies exactly what it is supposed to do, with the faded Form (Form2) being positioned immediately over a red rectangle on Form1 (the PictureBox) and when I click in the Caption Bar of the main Form (Form1) and move it around the screen the faded Form (Form2) follows it, remaining positioned exactly over the red PictureBox on Form1. There is some "sluggishness" of course because when the operating system is moving translucent Forms about it places a fairly heavy load on the processor, causing the translucent Form to fail to totally lock to the movement of the main Form, and taking perhaps one or two frames or before it "catches up" if you move quickly. Does it not happen like that at your end? Does the shaded Form not move with the main Form at all? Incidentally, the reason why the failure to totally lock is so apparent (in the example I posted) is because a Picture Box on the maain Form is used to provide the "coloured rectangle in the area of the translucent controls" that you asked for. If you instead set the backcolor of the translucent Form and the backcolour of its contained text boxes (or whatever) to provide the effect then you will not notice the failure to totally lock anywhere near as much, because effectively the shaded area if part of the translucent Form. It's hard to figure out a different way of doing this (which there may be) because I'm still not entirely sure about the effect you are after? Anyway, if you use the example I posted are you saying that the translucent Form does not move with the main Form at all? If so then you must have done somehting differetn because it works okay here, and I've used the code from my own post. Perhaps you may like to come back with some more details? I'm sure there will be some less processor intensive ways of providing the effect you are after, at least in some specific circumstances. Exactly what are you after, and what controls do you require to have this translucent effect? Mike
|
Fri, 08 Oct 2010 03:24:00 GMT |
|
 |
Jimmy #12 / 16
|
 Fading a PictureBox?
I didn't initially (because I'm hard headed :), but I just tried it now. It didn't seem to show controls under it though. It just looks like a solid light red square. So I played around, threw some random controls onto Form1. I set the PictureBox invisible, set Form2's back color to red and took out the line where it changes the Form2 back color to white, then it worked! If you do that you'll see what I was looking for. I need to play around a bit with some resize code, but I think that will work. Thank you so much!!! Quote: > I'm not sure what you mean about the faded Form not moving with the main > Form? Are you using the example code I posted?
|
Fri, 08 Oct 2010 11:49:03 GMT |
|
 |
Mike William #13 / 16
|
 Fading a PictureBox?
Quote: > I didn't initially (because I'm hard headed :), > but I just tried it now. It didn't seem to show > controls under it though. It just looks like a > solid light red square.
That's because you did /not/ place any Controls on Form2, which is what I meant you to do when I said, ". . . you need to create a small second Form and set it to Borderless and place some controls on it". The reason you could not see the controls is because there weren't any to see. The idea was to show the Contols that live on the translucent Form2, not the Controls that live on Form1. Quote: > So I played around, threw some random controls > onto Form1. I set the PictureBox invisible, set > Form2's back color to red and took out the line > where it changes the Form2 back color to white, > then it worked!
In that case there is no need for the PictureBox at all. The only reason I included the Form1 PictureBox was to provide a simple means of causing a rectangular area of Form1 to have a colour different from the main Form1 colour in a way that did not require constant redrawing and that provided the effect you were after. The idea was to provide a coloured "background" which can be "translucently seen" through the translucent Form2 which was sitting on top of it, so that Form 2 and its contained Controls appeared with a "translucent hue". I gathered from your posts that was the effect you wanted? Quote: > If you do that you'll see what I was looking for. > I need to play around a bit with some resize code, > but I think that will work. Thank you so much!!!
You're welcome. But the effect you have got now, after your own modifications, means that the user can see the various Controls in the rectangle, so that the rectangle itself and all the Controls within it have a sort of translucent "pink hue", but the user cannot actually interact with those controlsin any way. He cannot click any of the buttons and he cannot enter text into any of the TextBoxes, etc. If you instead use the method I suggested (if you use the code exactly as I posted it and if you place the controls where I suggested they should be placed, which is on Form2 instead of on Form1) then the controls and the rectanglular area will lok as they do now in your modified version but the user will actually be able to interact with those controls, type text into the TextBoxes and click the buttons or whatever. I concluded from your original messages that was exactly how you wanted it to behave? If that is the case then your modified version will not achieve that effect. Otherwise, if you actually do want the Controls in the "pink rectangle" to look and behave exactly as they currently do in your modification of my code (so that the user cannot interact with them) then there is a very much better way of doing it which does not involve subclassing and does not involve using extra Forms (Form2) and which will achieve exactly the same visual effect, but in a way that is much more "processor friendly". Post again if that's what you want. Mike
|
Fri, 08 Oct 2010 17:05:43 GMT |
|
 |
Mike William #14 / 16
|
 Fading a PictureBox?
Quote: > I didn't initially [try your code] because I'm hard headed :)
I do understand that view Jimmy, because I'm often quite hard headed myself, but to be honest I've spent some considerable time looking at your problem and writing code in an attempt to solve it for you and I think it might be nice of you to spend just a few minutes yourself actually running the code I've posted, especially as I always spend extra time taking the trouble to post my code examples in such a way that it is very easy for anyone to paste it exactly as it stands into a new VB project :-( Until you post back again I'm still not entirely sure what effect you are after, but if you want the Controls which are covered with the "translucent rectangle" to be inaccessible to the user while they are so covered (such that the translucent rectangle is an indicator of a specific block of controls which the use ris not permitted to use at any given moment) then there is a very much eaiser (and much more processor friendly) way of doing it which does not involve any extra Forms or any subclassing. The following is a just a quick example that uses hard coded values for the area of interest, but it can of course easily be turned into a more flexible function to which you can pass just a few simple parameters. Start a new VB project and place one TextBox, one ListBox, one PictureBox and two Command Buttons on the Form. Then paste in the following code. Does this do what you are after? Mike Option Explicit Private Declare Function AlphaBlend Lib "msimg32.dll" _ (ByVal destDC As Long, ByVal xDest As Long, _ ByVal yDest As Long, ByVal widthDest As Long, _ ByVal heightDest As Long, ByVal srcDC As Long, _ ByVal xSrc As Long, ByVal ySrc As Long, _ ByVal widthSrc As Long, ByVal heightSrc 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 Type BLENDFUNCTION BlendOp As Byte BlendFlags As Byte SourceConstantAlpha As Byte AlphaFormat As Byte End Type Private Const AC_SRC_OVER As Long = &H0 Private Disabled As Boolean Private Sub Command3_Click() Picture1.Cls End Sub Private Sub Form_Load() Dim n As Long Me.ScaleMode = vbPixels Picture1.BorderStyle = vbBSNone Picture1.ScaleMode = vbPixels Picture1.BackColor = vbRed Picture1.AutoRedraw = True Picture1.Visible = False Text1.Move 50, 20, 120, 60 List1.Move 50, 100, 120, 100 For n = 1 To 50 List1.AddItem "Item " & Format(n) Next n Command1.Move 50, 210 Command2.Move 250, 200 Command2.Caption = "Click Me" End Sub Private Sub Command2_Click() Dim bf As BLENDFUNCTION, lBF As Long If Not Disabled Then Picture1.Width = 140 Picture1.Height = 240 Picture1.Cls With bf .BlendOp = AC_SRC_OVER .BlendFlags = 0 .SourceConstantAlpha = 128 .AlphaFormat = 0 End With RtlMoveMemory lBF, bf, 4 AlphaBlend Picture1.hdc, 0, 0, 140, _ 240, Me.hdc, 40, 10, _ 140, 240, lBF Picture1.Refresh Picture1.Move 40, 10 Picture1.ZOrder Picture1.Visible = True Disabled = True Else Picture1.Visible = False Disabled = False End If End Sub
|
Sat, 09 Oct 2010 03:37:34 GMT |
|
 |
Jimmy #15 / 16
|
 Fading a PictureBox?
Hey Mike. Do you ever do any contract work? I sometimes have little things like this that I usually go to RentACoder.com for, but I'd much rather find some good people like you. I don't suppose you'd have an email address I could write to. Of course the whiskyandcoke doesn't work. I'd like to compensate you for your help so far, even though I know you're freely giving it away.
|
Sun, 10 Oct 2010 04:53:34 GMT |
|
|
Page 1 of 2
|
[ 16 post ] |
|
Go to page:
[1]
[2] |
|