I have a Picturebox that has an image displayed inside. Through code, I was able to have the "whole image" display in it without distortion. (Like a "Fit All" in most any image viewer program) Now, when the Picturebox gets resized by the user, I want the image to recalculate and display as "Fit All" again. So I have code in my SizeChanged event of the picturebox. When the "size changed", it does it's calculation, and displays properly. It works, but there is a problem: If the user drags the Picturebox window larger or smaller, the SizeChanged event fires many times per second. This causes alot of sluggishness in the app when trying to display the image. Is there anyway that i can have the SizeChanged event fire ONCE when i'm done resizing the picturebox? (By the way, the picturebox gets resized indirectly. It's dock is set to Fill. When the interface "Next" to it gets resized, the Picturebox naturally will resize accordingly) Thanks for all your help! John
Hi John, when you run you code: [quoted text, click to view] > Private Sub Form1_SizeChanged(...) Handles MyBase.SizeChanged > MessageBox.Show("Size Changed!") > End Sub
the first time you see the messagebox pop up is because the form is initialized, but after that the event normal only fires if you let go the form border, so at the end of the SizeChanged event. hth Greetz Peter -- Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. "johnb41" <orders@informatik.com> schreef in bericht news:1117457542.581437.123130@z14g2000cwz.googlegroups.com... [quoted text, click to view] > Peter, > > It's actually a Panel that I have the SizeChanged event attached to. > This is so the I get scrollbars when the image is larger than the > Panel. > > If it's not any trouble, could you post some sample code that makes the > event fire only once? I just did a sample test on resizing a plain > form: > > Private Sub Form1_SizeChanged(...) Handles MyBase.SizeChanged > MessageBox.Show("Size Changed!") > End Sub > > The form won't even resize because the messagebox pops up immediately. > If I could get the messagebox to show up after finishing the resize, > that would be awesome. I could then adapt it to my real app. > > Thanks! > John >
"johnb41" [quoted text, click to view] > Thanks for the reply. You make it seem obvious! Could you describe > more of what you mean, as it's very unclear to me. Thanks! >
\\\ Static OldSize As Size If Not OldSize.Equals(MeControl.Size) Then ....procedure End If /// I hope this helps, Cor
"johnb41" <orders@informatik.com> schrieb: [quoted text, click to view] >I have a Picturebox that has an image displayed inside. Through code, > I was able to have the "whole image" display in it without distortion. > (Like a "Fit All" in most any image viewer program) > > Now, when the Picturebox gets resized by the user, I want the image to > recalculate and display as "Fit All" again. > > So I have code in my SizeChanged event of the picturebox. When the > "size changed", it does it's calculation, and displays properly. > > It works, but there is a problem: If the user drags the Picturebox > window larger or smaller, the SizeChanged event fires many times per > second. This causes alot of sluggishness in the app when trying to > display the image.
If you are experiencing a flicker, you could enable double buffering for the picturebox control. To do so, create a class that inherits from 'System.Windows.Forms.PictureBox' and provides the constructor shown in the listing below: \\\ Public Sub New() Me.SetStyle( _ ControlStyles.ResizeRedraw Or _ ControlStyles.DoubleBuffer Or _ ControlStyles.AllPaintingInWmPaint, _ True _ ) Me.UpdateStyles() End Sub /// Then you use your custom picturebox control instead of the standard Windows Forms picturebox. -- M S Herfried K. Wagner M V P <URL: http://dotnet.mvps.org/> V B <URL: http://classicvb.org/petition/>
Peter, It's actually a Panel that I have the SizeChanged event attached to. This is so the I get scrollbars when the image is larger than the Panel. If it's not any trouble, could you post some sample code that makes the event fire only once? I just did a sample test on resizing a plain form: Private Sub Form1_SizeChanged(...) Handles MyBase.SizeChanged MessageBox.Show("Size Changed!") End Sub The form won't even resize because the messagebox pops up immediately. If I could get the messagebox to show up after finishing the resize, that would be awesome. I could then adapt it to my real app. Thanks! John
Thanks for the reply. You make it seem obvious! Could you describe more of what you mean, as it's very unclear to me. Thanks! John
I gotta leave and do family stuff on this Memorial Day, so i'll only post this quick message: For me, the SizeChanged event seems to keep firing again and again, until I let go of the mouse. This is in my real app, not the sample one w/ the messagebox. For example, the image constantly tries to redraw its self until I let go of the mouse. I'll have to do more testing, and then play w/ Cor and herfried's suggestions... John
John, You can use in the event two static variables (or one static point) to see everytime if it changed, I hope this helps, Cor
Hi John, which sizechanged event are you handling? Because I have written a bit of code which does the same thing, and tried it in these 3 events and they all only fire once, when I finish dragging the form border Private Sub ptbImg_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles ptbImg.Resize End Sub Private Sub ptbImg_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles _ ptbImg.SizeChanged End Sub Private Sub frmResize_SizeChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles _ MyBase.SizeChanged End Sub greetz Peter -- Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. "Cor Ligthert" <notmyfirstname@planet.nl> schreef in bericht news:uq$esOOZFHA.3488@tk2msftngp13.phx.gbl... [quoted text, click to view] > John, > > You can use in the event two static variables (or one static point) to see > everytime if it changed, > > I hope this helps, > > Cor > >
Thanks for the code. But it made no difference. Here is what I now have: Private Sub Pnl_Image_SizeChanged(...) Handles Pnl_Image.SizeChanged Static OldSize As Size If Not OldSize.Equals(Pnl_Image.Size) Then ' call procedure to resize and display image End If End Sub What am I missing? John
John, Sorry, I was reading it not well I thought that the picture stayed the same, of course does this not help. The only thing that I can come up that can help you here is probably a timer. We people are not able to see some things that fast. I never tried it, however you can probably do it in the same way as mysample, and than there is not much to change. Private Sub Pnl_Image_SizeChanged(...) Handles Pnl_Image.SizeChanged Static OldTime As Integer If (Environment.TicksCount - OldTime) > 50 Then ' call procedure to resize and display image End If OldTime = Environments.TicksCount End Sub And than set that 50 to a proper value. Maybe this helps, I am curious. Cor
John, have you looked at my example? in my opinion it does what you want. Greetz Peter -- Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. "johnb41" <orders@informatik.com> schreef in bericht news:1117551471.570946.61990@g44g2000cwa.googlegroups.com... [quoted text, click to view] > Cor, > > Interesting idea, thanks! > > But the only benefit it has is the image redraw happens a little less > frequently. And if I let go of the mouse at the wrong time, the image > doesn't redraw. I have to let go of the mouse immediately after it > redraws if I want the image displayed properly. > > I played w/ the number value. A number too high refreshes too > infrequently, and often when I let go of the mouse, my subroutine > doesn't fire, and thus my image doesn't get resized/redrawn. A number > too low, and the effect is similar to the original code. > > Well, I really appreciate all the help you've given me, Cor. But it > looks like this is pretty much impossible! :( > > John >
Cor, That didn't make a difference. My procedure fires again and again until I let go of the mouse. It's actually not "as" bad now that i'm at work on a much faster computer. But it's still annoying. Any more suggestions, or should I just give up? Thanks, John
Cor, Interesting idea, thanks! But the only benefit it has is the image redraw happens a little less frequently. And if I let go of the mouse at the wrong time, the image doesn't redraw. I have to let go of the mouse immediately after it redraws if I want the image displayed properly. I played w/ the number value. A number too high refreshes too infrequently, and often when I let go of the mouse, my subroutine doesn't fire, and thus my image doesn't get resized/redrawn. A number too low, and the effect is similar to the original code. Well, I really appreciate all the help you've given me, Cor. But it looks like this is pretty much impossible! :( John
Peter, Yes, I have. For me, the SizeChanged event fires again and again as the Panel gets resized, not just when I let go of the mouse. Am I missing something? Did you write any special code so it works as you say? John
Peter, Yes, I have. For me, the SizeChanged event fires again and again as the Panel gets resized, not just when I let go of the mouse. Am I missing something? Did you write any special code so it works as you say? John
John, I forgot it, however this is classic [quoted text, click to view] > Private Sub Pnl_Image_SizeChanged(...) Handles > Pnl_Image.SizeChanged > Static OldSize As Size > If Not OldSize.Equals(Pnl_Image.Size) Then > ' call procedure to resize and display image > End If
OldSize = Pnl_Image.Size [quoted text, click to view] > End Sub
I hope this helps, :-) Cor
Hi John, sorry for not responding faster, but after 5 o' clock (belgian time), I haven't got access to the ng's for the moment (pc at home is broke) The example I posted, runs very smooth at my computer, it only fires the sizechanged event once, and that's when I release the form border after resizing. Which version of VS do you have? 2002, 2003? I have got 2003. Greetz Peter -- Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. "johnb41" <orders@informatik.com> schreef in bericht news:1117553671.549306.262640@o13g2000cwo.googlegroups.com... [quoted text, click to view] > Peter, > > Yes, I have. For me, the SizeChanged event fires again and again as > the Panel gets resized, not just when I let go of the mouse. Am I > missing something? Did you write any special code so it works as you > say? > > John >
I also find it very strange, if I put a msgbox in the sizechanged event of a form, it first pops up before the form is even visible (that's just the form initializing) and then when the form is loaded it only pops up AFTER I let go of the mouse button, no extra code required. For example the example I posted at my pc only fires the sizechanged event after I let go of the mousebutton. Greetz Peter [quoted text, click to view] > a messagebox inside a Sizechanged event (for a Form), the messagebox > does not appear until AFTER you let go of the mouse button? No extra > code required?
-- Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. "johnb41" <orders@informatik.com> schreef in bericht news:1117635224.936869.82610@g14g2000cwa.googlegroups.com... [quoted text, click to view] > I have VS 2003 also. So let me get this straight, if you simply put in > a messagebox inside a Sizechanged event (for a Form), the messagebox > does not appear until AFTER you let go of the mouse button? No extra > code required? > > Amazing. I can't even resize a form because the messagbox pops up too > soon. > > If anyone else is reading this, does this happen to you also? > > If this is true, i'm surprised that the others that posted in this > thread didn't mention it. Cor really went out of his way to help w/ a > couple potential solutions. Now i'm more confused than ever! (but that > isn't new) > > John >
I have VS 2003 also. So let me get this straight, if you simply put in a messagebox inside a Sizechanged event (for a Form), the messagebox does not appear until AFTER you let go of the mouse button? No extra code required? Amazing. I can't even resize a form because the messagbox pops up too soon. If anyone else is reading this, does this happen to you also? If this is true, i'm surprised that the others that posted in this thread didn't mention it. Cor really went out of his way to help w/ a couple potential solutions. Now i'm more confused than ever! (but that isn't new) John
Windows has an option called "Show Windows Contents While Dragging". If this is turned on, you will receive a continuous stream of SizeChanged events. If it is turned off, you only get a single SizeChanged event. Since this is a user-defined setting, you need to account for both cases and make your SizeChanged code as quick as possible. The same goes for Move events. -- Jonathan Allen [quoted text, click to view] "Peter Proost" <pproost@nospam.hotmail.com> wrote in message news:O$B%23GrrZFHA.3864@TK2MSFTNGP10.phx.gbl... >I also find it very strange, if I put a msgbox in the sizechanged event of >a > form, it first pops up before the form is even visible (that's just the > form > initializing) and then when the form is loaded it only pops up AFTER I let > go of the mouse button, no extra code required. > > For example the example I posted at my pc only fires the sizechanged event > after I let go of the mousebutton. > > Greetz Peter > >> a messagebox inside a Sizechanged event (for a Form), the messagebox >> does not appear until AFTER you let go of the mouse button? No extra >> code required? > > > -- > Programming today is a race between software engineers striving to build > bigger and better idiot-proof programs, and the Universe trying to produce > bigger and better idiots. So far, the Universe is winning. > > "johnb41" <orders@informatik.com> schreef in bericht > news:1117635224.936869.82610@g14g2000cwa.googlegroups.com... >> I have VS 2003 also. So let me get this straight, if you simply put in >> a messagebox inside a Sizechanged event (for a Form), the messagebox >> does not appear until AFTER you let go of the mouse button? No extra >> code required? >> >> Amazing. I can't even resize a form because the messagbox pops up too >> soon. >> >> If anyone else is reading this, does this happen to you also? >> >> If this is true, i'm surprised that the others that posted in this >> thread didn't mention it. Cor really went out of his way to help w/ a >> couple potential solutions. Now i'm more confused than ever! (but that >> isn't new) >> >> John >> > >
Jonathan, Thanks for that info. I thought i was going crazy! So it looks like i'm stuck w/ a sluggishly slow app when the user resizes the image window. :( John
John, Can you try this one, I have taken the sample from Peter to test it this time. \\\ Public SwMoving As Boolean Private Sub Panel1_SizeChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Panel1.SizeChanged SwMoving = True End Sub Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = &HA0 Then 'is up &HA1 is nonclientarea down If SwMoving Then If Not ptbImg.Image Is Nothing Then loadimage(CStr(ptbImg.Tag)) End If SwMoving = False End If End If MyBase.WndProc(m) End Sub /// I hope that it this time helps, Cor
John, What you did not tell all the time in this thread is how you resize your panel. I have the same as I think for others assumed that it was resized accoording the resizing of the form. However was in doubt if it was because of a slider. Cor
John, This works than like a splitter (I wrote slider) and when I had understood this earlier, a lot easier. You set in the splitter mouse down event (your control) a swMouseDown (a global value) to true. In the Mouse Up event of that you set your resizing code in a kind of the same way as in the previous example (of course a call to a sub) and set the swMouseDown again to false. As long as that mouse is down you do nothing and when it goes up again you do your code. Because that I don't know that control, did I write it in this way, I hope that this explains it. Cor
Cor, Wow, thanks for the extra effort and help! I tried your code (obviously had to tweak it a little to fit my app), and here's what happened: The panel (with picturebox) gets resized without any sluggishness in the app. BUT the image does not get redrawn when i let go of the mouse. But whenever i move my mouse over the bar at the top of the form (i can't remember the name; the bar that has the minimize, maximize and close buttons) then sub routine fires that resizes and redisplays the image. Strange. If the image would resize to the new Panel size without having to run my mouse over the top bar, then it would be perfect!!! Here's my code: Public SwMoving As Boolean Private Sub Pnl_Image_SizeChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Pnl_Image.SizeChanged SwMoving = True End Sub Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = &HA0 Then 'is up &HA1 is nonclientarea down If SwMoving Then If Not Pb_image.Image Is Nothing Then 'below is routine that resizes 'and redisplays the image. 'The image gets displayed in the 'form that THIS code is in. Call displayimage(m_image, Me) End If SwMoving = False End If End If MyBase.WndProc(m) End Sub Anyway to tweak it a little? Thanks so much! John
I "thought" I mentioned it briefly somewhere. Anyway, here's how my Panel gets resized: The Panel is docked (Fill) on Form1. To the right of the panel is a dockable window (thanks to dotnetbar ( www.devcomponents.com)). When the dockable window is resized (left to right) or hidden, the Panel will resize accordingly. So that's how it's resized! Is your code adaptable for my situation? (by the way, if i resize my main form, it works really nice! :) John
Hi Cor, your example works nicely, I think John will be very pleased with it Greetz Peter -- Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. "Cor Ligthert" <notmyfirstname@planet.nl> schreef in bericht news:#vUMu1tZFHA.3120@TK2MSFTNGP12.phx.gbl... [quoted text, click to view] > John, > > Can you try this one, I have taken the sample from Peter to test it this > time. > > \\\ > Public SwMoving As Boolean > Private Sub Panel1_SizeChanged(ByVal sender As Object, _ > ByVal e As System.EventArgs) Handles Panel1.SizeChanged > SwMoving = True > End Sub > Protected Overrides Sub WndProc(ByRef m As Message) > If m.Msg = &HA0 Then 'is up &HA1 is nonclientarea down > If SwMoving Then > If Not ptbImg.Image Is Nothing Then > loadimage(CStr(ptbImg.Tag)) > End If > SwMoving = False > End If > End If > MyBase.WndProc(m) > End Sub > /// > > I hope that it this time helps, > > Cor > >
In the MouseUp event, you say to call a sub. Do you mean the sub that I created to do the resizing calculations, or the Sub WndProc that you created? I tried the latter, and it needs a "message" argument. I don't know what to put in there. If i totally ignore the Sub WndProc, and just put in my procedure, then i get unusual results. Sometimes my image gets redrawn, and sometimes it does not. Most of the time it does not redraw. It's unpredictable. So in summary, what of your original code do I keep? John
John, When it is in the case of a splitter you can use this code. \\\ Private Sub Splitter2_SplitterMoved(ByVal sender As Object, _ ByVal e As System.Windows.Forms.SplitterEventArgs) Handles Splitter2.SplitterMoved If Not ptbImg.Image Is Nothing Then loadimage(CStr(ptbImg.Tag)) End If End Sub /// When that wont go you can try this. \\\However gives a little bit stranger effect Public SwMoving As Boolean Public swSplitterMouseMoving As Boolean Private Sub Panel1_SizeChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Panel1.SizeChanged SwMoving = True End Sub Protected Overrides Sub WndProc(ByRef m As Message) If m.Msg = &HA0 Then If SwMoving Then If Not ptbImg.Image Is Nothing Then loadimage(CStr(ptbImg.Tag)) End If SwMoving = False End If SwMoving = False End If MyBase.WndProc(m) End Sub Private Sub Splitter2_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles Splitter2.MouseEnter swSplitterMouseMoving = True End Sub Private Sub Splitter2_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Splitter2.MouseLeave If swSplitterMouseMoving Then If SwMoving Then If Not ptbImg.Image Is Nothing Then loadimage(CStr(ptbImg.Tag)) End If SwMoving = False End If SwMoving = False End If swSplitterMouseMoving = False End Sub /// I hope this helps, Cor
Addendum: \\\ Private m_Image As Image Private m_Redraw As Boolean = True Private Sub Form1_Load( _ ByVal sender As Object, _ ByVal e As EventArgs _ ) Handles MyBase.Load m_Image = Image.FromFile("C:\WINDOWS\Angler.bmp") End Sub Protected Overrides Sub WndProc( _ ByRef m As Message _ ) Const WM_ENTERSIZEMOVE As Int32 = &H231 Const WM_EXITSIZEMOVE As Int32 = &H232 Select Case m.Msg Case WM_ENTERSIZEMOVE m_Redraw = False Case WM_EXITSIZEMOVE m_Redraw = True Me.Panel1.Invalidate() End Select MyBase.WndProc(m) End Sub Private Sub Panel1_Paint( _ ByVal sender As Object, _ ByVal e As PaintEventArgs _ ) Handles Panel1.Paint If m_Redraw Then e.Graphics.DrawImage( _ m_Image, _ 0, 0, _ Me.Panel1.ClientSize.Width, Me.Panel1.ClientSize.Height _ ) End If End Sub /// However, this solution would prevent the panel from redrawing if the window is dragged by the mouse. -- M S Herfried K. Wagner M V P <URL: http://dotnet.mvps.org/> V B <URL: http://classicvb.org/petition/>
Herfried, The main problem is a dockable window (thanks to dotnetbar ( www.devcomponents.com)). The rest of the solutions where already given (I think mine is nicer), do you know something about this control and to stop actions using this while resizing. Cor
"Cor Ligthert" <notmyfirstname@planet.nl> schrieb: [quoted text, click to view] > \\\ > Public SwMoving As Boolean > Private Sub Panel1_SizeChanged(ByVal sender As Object, _ > ByVal e As System.EventArgs) Handles Panel1.SizeChanged > SwMoving = True > End Sub > Protected Overrides Sub WndProc(ByRef m As Message) > If m.Msg = &HA0 Then 'is up
'&HA0' is 'WM_NCMOUSEMOVE'! In addition to that, note that the user can change the size of a window using the keyboard (Alt+Space -> "Resize" -> arrow keys), which won't fire non-client mouse events. All together I don't see the benefits of your solution. -- M S Herfried K. Wagner M V P <URL: http://dotnet.mvps.org/> V B <URL: http://classicvb.org/petition/>
Herfried, [quoted text, click to view] > In addition to that, note that the user can change the size of a window > using the keyboard (Alt+Space -> "Resize" ->
A good addition. However for that can be tested in this procedure probably just keyup &H291 with orelse (I did not test it). I could not find all those shortcuts from C++ on Google, however I have now copied a page from Bob Powell where it is was in, therefore I have them now saved in my HKW system. I thought yesterday it would be a nice extension if somebody like Herfried makes a nice dll so that we can get those in the same way as all other enumerations. When you need that information from Bob Powell to make this than I can sent them you by mail. (Before you say it, yes I can make it myself as well however it looks so nice as a link to your page) The Herfried.K.Wagner namespace extension to the framework. :-) Cor
Herfried, I will have a look at it, (as you know, do I hate sites which wants my emailadres, although I know from you that this one is harmless) Thanks, Cor
Cor, "Cor Ligthert" <notmyfirstname@planet.nl> schrieb: [quoted text, click to view] > I will have a look at it, (as you know, do I hate sites which wants my > emailadres, although I know from you that this one is harmless)
Yeah, I hate them too because I have to lookup my password every time I log in. -- M S Herfried K. Wagner M V P <URL: http://dotnet.mvps.org/> V B <URL: http://classicvb.org/petition/>
Sorry I couldn't try your suggestions out until now. ... and thanks for the continued help with this! Unfortunately the dotnetbar "dockable window" does not have a splitter that has events. No splitter at all that I can see. It's probably using one in the background, but I have no idea how to access it. I think i'm just going to lay this issue to rest. I will not bother having an instantly re-drawable picturebox/panel. Thanks again for all your help!!! John
Herfried, I tried your code, but in my app it produced some side effect errors that I could not figure out. As I wrote to Cor above, I decided to just give up on this effect. But at least this thread was not for nothing... it does have some valuable code for having the SizeChanged event fire once if the "form" itself is resized. Thanks! John
Don't see what you're looking for? Try a search.
|