From: Mike Williams on 17 Apr 2010 04:50 "Andrew Elder" <aelder(a)melbpc.org.au> wrote in message news:uJ8Y6cc3KHA.1452(a)TK2MSFTNGP06.phx.gbl... > I cured the first problem [Command Buttons inside a Frame > disappearing] by setting the Clipcontrols for the Frame to False. That's why I mentioned ClipControls in my previous response. There are all sorts of possibilities and you might, for example, have had the Form's ClipControls set to False and the Frame's ClipControls set to True, which definitely causes incorrect painting and which is a condition that is specifically mentioned in the help files. Setting the Frame's ClipControls to False in that case does usually fix the problem, but unless you have a very specific reason for having the Form's ClipControl's property set to False (which is very rarely a requirement on modern machines) then the best thing is to set them both to True, which is the default and which also fixes the problem. > I still do not fully understand what this does, despite reading > the help several time, but it seems to have fixed this one! The ClipControls property does a couple of important things, but the main thing it does when set to True on a specific object (the default setting) is that it creates a drawing region for that object which contains "rectangular clipping holes" in all the places where contained controls (Command Buttons, Text Boxes, etc) are placed within it. This prevents any drawing methods or Cls method (where applicable) from drawing or painting over any of those Controls. This of course means that your own drawings will not overwrite any such contained controls (if you or VB happen to draw in those places) and it also means that after performing a Cls then VB does not need to redraw any of the contained controls (Command Buttons Text Boxes or whatever) because the "ClipControls True" prevented Cls from painting over them in the first place, whereas if ClipControls is False then a VB Cls method will "clear" the Form completely, painting over its contained controls as well and causing them to disappear, and then the VB Cls method will immediately and automatically redraw those controls that it painted over. This redrawing of the painted over controls goes wrong if, for example, you have ClipControls False on the Form and True on the Frame. To see what difference ClipControls makes as far as drawing methods (lines, circles, paintpicture, etc) are concerned try the following code in a Form containing lots of different controls including one Frame control that itself has lots of contained controls. First set the ClipControls property of both the Form and the Frame to True in the IDE (the default setting) and run the program and click one or other (or both) of the two buttons (the ones with bold captions on them). Then come back to the IDE and set either the Form or the Frame (or both) ClipControls property to False and run it again: Mike Option Explicit Private Declare Function GetDC Lib "user32" _ (ByVal hwnd As Long) As Long Private Declare Function LineTo Lib "gdi32" _ (ByVal hdc As Long, ByVal x As Long, _ ByVal y As Long) As Long Private Sub Form_Load() Command1.Font.Bold = True Command2.Font.Bold = True Command1.Caption = "Draw Lines in Frame" Command2.Caption = "Draw Lines in Form" End Sub Private Sub Command1_Click() Dim n As Long, DC As Long Me.ScaleMode = vbPixels DC = GetDC(Frame1.hwnd) For n = 1 To 20 LineTo DC, Rnd * Frame1.Width, Rnd * Frame1.Height Next n End Sub Private Sub Command2_Click() Dim n As Long Me.ScaleMode = vbPixels Me.ForeColor = vbBlue For n = 1 To 20 LineTo Me.hdc, Rnd * ScaleWidth, Rnd * ScaleHeight Next n End Sub
From: Mike Williams on 17 Apr 2010 06:17 "Andrew Elder" <aelder(a)melbpc.org.au> wrote in message news:uJ8Y6cc3KHA.1452(a)TK2MSFTNGP06.phx.gbl... > The second problem [a PictureBox problem] "just got better"! > I was tesing various combinations of Clipcontrols and Autoredraw, > and it all started to work properly again . . so I am happy. But, > I don't fully understand what I did to fix it, so I am not happy! Autoredraw, as you probably already know, causes your drawing to become "automatically persistent" because your drawing goes into a memory bitmap which VB then draws into the visible PictureBox whenever it needs to do so. The only "rider" to this is that if you draw into an Autoredraw PicBox using /only/ GDI methods (as opposed to native VB drawing methods) then VB does not know you have drawn anything into its memory bitmap and so it will not perform its otherwise automatic update of the displayed PictureBox. So, whenever you do draw into it using only GDI methods you need to "tell the PictureBox you have drawn something", either by using a PicBox.Refresh or by using one of its native VB drawing methods. Autoredraw being True also stops the PictureBox Paint event from firing, so if you have drawing code in its Paint event it will not execute whilst Autoredraw is True. One other thing is that the VB Autoredraw mechanism redraws /only/ those parts of the PictureBox that actually need redrawing (the usually very narrow band that for example might have otherwise been "wiped" at each mouse movement when dragging the PicBox on and off the edge of the display). This is almost never a problem because it is in fact the only portion that needs redrawing, but it is worth bearing in mind if you are ever doing anything a bit unusual with the PictureBox for some reason. Also, regarding the ClipControls property, the other important thing which ClipControls does (referring to my mention of "a couple of important things" in my previous response) is that it changes the behaviour of the Paint event in a non-Autoredraw PictureBox. When ClipControls is True (the default setting) then the Paint event (each time it fires) peforms whatever drawing code you have placed into it without performing any clipping, so that if your drawing code fills the PictureBox with a graph or whatever then the entire graph will be drawn at each Paint event. On the other hand, when ClipControls is False then the Paint event sets up a clipping region which encompasses only the part of the PictureBox that actually currently needs redrawing (for example the narrow band of it that has just been moved off the edge of the display and back again). This often (but not always) means that the redraw is performed faster, because instead of the entire drawing being done only part of its has actually been drawn, with the rest being "clipped". As far as the "persistence" of the drawing (your graph or whatever) is concerned there is usually no visible difference between the two (ClipControls True or False) because in a lot of cases your Paint event code is simply reedrawing the same graph. The only difference in such cases is the speed of the redrawing. To see what I mean as far as the visible aspect is concerned try the following code which has been written specifically so that you can see the difference between ClipControls True and False, because instead of drawing the same drawing each time in the Paint event it draws a randomly placed selection of dots, which of course will be a different dot pattern each time. If you run the code as it stands (with ClipControls being set to True, the default setting) you will see a random pattern of dots in the PictureBox. If you then move the Form so that an edge of the PictureBox goes on and off the screen you will see that the Paint event each time draws another random pattern of dots. The small band of the PictureBox that was "wiped" by going on and off the edge of the screen will contain just one pattern of dots (replacing the pattern that was "wiped" in that area) but the rest of the PictureBox will have both the old pattern of dots and the newly drawn pattern of dots as well, becoming slightly darker each time. Now change the code so that ClipControls is False and try the same thing, moving the Form so that an edge of the pictureBox goes on and off the screen as before. This time it will be obvious that even though the drawing code was attempting to draw the pattern of dots over the whole PictureBox, the only the part of that drawing which was actually drawn is the part that "needed redrawing because it had been wiped", with the rest of the drawing not being done because it was "clipped". So, as should now be apparent, the many different combinations of Autoredraw and ClipControls on your Form and your PictureBoxes (and to an extent on your Frames) can cause your program to behave in a number of different ways under various different circumstances, and many of the things that people say are apparently "random behaviour" are not random at all, although having said that, there will always be the odd occasion when something you have done (or something VB has done) has caused VB itself to get confused, and in some cases rebuilding (or even just partially rebuilding and recompiling) you app can sometimes fix some things ;-) By the way, I've used the Line method in the following code to draw each dot rather than the PSet method because Vista has a bug when it is not running its Aero desktop which causes both VB Pset and GDI SetPixel fail to draw the dot whenever bit 8 is set in the X coordinate. That's something else you would be wise to remember whenever you need to draw individual dots. Mike Option Explicit Private Sub Form_Load() Picture1.AutoRedraw = False Picture1.ClipControls = True End Sub Private Sub Picture1_Paint() Picture1.ScaleMode = vbPixels Dim n As Long, x As Long, y As Long For n = 1 To 1000 x = Rnd * Picture1.ScaleWidth y = Rnd * Picture1.ScaleHeight Picture1.Line (x, y)-(x + 1, y) Next n End Sub
First
|
Prev
|
Pages: 1 2 Prev: What file extensions are considered to be executable? Next: Design Input Needed |