Toon posts:

[vb.net] verdwijnen van rectangles bij overlappen vensters.

Pagina: 1
Acties:

Verwijderd

Topicstarter
dit probleem kan ik in 5000 woorden omschrijven, maar deze plaatjes zeggen denk ik genoeg. wie heeft er een oplossing voor dit probleem, ik snap er geen aars van..

Zo ziet het er normaal uit, heel veel rechthoeken getekent via de code.

Afbeeldingslocatie: http://members1.chello.nl/~h.burgering/normaal.JPG

Zo ziet het eruit als er een venster overheen gaat, normaal dus.

Afbeeldingslocatie: http://members1.chello.nl/~h.burgering/vensterover.JPG

Zo ziet het eruit als het venster weer weg gaat, een gedeelte van de rechthoeken zijn ook weg. Dit is niet goed, de rechthoeken moeten blijven staan.

Afbeeldingslocatie: http://members1.chello.nl/~h.burgering/erna.JPG

  • Kuhlie
  • Registratie: December 2002
  • Niet online
In visual basic 6 kon je de property 'autoredraw' aanzetten, misschien is er in .Net ook zoiets?

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 19-05 21:24

NMe

Quia Ego Sic Dico.

Ik meen me van programmeren in C++ te herinneren dat je een buffer moet maken voor alles wat er op het scherm komt te staan, en die buffer bij bepaalde events terug moet schrijven naar het scherm. Maar tis alweer een tijdje terug, en hoe je dat in VB.NET aan moet pakken weet ik niet. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
De Windows GDI is zo ontworpen dat enkel hetgeen dat momenteel echt zichtbaar is op het scherm in het geheugen wordt opgeslagen.
Dat wil dus zeggen dat, als je er een venster voor jouw venster gesleept wordt, de contents van het niet zichbare gedeelte van jouw venster uit het (video)geheugen verwijderd worden.
Als dat 'niet zichtbare gedeelte' terug zichtbaar wordt (omdat je bv. het overlappende venster sluit), dan weet Windows niet wat er op jouw scherm stond. Windows zal dan een WM_PAINT message versturen naar uw window, zodat uw applicatie weet dat het de 'inhoud' van jouw venster moet verversen. De 'OnPaint' event van jouw venster (form) zal dus getriggered worden.
Het is dus jouw taak dat je zorgt dat die OnPaint event netjes afgehandeld wordt. In de OnPaint method zal je er dus moeten voor zorgen dat de inhoud (de rectangles dus) opnieuw getekend worden.

Zie ook hier:
[rml][ c#.net] paint functie[/rml]

Wat misschien het makkelijkst is om je probleem op te lossen: maak een class 'MyRectangle' oid, stop alle MyRectangle objecten die je tekent in een arraylist.
In de OnPain event overloop je die arraylist en roep je van ieder object de 'Draw' method ofzo aan.

[ Voor 21% gewijzigd door whoami op 12-09-2004 22:36 ]

https://fgheysels.github.io/


Verwijderd

Topicstarter
dit is precies wat ik zocht, bedankt voor de hulp. Ik ga het even proberen, als het niet lukt horen jullie het wel.

  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 21-05 14:59

pjvandesande

GC.Collect(head);

Het OnPaint event geeft je ook een Rectangle van het gedeelte dat opnieuw getekend moet worden.
Dit is makkelijk zodat je niet alles hoeft te hertekenen.

Verwijderd

Topicstarter
het lukt met niet helemaal, je zei dat ik het allemaal in een arraylist kan gooien, ik heb gezocht op msdn e.d., maar ik snap niet helemaal wat je daarmee bedoelt. Ik zal even een stukje code laten zien hoe ik de rectangles teken. kan iemand me dan een btje vertellen hoe dat werkt met een arraylist. moet je de coordinaten en hoogte en breedte erin gooien of zo iets.. als je op een rectangle met de rechtermuisknop klikt, moet je wel weten op welke rectangle er is geklikt.

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        Dim myPen As New System.Drawing.Pen(System.Drawing.Color.Black)
        Dim myBrushRed As New System.Drawing.SolidBrush(System.Drawing.Color.Red)
        Dim myBrushWhite As New System.Drawing.SolidBrush(System.Drawing.Color.White)
        Dim myBrushBlack As New System.Drawing.SolidBrush(System.Drawing.Color.Black)
        Dim myBrushGrey As New System.Drawing.SolidBrush(System.Drawing.Color.LightGray)

        Dim g As System.Drawing.Graphics = ActiveForm.CreateGraphics

        'E001
        g.FillRectangle(myBrushGrey, 22, 50, 30, 75)
        g.DrawRectangle(myPen, 22, 50, 30, 75)
        'E003
        g.FillRectangle(myBrushGrey, 182, 90, 195, 30)
        g.DrawRectangle(myPen, 182, 90, 195, 30)
        'V001
        g.FillRectangle(myBrushWhite, 22, 125, 30, 30)
        g.DrawRectangle(myPen, 22, 125, 30, 30)


De coordinaten zijn bekend en de hoogtes en breedtes ook. hier komt alleen nog de resize formule op, als je bijvoorbeeld een kleiner scherm hebt ed.

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
Je zou kunnen een eigen class 'Rectangle' oid maken. Die class geef je een 'Draw()' method oid, zodat een rectangle zichzelf kan tekenen.
Als je dan een rectangle maakt, kan je die toevoegen aan die arraylist.

Je moet wel zelf bepalen of die moeite het waard is in jouw geval.

https://fgheysels.github.io/


  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

Of een 'Overridable Sub Draw(g as Graphics)' ;)

En als je er dan een beetje een standaard class van maakt kan je de class ook overerven en bijvoorbeeld ook cirkels enzo tekenen (of meer dan alleen een rechthoek).

En vergeet dit niet (als het begint te knipperen):
code:
1
2
3
  Me.SetStyle(Windows.Forms.ControlStyles.UserPaint, True)
  Me.SetStyle(Windows.Forms.ControlStyles.AllPaintingInWmPaint, True)
  Me.SetStyle(Windows.Forms.ControlStyles.DoubleBuffer, True)


Bovenstaande zet je in de constructor van de Control waarmee je tekent (waar de OnPaint dus in staat).

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • Twilight Burn
  • Registratie: Juni 2000
  • Laatst online: 29-04 11:55
Wat je ook kunt doen is op een Image in een Picturebox tekenen, dan wordt het ook automatisch voor je gedaan, kost je wel het geheugen van het plaatje.

Voorbeeldcode:
code:
1
2
3
4
        Dim i As New Bitmap(PictureBox1.Width, PictureBox1.Height)
        Dim g As Graphics = Graphics.FromImage(i)
        PictureBox1.Image = i
        g.FillRectangle(Brushes.Blue, 20, 20, 80, 80)

Verwijderd

Topicstarter
ik roep nu, om het een en ander te testen, de functie op uit de module om alle rectangles, waarvan ik de coordinaten in een array heb gezet, te tekenen in de OnPaint sub. dan krijg ik de volgende foutmelding als ik een venster over het getekende heen haal zodat het opnieuw getekent moet worden.

Afbeeldingslocatie: http://members1.chello.nl/~h.burgering/foutje.JPG

[ Voor 9% gewijzigd door Verwijderd op 14-09-2004 17:46 ]


  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

Euhm.. Tja, Object dat aangeroepen wordt bestaat niet.
code:
1
2
Dim t as Textbox
t.Text="Hello"
gaat daarom ook niet werken.

Zet een Try-Catch-blok in je OnPaint; breekpunt in de Catch. Bekijk de stack-trace en je ziet waar het misgaat.

30Drie Web Design & IT Consultancy | Raven Consultancy Services


Verwijderd

Topicstarter
het gaat me niet lukken.. ik roep in de onpaint van mijn main form (form2) de volgende functie aan. met deze functie teken ik ook de rectangles in het begin (form2_load), de coordinaten en maten haalt de functie uit een array welke ik er in het begin inzet.

Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    Function PaintRectangles()

        Dim myPen As New System.Drawing.Pen(System.Drawing.Color.Black)
        Dim myBrushRed As New System.Drawing.SolidBrush(System.Drawing.Color.Red)
        Dim myBrushWhite As New System.Drawing.SolidBrush(System.Drawing.Color.White)
        Dim myBrushBlack As New System.Drawing.SolidBrush(System.Drawing.Color.Black)
        Dim myBrushGrey As New System.Drawing.SolidBrush(System.Drawing.Color.LightGray)
        'Dim g As System.Drawing.Graphics

        'Dim F2 As form2
        'F2 = winkelindeling.form2.ActiveForm

        'g = F2.CreateGraphics

        For i = 0 To 100
            Dim x As Short = coordinaten(i, 2)
            Dim y As Short = coordinaten(i, 3)
            Dim height As Short = coordinaten(i, 4)
            Dim width As Short = coordinaten(i, 5)

            If coordinaten(i, 1) = 0 Then form2.ActiveForm.CreateGraphics.FillRectangle(myBrushWhite, x, y, width, height)
            If coordinaten(i, 1) = 1 Then form2.ActiveForm.CreateGraphics.FillRectangle(myBrushBlack, x, y, width, height)
            If coordinaten(i, 1) = 2 Then form2.ActiveForm.CreateGraphics.FillRectangle(myBrushGrey, x, y, width, height)

            form2.ActiveForm.CreateGraphics.DrawRectangle(myPen, x, y, width, height)
        Next
    End Function


ik blijf dan de fout krijgen die ik een bericht hiervoor al beschreef. ik heb de try ... catch geprobeerd, maar hij geeft aan dat hij bij het aanroepen van de functie in de onpaint een probleem heeft. Wie weet wat ik fout doe, ben er nu al 2 dagen mee bezig en begin nu moe te worden 8)7

Is dit btw wel de goede onpaint in het form. en kan iemand mij vertellen wat een overrides sub is.

Visual Basic:
1
2
3
4
5
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)

        PaintRectangles()

    End Sub

[ Voor 7% gewijzigd door Verwijderd op 16-09-2004 20:35 ]


  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

Allereerst zit je een beetje te goochelen met de Graphics.
What ever happened with e.Graphics in de OnPaint? Je krijgt 'm gratis, waarom opzoeken?

In de form_load kan je al het tekenen weglaten, want dit doe je door de OnPaint te overriden (en doe ook even een MyBase.OnPaint aan het begin van de functie).

Als je de Try Catch in de hele OnPaint zet, dan moet er zeker ergens een regelnummer uitrollen.

Heb je 'coordinaten' trouwens wel ergens goed gedeclareerd?

En voor het geheel: misschien is het verstandig om van een Panel over te erven die de werkelijke tekening bevat en deze dan gewoon in het Form te zetten. Via die weg kan je met een beetje geknutsel ook nog automatisch scrollbarren realiseren.

Oja, het is de goede sub.
Drie keer raden wat Overrides Sub betekent...
Je hebt toch wel de MSDN-library geïnstalleerd? Staat er gewoon in.

[ Voor 11% gewijzigd door MrSleeves op 17-09-2004 08:40 ]

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • whoami
  • Registratie: December 2000
  • Laatst online: 23:34
Zet eens een breakpoint in je code, stap er met de debugger door, kijk op welke regel hij crasht, kijk welke variable er null is, ga na waarom deze null is, etc....

Programmeren is niet alleen code kloppen en naar de code staren als er iets mislukt. Debuggen is een gedeelte van het proces.

https://fgheysels.github.io/


  • PeetR
  • Registratie: Februari 2002
  • Laatst online: 13-09-2025
Alhoewel mijn probleem niet exact hetzelfde is denk ik tog dat het wel in dit topic past...

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Public Sub TEK_AR_100HB(ByRef Int_X1 As Short, ByRef Int_Y1 As Short,_
 ByRef Int_Waarde As Short)

        Dim Dbl_A As Double
        Dim Dbl_B As Double

        Dbl_A = ANDB(Int_Waarde, 1)
        Dbl_B = ANDB(Int_Waarde, 2) / 2

        RECTANGLE(Int_X1, Int_Y1, Int_X1 + 400, Int_Y1 + 200)
        RECTANGLE(Int_X1, Int_Y1 + 100, Int_X1 + 400, Int_Y1 + 102)
        RECTANGLE(Int_X1, Int_Y1 + 160, Int_X1 + 400, Int_Y1 + 162)
end sub

Public Sub RECTANGLE(ByRef x As Short, ByRef y As Short, _
ByRef Width As Short, ByRef Height As Short, _
Optional ByRef drawcolor As Short = 1)

        Select Case drawcolor
            Case 0
                drwcolor = Color.White

            Case 1
                drwcolor = Color.Black

            Case 2
                drwcolor = Color.Red

            Case 3
                drwcolor = Color.Magenta

            Case 4
                drwcolor = Color.Yellow

            Case 5
                drwcolor = Color.Green

            Case 6
                drwcolor = Color.Blue

            Case 7
                drwcolor = Color.Cyan
        End Select



        drawwidth = 1
        rect.X = x
        rect.Y = y
        rect.Height = Height - y
        rect.Width = Width - x


        Dim i As New Bitmap(TekBox.Width, TekBox.Height)
        Dim g As Graphics = Graphics.FromImage(i)
        TekBox.Image = i
        TekBox.Invalidate(rect)

        g.DrawRectangle(New pen(drwcolor, drawwidth), rect)
end sub


Dit is mjin code tot nu toe. Het probleem is dat de als je de sub TEK_AR_100HB aanroept hij op het sherm alleen de laatste rechthoek tekent ipv alle 3.

Ben hier al 2 dagen mee aan het stoeien en van de MSDN-page wordt je ook niet altijd even vrolijk.

Het zal vast iets simples zijn maar ik ben helaas niet zo'n masterlijke programmeur in VB.

Your time as a student is the best time of your life


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Teken je de laatste rectangle niet gewoon over de vorige heen? Dan is het logisch dat je die niet meer ziet.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • cowgirl
  • Registratie: November 2000
  • Laatst online: 18-12-2025
Je roept 3x de sub RECTANGLE aan waardoor ook 3x een nieuwe bitmap gemaakt wordt. Hierdoor worden de eerste twee bitmaps overschreven.
Misschien kan je iets doen door op r56 += te gebruiken, maar ik ben ook geen VB held.

  • PeetR
  • Registratie: Februari 2002
  • Laatst online: 13-09-2025
@rwb:
als je goed naar de coordinaten kijkt is dat niet het geval....

@cowgirl:
een bitmap kun je niet += dus daat gaat ook nie werken.
Begrijp nu wel waar het probleem in zit. Hoop dat er nog wat mensen met idee'tjes zijn, en ga zelf ondertussen ook nog eea proberen.

[ Voor 63% gewijzigd door PeetR op 05-10-2004 15:50 ]

Your time as a student is the best time of your life


  • cowgirl
  • Registratie: November 2000
  • Laatst online: 18-12-2025
PeetR schreef op 05 oktober 2004 @ 15:46:
als je goed naar de coordinaten kijkt is dat niet het geval....
Je kent i toe aan TekBox.Image, i bestaat op dat moment uit 1 rechthoek. Het lijkt me dus dat het wel overschreven wordt. Verder vraag ik me op dit moment af of het toevoegen wel zal gaan werken want daarvoor zal de achtergrond van het plaatje ook transparant moeten zijn.

  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

In gokmode:

code:
1
2
3
4
5
6
        If TekBok.Image is nothing then
                TekBok.Image = New Bitmap(TekBox.Width, TekBox.Height)
        End If
        Dim i As Image = TekBok.Image
        Dim g As Graphics = Graphics.FromImage(i)
        TekBox.Invalidate(rect)


Je overschrijft steeds de Image, dus logisch dat je maar één rechthoek ziet, namelijk de laatste, maar dat werd al gezegd.

Anyway, je moet zorgen dat je een Image hebt. Daar vraag je dan steeds de Graphics van (met Graphics.FromImage; je was warm ;) ).
En dan ga je daarmee tekenen.

[ Voor 19% gewijzigd door MrSleeves op 05-10-2004 16:24 . Reden: nog even TekBok.Image checken... ]

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ah dat is idd het probleem probeer het eens ongeveer zo

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MyClass
{
    private Bitmap _myBitmap;
    private Graphics _myGraphics;

    public MyClass()
    {
        _myBitmap = new Bitmap();
        _myGraphics = Graphics.FromImage( _myBitmap );
    }

    public void Draw()
    {
        DrawRectangle( 0, 0, 10, 10 );
        DrawRectangle( 10, 0, 10, 10 );
    }

    public void DrawRectangle( int x, int y, int width, int height )
    {
        Pen _pen = new Pen( Color.Black );
        _myGraphics.DrawRectangle( _pen, x, y, width, height );
    }
}


Hier heb je je Image en je Graphics object buiten je DrawRect Methode gehouden en teken je dus telkens op hetzelfde plaatje

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


  • PeetR
  • Registratie: Februari 2002
  • Laatst online: 13-09-2025
@chief.net
hmm jha owkee; zover was ik ook inmiddels; heb nu alleen nog een probleempje met waar de code staat. de sub rectangle staat nl in een losse module en de sub TEK_AR_100HB staat weer in een andere module.

Nou had ik een mooi formje gemaakt met een picturebox met de naam TekBox en een knop die TEK_AR_100HB aanroept. Als je dan de code van die sub erbij plaats in de form_class doet ie ut gewoon, maar staan ze in de modules zie ik niks meer gebeuren, magoed. Dat zoek ik nog wel ff uit.

Your time as a student is the best time of your life


  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

PeetR schreef op 05 oktober 2004 @ 16:44:
@chief.net
hmm jha owkee; zover was ik ook inmiddels; heb nu alleen nog een probleempje met waar de code staat. de sub rectangle staat nl in een losse module en de sub TEK_AR_100HB staat weer in een andere module.

Nou had ik een mooi formje gemaakt met een picturebox met de naam TekBox en een knop die TEK_AR_100HB aanroept. Als je dan de code van die sub erbij plaats in de form_class doet ie ut gewoon, maar staan ze in de modules zie ik niks meer gebeuren, magoed. Dat zoek ik nog wel ff uit.
Euhm... Ik ben niet echt een fan van Modules, maar zorg je er wel voor dat die TekBox bekent is bij de functie RECTANGLE. Dat je 'm meegeeft ofzo?

Mooier zou zijn als je een Class neemt die overerft van PictureBox of UserControl (maakt niet veel uit, denk dat de laatste het beste is) en dat je daarin de functies zet en dan met OnPaint (en zo zijn we weer bij het originele topic B) ) de handel er in zet?

30Drie Web Design & IT Consultancy | Raven Consultancy Services

Pagina: 1